diff --git a/Makefile b/Makefile old mode 100755 new mode 100644 index 76fb1c2..f0f98e5 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS) -EXTRA_CFLAGS += -O2 +EXTRA_CFLAGS += -O1 #EXTRA_CFLAGS += -O3 #EXTRA_CFLAGS += -Wall #EXTRA_CFLAGS += -Wextra @@ -44,12 +44,15 @@ CONFIG_RTL8710B = n CONFIG_RTL8192F = n CONFIG_RTL8822C = n CONFIG_RTL8814B = n +CONFIG_RTL8723F = n ######################### Interface ########################### CONFIG_USB_HCI = y CONFIG_PCI_HCI = n CONFIG_SDIO_HCI = n CONFIG_GSPI_HCI = n ########################## Features ########################### +CONFIG_AP_MODE = y +CONFIG_P2P = y CONFIG_MP_INCLUDED = y CONFIG_POWER_SAVING = y CONFIG_IPS_MODE = default @@ -74,7 +77,7 @@ CONFIG_80211W = y CONFIG_REDUCE_TX_CPU_LOADING = n CONFIG_BR_EXT = y CONFIG_TDLS = n -CONFIG_WIFI_MONITOR = y +CONFIG_WIFI_MONITOR = n CONFIG_MCC_MODE = n CONFIG_APPEND_VENDOR_IE_ENABLE = n CONFIG_RTW_NAPI = y @@ -82,33 +85,39 @@ CONFIG_RTW_GRO = y CONFIG_RTW_NETIF_SG = y CONFIG_RTW_IPCAM_APPLICATION = n CONFIG_RTW_REPEATER_SON = n -CONFIG_RTW_WIFI_HAL = n CONFIG_ICMP_VOQ = n CONFIG_IP_R_MONITOR = n #arp VOQ and high rate # user priority mapping rule : tos, dscp CONFIG_RTW_UP_MAPPING_RULE = tos -# Enable VHT rate on 2.4G channel or not -CONFIG_RTW_VHT_2G4 = y -CONFIG_RTW_IOCTL_SET_COUNTRY = y +CONFIG_RTW_MBO = n +########################## Android ########################### +# CONFIG_RTW_ANDROID - 0: no Android, 4/5/6/7/8/9/10/11 : Android version +CONFIG_RTW_ANDROID = 0 + +ifeq ($(shell test $(CONFIG_RTW_ANDROID) -gt 0; echo $$?), 0) +EXTRA_CFLAGS += -DCONFIG_RTW_ANDROID=$(CONFIG_RTW_ANDROID) +endif ########################## Debug ########################### CONFIG_RTW_DEBUG = y # default log level is _DRV_INFO_ = 4, # please refer to "How_to_set_driver_debug_log_level.doc" to set the available level. -CONFIG_RTW_LOG_LEVEL = 3 +CONFIG_RTW_LOG_LEVEL = 4 # enable /proc/net/rtlxxxx/ debug interfaces CONFIG_PROC_DEBUG = y ######################## Wake On Lan ########################## CONFIG_WOWLAN = n -#bit2: deauth, bit1: unicast, bit0: magic pkt. -CONFIG_WAKEUP_TYPE = 0x7 +#bit3: ARP enable, bit2: deauth, bit1: unicast, bit0: magic pkt. +CONFIG_WAKEUP_TYPE = 0xf CONFIG_WOW_LPS_MODE = default #bit0: disBBRF off, #bit1: Wireless remote controller (WRC) CONFIG_SUSPEND_TYPE = 0 CONFIG_WOW_STA_MIX = n CONFIG_GPIO_WAKEUP = n +# Please contact with RTK support team first. After getting the agreement from RTK support team, +# you are just able to modify the CONFIG_WAKEUP_GPIO_IDX with customized requirement. CONFIG_WAKEUP_GPIO_IDX = default CONFIG_HIGH_ACTIVE_DEV2HST = n ######### only for USB ######### @@ -121,6 +130,10 @@ CONFIG_AP_WOWLAN = n CONFIG_RTW_SDIO_PM_KEEP_POWER = y ###################### MP HW TX MODE FOR VHT ####################### CONFIG_MP_VHT_HW_TX_MODE = n +###################### ROAMING ##################################### +CONFIG_LAYER2_ROAMING = y +#bit0: ROAM_ON_EXPIRED, #bit1: ROAM_ON_RESUME, #bit2: ROAM_ACTIVE +CONFIG_ROAMING_FLAG = 0x3 ###################### Platform Related ####################### CONFIG_PLATFORM_I386_PC = y CONFIG_PLATFORM_ANDROID_X86 = n @@ -148,7 +161,6 @@ CONFIG_PLATFORM_ARM_TCC8930_JB42 = n CONFIG_PLATFORM_ARM_RK2818 = n CONFIG_PLATFORM_ARM_RK3066 = n CONFIG_PLATFORM_ARM_RK3188 = n -CONFIG_PLATFORM_ARM_RK3399 = n CONFIG_PLATFORM_ARM_URBETTER = n CONFIG_PLATFORM_ARM_TI_PANDA = n CONFIG_PLATFORM_MIPS_JZ4760 = n @@ -175,6 +187,7 @@ CONFIG_PLATFORM_MOZART = n CONFIG_PLATFORM_RTK119X = n CONFIG_PLATFORM_RTK119X_AM = n CONFIG_PLATFORM_RTK129X = n +CONFIG_PLATFORM_RTK1319 = n CONFIG_PLATFORM_RTK390X = n CONFIG_PLATFORM_NOVATEK_NT72668 = n CONFIG_PLATFORM_HISILICON = n @@ -222,6 +235,7 @@ _OS_INTFS_FILES := os_dep/osdep_service.o \ os_dep/linux/wifi_regd.o \ os_dep/linux/rtw_android.o \ os_dep/linux/rtw_proc.o \ + os_dep/linux/nlrtw.o \ os_dep/linux/rtw_rhashtable.o ifeq ($(CONFIG_MP_INCLUDED), y) @@ -721,6 +735,18 @@ endif endif +########### HAL_RTL8723F ################################# +ifeq ($(CONFIG_RTL8723F), y) +RTL871X := rtl8723f +ifeq ($(CONFIG_USB_HCI), y) +MODULE_NAME = 8723fu +endif +ifeq ($(CONFIG_SDIO_HCI), y) +MODULE_NAME = 8723fs +endif + +endif + ########### HAL_RTL8188F ################################# ifeq ($(CONFIG_RTL8188F), y) @@ -1007,6 +1033,17 @@ endif ########### END OF PATH ################################# +ifeq ($(CONFIG_AP_MODE), y) +EXTRA_CFLAGS += -DCONFIG_AP_MODE +endif + +ifeq ($(CONFIG_P2P), y) +EXTRA_CFLAGS += -DCONFIG_P2P +ifneq ($(CONFIG_AP_MODE), y) +$(error "CONFIG_AP_MODE is required for CONFIG_P2P") +endif +endif + ifeq ($(CONFIG_USB_HCI), y) ifeq ($(CONFIG_USB_AUTOSUSPEND), y) EXTRA_CFLAGS += -DCONFIG_USB_AUTOSUSPEND @@ -1154,11 +1191,18 @@ endif ifeq ($(CONFIG_AP_WOWLAN), y) EXTRA_CFLAGS += -DCONFIG_AP_WOWLAN +ifeq ($(CONFIG_AP_MODE), n) +EXTRA_CFLAGS += -DCONFIG_AP_MODE +endif ifeq ($(CONFIG_SDIO_HCI), y) EXTRA_CFLAGS += -DCONFIG_RTW_SDIO_PM_KEEP_POWER endif endif +ifeq ($(CONFIG_LAYER2_ROAMING), y) +EXTRA_CFLAGS += -DCONFIG_LAYER2_ROAMING -DCONFIG_ROAMING_FLAG=$(CONFIG_ROAMING_FLAG) +endif + ifeq ($(CONFIG_PNO_SUPPORT), y) EXTRA_CFLAGS += -DCONFIG_PNO_SUPPORT ifeq ($(CONFIG_PNO_SET_DEBUG), y) @@ -1248,15 +1292,6 @@ ifeq ($(CONFIG_IP_R_MONITOR), y) EXTRA_CFLAGS += -DCONFIG_IP_R_MONITOR endif -ifeq ($(CONFIG_RTW_WIFI_HAL), y) -#EXTRA_CFLAGS += -DCONFIG_RTW_WIFI_HAL_DEBUG -EXTRA_CFLAGS += -DCONFIG_RTW_WIFI_HAL -EXTRA_CFLAGS += -DCONFIG_RTW_CFGVEDNOR_LLSTATS -EXTRA_CFLAGS += -DCONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI -EXTRA_CFLAGS += -DCONFIG_RTW_CFGVEDNOR_RSSIMONITOR -EXTRA_CFLAGS += -DCONFIG_RTW_CFGVENDOR_WIFI_LOGGER -endif - ifeq ($(CONFIG_MP_VHT_HW_TX_MODE), y) EXTRA_CFLAGS += -DCONFIG_MP_VHT_HW_TX_MODE ifeq ($(CONFIG_PLATFORM_I386_PC), y) @@ -1289,20 +1324,16 @@ endif EXTRA_CFLAGS += -DDM_ODM_SUPPORT_TYPE=0x04 -ifeq ($(CONFIG_RTW_VHT_2G4), y) -EXTRA_CFLAGS += -DRTW_VHT_2G4=1 -else -EXTRA_CFLAGS += -DRTW_VHT_2G4=0 -endif - -ifeq ($(CONFIG_RTW_IOCTL_SET_COUNTRY), y) -EXTRA_CFLAGS += -DCONFIG_RTW_IOCTL_SET_COUNTRY +ifeq ($(CONFIG_RTW_MBO), y) +EXTRA_CFLAGS += -DCONFIG_RTW_MBO -DCONFIG_RTW_80211K -DCONFIG_RTW_WNM -DCONFIG_RTW_BTM_ROAM +EXTRA_CFLAGS += -DCONFIG_RTW_80211R endif ifeq ($(CONFIG_PLATFORM_I386_PC), y) EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT -SUBARCH := $(shell uname -m | sed -e 's/i.86/i386/;s/armv7l/arm/;s/aarch64/arm64/') + +SUBARCH := $(shell uname -m | sed -e s/i.86/i386/) ARCH ?= $(SUBARCH) CROSS_COMPILE ?= KVER := $(shell uname -r) @@ -1671,7 +1702,9 @@ EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE # default setting for Power control EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC +ifeq ($(CONFIG_SDIO_HCI), y) EXTRA_CFLAGS += -DRTW_SUPPORT_PLATFORM_SHUTDOWN +endif # default setting for Special function ARCH := arm CROSS_COMPILE := /home/android_sdk/Rockchip/Rk3188/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi- @@ -1696,37 +1729,6 @@ KSRC := /home/android_sdk/Rockchip/Rk3066sdk/kernel MODULE_NAME :=wlan endif -ifeq ($(CONFIG_PLATFORM_ARM_RK3399), y) -EXTRA_CFLAGS += -DCONFIG_PLATFORM_ROCKCHIPS -EXTRA_CFLAGS += -DCONFIG_PLATFORM_ROCKCHIPS_RK3399 -EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -EXTRA_CFLAGS += -Wno-error=date-time - -# default setting for Android -EXTRA_CFLAGS += -DCONFIG_PLATFORM_ANDROID -EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT -EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE -# default setting for Android 5.0 and later -EXTRA_CFLAGS += -DCONFIG_RADIO_WORK - -# default setting for Special function -EXTRA_CFLAGS += -DCONFIG_P2P_IPS -EXTRA_CFLAGS += -DCONFIG_RESUME_IN_WORKQUEUE - -ARCH ?= arm64 -CROSS_COMPILE ?= /rk3328_box_android_8.0_pro/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android- -KSRC ?= /rk3328_box_android_8.0_pro/kernel - -ifeq ($(CONFIG_SDIO_HCI), y) -EXTRA_CFLAGS += -DCONFIG_PLATFORM_OPS -_PLATFORM_FILES += platform/platform_rockchips_sdio.o -ifeq ($(CONFIG_RTL8822B), y) -USER_MODULE_NAME := 8822bs -endif -endif - -endif - ifeq ($(CONFIG_PLATFORM_ARM_URBETTER), y) EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN #-DCONFIG_MINIMAL_MEMORY_USAGE ARCH := arm @@ -1921,6 +1923,7 @@ EXTRA_CFLAGS += -DCONFIG_RADIO_WORK endif #ARCH, CROSS_COMPILE, KSRC,and MODDESTDIR are provided by external makefile INSTALL_PREFIX := +MODULE_NAME := wlan endif ifeq ($(CONFIG_PLATFORM_ARM_RTD299X_LG), y) @@ -1977,9 +1980,6 @@ EXTRA_CFLAGS += -DRTW_USE_CFG80211_STA_EVENT # default setting for Android 5.x and later #EXTRA_CFLAGS += -DCONFIG_RADIO_WORK -# Change active scan time in each channel, unit is ms -#EXTRA_CFLAGS += -DSURVEY_TO_ACTIVE=50 - # If system could power on and recognize Wi-Fi SDIO automatically, # platfrom operations are not necessary. #ifeq ($(CONFIG_SDIO_HCI), y) @@ -2082,11 +2082,13 @@ MODULE_NAME := 8192eu endif +# Actions-Micro use this flag for DHC 1195 and DHC 1395 ifeq ($(CONFIG_PLATFORM_RTK119X_AM), y) EXTRA_CFLAGS += -DCONFIG_PLATFORM_RTK119X_AM EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -EXTRA_CFLAGS += -DCONFIG_TRAFFIC_PROTECT -EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE -DCONFIG_FULL_CH_IN_P2P_HANDSHAKE +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_FULL_CH_IN_P2P_HANDSHAKE +EXTRA_CFLAGS += -DCONFIG_SEL_P2P_IFACE=2 EXTRA_CFLAGS += -DCONFIG_IFACE_NUMBER=3 EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT @@ -2104,7 +2106,43 @@ endif ifeq ($(CONFIG_PLATFORM_RTK129X), y) EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -EXTRA_CFLAGS += -DRTK_129X_PLATFORM +EXTRA_CFLAGS += -DCONFIG_PLATFORM_RTK129X +EXTRA_CFLAGS += -DCONFIG_TRAFFIC_PROTECT +# default setting for Android 4.1, 4.2 +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +#EXTRA_CFLAGS += -DCONFIG_P2P_IPS -DCONFIG_QOS_OPTIMIZATION +EXTRA_CFLAGS += -DCONFIG_QOS_OPTIMIZATION +# Enable this for Android 5.0 +EXTRA_CFLAGS += -DCONFIG_RADIO_WORK +ifeq ($(CONFIG_RTL8821C)$(CONFIG_SDIO_HCI),yy) +EXTRA_CFLAGS += -DCONFIG_WAKEUP_GPIO_INPUT_MODE +EXTRA_CFLAGS += -DCONFIG_BT_WAKE_HST_OPEN_DRAIN +endif +EXTRA_CFLAGS += -Wno-error=date-time +# default setting for Android 7.0 +ifeq ($(RTK_ANDROID_VERSION), nougat) +EXTRA_CFLAGS += -DRTW_P2P_GROUP_INTERFACE=1 +endif +#EXTRA_CFLAGS += -DCONFIG_#PLATFORM_OPS +ifeq ($(CONFIG_USB_HCI), y) +EXTRA_CFLAGS += -DCONFIG_USE_USB_BUFFER_ALLOC_TX +endif + +ARCH := arm64 + +# ==== Cross compile setting for Android 4.4 SDK ===== +#CROSS_COMPILE := arm-linux-gnueabihf- +#KVER := 4.1.10 +#CROSS_COMPILE := $(CROSS) +#KSRC := $(LINUX_KERNEL_PATH) +CROSS_COMPILE := /home/android_sdk/DHC/trunk-6.0.0_r1-QA160627/phoenix/toolchain/asdk64-4.9.4-a53-EL-3.10-g2.19-a64nt-160307/bin/asdk64-linux- +KSRC := /home/android_sdk/DHC/trunk-6.0.0_r1-QA160627/linux-kernel +endif + +ifeq ($(CONFIG_PLATFORM_RTK1319), y) +EXTRA_CFLAGS += -DCONFIG_PLATFORM_RTK1319 +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN EXTRA_CFLAGS += -DCONFIG_TRAFFIC_PROTECT # default setting for Android 4.1, 4.2 EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE @@ -2197,9 +2235,6 @@ EXTRA_CFLAGS += -DRTW_USE_CFG80211_STA_EVENT # default setting for Android 5.x and later EXTRA_CFLAGS += -DCONFIG_RADIO_WORK -# Change active scan time in each channel, unit is ms -#EXTRA_CFLAGS += -DSURVEY_TO_ACTIVE=50 - ifeq ($(CONFIG_SDIO_HCI), y) EXTRA_CFLAGS += -DCONFIG_PLATFORM_OPS _PLATFORM_FILES += platform/platform_aml_s905_sdio.o @@ -2261,6 +2296,14 @@ ifeq ($(CONFIG_CUSTOMER_HUAWEI), y) EXTRA_CFLAGS += -DCONFIG_HUAWEI_PROC endif +CONFIG_PLATFORM_CMAP_INTFS = n +ifeq ($(CONFIG_PLATFORM_CMAP_INTFS), y) +PLATFORM_CMAP_INTFS_TYPE = 00 +EXTRA_CFLAGS += -DCONFIG_PLATFORM_CMAP_INTFS -DCMAP_UNASSOC_METRICS_STA_MAX=32 +_OS_INTFS_FILES += os_dep/linux/custom_multiap_intfs/custom_multiap_intfs.o +_PLATFORM_FILES += platform/custom_multiap_intfs_$(PLATFORM_CMAP_INTFS_TYPE).o +endif + ifeq ($(CONFIG_MULTIDRV), y) ifeq ($(CONFIG_SDIO_HCI), y) @@ -2308,6 +2351,11 @@ ifeq ($(CONFIG_RTL8814B), y) include $(src)/rtl8814b.mk endif +########### HAL_RTL8723F ################################# +ifeq ($(CONFIG_RTL8723F), y) +include $(src)/rtl8723f.mk +endif + rtk_core := core/rtw_cmd.o \ core/rtw_security.o \ core/rtw_debug.o \ @@ -2323,9 +2371,11 @@ rtk_core := core/rtw_cmd.o \ core/rtw_pwrctrl.o \ core/rtw_rf.o \ core/rtw_chplan.o \ + core/monitor/rtw_radiotap.o \ core/rtw_recv.o \ core/rtw_sta_mgt.o \ core/rtw_ap.o \ + core/wds/rtw_wds.o \ core/mesh/rtw_mesh.o \ core/mesh/rtw_mesh_pathtbl.o \ core/mesh/rtw_mesh_hwmp.o \ @@ -2342,13 +2392,34 @@ rtk_core := core/rtw_cmd.o \ core/rtw_odm.o \ core/rtw_rm.o \ core/rtw_rm_fsm.o \ + core/rtw_ft.o \ + core/rtw_wnm.o \ + core/rtw_mbo.o \ core/rtw_rm_util.o \ - core/efuse/rtw_efuse.o + core/efuse/rtw_efuse.o \ + core/rtw_roch.o ifeq ($(CONFIG_SDIO_HCI), y) rtk_core += core/rtw_sdio.o endif +EXTRA_CFLAGS += -I$(src)/core/crypto +rtk_core += \ + core/crypto/aes-internal.o \ + core/crypto/aes-internal-enc.o \ + core/crypto/aes-gcm.o \ + core/crypto/aes-ccm.o \ + core/crypto/aes-omac1.o \ + core/crypto/ccmp.o \ + core/crypto/gcmp.o \ + core/crypto/aes-siv.o \ + core/crypto/aes-ctr.o \ + core/crypto/sha256-internal.o \ + core/crypto/sha256.o \ + core/crypto/sha256-prf.o \ + core/crypto/rtw_crypto_wrap.o \ + core/rtw_swcrypto.o + $(MODULE_NAME)-y += $(rtk_core) $(MODULE_NAME)-$(CONFIG_WAPI_SUPPORT) += core/rtw_wapi.o \ @@ -2431,17 +2502,17 @@ config_r: clean: #$(MAKE) -C $(KSRC) M=$(shell pwd) clean - cd hal ; rm -fr */*/*/*.mod.c */*/*/*.mod */*/*/*.o */*/*/.*.cmd */*/*/*.ko */*/*/*.ur-safe - cd hal ; rm -fr */*/*.mod.c */*/*.mod */*/*.o */*/.*.cmd */*/*.ko */*/*.ur-safe - cd hal ; rm -fr */*.mod.c */*.mod */*.o */.*.cmd */*.ko */*.ur-safe - cd hal ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko *.ur-safe - cd core ; rm -fr */*.mod.c */*.mod */*.o */.*.cmd */*.ko */*.ur-safe - cd core ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko *.ur-safe - cd os_dep/linux ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko *.ur-safe - cd os_dep ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko *.ur-safe - cd platform ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko *.ur-safe + cd hal ; rm -fr */*/*/*.mod.c */*/*/*.mod */*/*/*.o */*/*/.*.cmd */*/*/*.ko + cd hal ; rm -fr */*/*.mod.c */*/*.mod */*/*.o */*/.*.cmd */*/*.ko + cd hal ; rm -fr */*.mod.c */*.mod */*.o */.*.cmd */*.ko + cd hal ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + cd core ; rm -fr */*.mod.c */*.mod */*.o */.*.cmd */*.ko + cd core ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + cd os_dep/linux ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + cd os_dep ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + cd platform ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko rm -fr Module.symvers ; rm -fr Module.markers ; rm -fr modules.order rm -fr *.mod.c *.mod *.o .*.cmd *.ko *~ - rm -fr .tmp_versions *.ur-safe + rm -fr .tmp_versions endif diff --git a/README.md b/README.md index 09100ac..727f3ce 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # REALTEK RTL88x2B USB Linux Driver -**Current Driver Version**: 5.8.7.4 +**Current Driver Version**: 5.13.1 **Support Kernel**: 2.6.24 ~ 5.15 (with unofficial patches) Official release note please check ReleaseNotes.pdf diff --git a/clean b/clean index 7c3fb60..8766421 100644 --- a/clean +++ b/clean @@ -1,7 +1,5 @@ #!/bin/bash -rmmod 8822be -rmmod 88x2be -rmmod 8822bs -rmmod 88x2bs -rmmod 8822bu -rmmod 88x2bu +rmmod 8192cu +rmmod 8192ce +rmmod 8192du +rmmod 8192de diff --git a/core/crypto/aes-ccm.c b/core/crypto/aes-ccm.c new file mode 100644 index 0000000..dceec77 --- /dev/null +++ b/core/crypto/aes-ccm.c @@ -0,0 +1,211 @@ +/* + * Counter with CBC-MAC (CCM) with AES + * + * Copyright (c) 2010-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes.h" +#include "aes_wrap.h" + + +static void xor_aes_block(u8 *dst, const u8 *src) +{ + u32 *d = (u32 *) dst; + u32 *s = (u32 *) src; + *d++ ^= *s++; + *d++ ^= *s++; + *d++ ^= *s++; + *d++ ^= *s++; +} + + +static void aes_ccm_auth_start(void *aes, size_t M, size_t L, const u8 *nonce, + const u8 *aad, size_t aad_len, size_t plain_len, + u8 *x) +{ + u8 aad_buf[2 * AES_BLOCK_SIZE]; + u8 b[AES_BLOCK_SIZE]; + + /* Authentication */ + /* B_0: Flags | Nonce N | l(m) */ + b[0] = aad_len ? 0x40 : 0 /* Adata */; + b[0] |= (((M - 2) / 2) /* M' */ << 3); + b[0] |= (L - 1) /* L' */; + os_memcpy(&b[1], nonce, 15 - L); + WPA_PUT_BE16(&b[AES_BLOCK_SIZE - L], plain_len); + + wpa_hexdump_key(_MSG_EXCESSIVE_, "CCM B_0", b, AES_BLOCK_SIZE); + aes_encrypt(aes, b, x); /* X_1 = E(K, B_0) */ + + if (!aad_len) + return; + + WPA_PUT_BE16(aad_buf, aad_len); + os_memcpy(aad_buf + 2, aad, aad_len); + os_memset(aad_buf + 2 + aad_len, 0, sizeof(aad_buf) - 2 - aad_len); + + xor_aes_block(aad_buf, x); + aes_encrypt(aes, aad_buf, x); /* X_2 = E(K, X_1 XOR B_1) */ + + if (aad_len > AES_BLOCK_SIZE - 2) { + xor_aes_block(&aad_buf[AES_BLOCK_SIZE], x); + /* X_3 = E(K, X_2 XOR B_2) */ + aes_encrypt(aes, &aad_buf[AES_BLOCK_SIZE], x); + } +} + + +static void aes_ccm_auth(void *aes, const u8 *data, size_t len, u8 *x) +{ + size_t last = len % AES_BLOCK_SIZE; + size_t i; + + for (i = 0; i < len / AES_BLOCK_SIZE; i++) { + /* X_i+1 = E(K, X_i XOR B_i) */ + xor_aes_block(x, data); + data += AES_BLOCK_SIZE; + aes_encrypt(aes, x, x); + } + if (last) { + /* XOR zero-padded last block */ + for (i = 0; i < last; i++) + x[i] ^= *data++; + aes_encrypt(aes, x, x); + } +} + + +static void aes_ccm_encr_start(size_t L, const u8 *nonce, u8 *a) +{ + /* A_i = Flags | Nonce N | Counter i */ + a[0] = L - 1; /* Flags = L' */ + os_memcpy(&a[1], nonce, 15 - L); +} + + +static void aes_ccm_encr(void *aes, size_t L, const u8 *in, size_t len, u8 *out, + u8 *a) +{ + size_t last = len % AES_BLOCK_SIZE; + size_t i; + + /* crypt = msg XOR (S_1 | S_2 | ... | S_n) */ + for (i = 1; i <= len / AES_BLOCK_SIZE; i++) { + WPA_PUT_BE16(&a[AES_BLOCK_SIZE - 2], i); + /* S_i = E(K, A_i) */ + aes_encrypt(aes, a, out); + xor_aes_block(out, in); + out += AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + } + if (last) { + WPA_PUT_BE16(&a[AES_BLOCK_SIZE - 2], i); + aes_encrypt(aes, a, out); + /* XOR zero-padded last block */ + for (i = 0; i < last; i++) + *out++ ^= *in++; + } +} + + +static void aes_ccm_encr_auth(void *aes, size_t M, u8 *x, u8 *a, u8 *auth) +{ + size_t i; + u8 tmp[AES_BLOCK_SIZE]; + + wpa_hexdump_key(_MSG_EXCESSIVE_, "CCM T", x, M); + /* U = T XOR S_0; S_0 = E(K, A_0) */ + WPA_PUT_BE16(&a[AES_BLOCK_SIZE - 2], 0); + aes_encrypt(aes, a, tmp); + for (i = 0; i < M; i++) + auth[i] = x[i] ^ tmp[i]; + wpa_hexdump_key(_MSG_EXCESSIVE_, "CCM U", auth, M); +} + + +static void aes_ccm_decr_auth(void *aes, size_t M, u8 *a, const u8 *auth, u8 *t) +{ + size_t i; + u8 tmp[AES_BLOCK_SIZE]; + + wpa_hexdump_key(_MSG_EXCESSIVE_, "CCM U", auth, M); + /* U = T XOR S_0; S_0 = E(K, A_0) */ + WPA_PUT_BE16(&a[AES_BLOCK_SIZE - 2], 0); + aes_encrypt(aes, a, tmp); + for (i = 0; i < M; i++) + t[i] = auth[i] ^ tmp[i]; + wpa_hexdump_key(_MSG_EXCESSIVE_, "CCM T", t, M); +} + + +/* AES-CCM with fixed L=2 and aad_len <= 30 assumption */ +int aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce, + size_t M, const u8 *plain, size_t plain_len, + const u8 *aad, size_t aad_len, u8 *crypt, u8 *auth) +{ + const size_t L = 2; + void *aes; + u8 x[AES_BLOCK_SIZE], a[AES_BLOCK_SIZE]; + + if (aad_len > 30 || M > AES_BLOCK_SIZE) + return -1; + + aes = aes_encrypt_init(key, key_len); + if (aes == NULL) + return -1; + + aes_ccm_auth_start(aes, M, L, nonce, aad, aad_len, plain_len, x); + aes_ccm_auth(aes, plain, plain_len, x); + + /* Encryption */ + aes_ccm_encr_start(L, nonce, a); + aes_ccm_encr(aes, L, plain, plain_len, crypt, a); + aes_ccm_encr_auth(aes, M, x, a, auth); + + aes_encrypt_deinit(aes); + + return 0; +} + + +/* AES-CCM with fixed L=2 and aad_len <= 30 assumption */ +int aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce, + size_t M, const u8 *crypt, size_t crypt_len, + const u8 *aad, size_t aad_len, const u8 *auth, u8 *plain) +{ + const size_t L = 2; + void *aes; + u8 x[AES_BLOCK_SIZE], a[AES_BLOCK_SIZE]; + u8 t[AES_BLOCK_SIZE]; + + if (aad_len > 30 || M > AES_BLOCK_SIZE) + return -1; + + aes = aes_encrypt_init(key, key_len); + if (aes == NULL) + return -1; + + /* Decryption */ + aes_ccm_encr_start(L, nonce, a); + aes_ccm_decr_auth(aes, M, a, auth, t); + + /* plaintext = msg XOR (S_1 | S_2 | ... | S_n) */ + aes_ccm_encr(aes, L, crypt, crypt_len, plain, a); + + aes_ccm_auth_start(aes, M, L, nonce, aad, aad_len, crypt_len, x); + aes_ccm_auth(aes, plain, crypt_len, x); + + aes_encrypt_deinit(aes); + + if (os_memcmp_const(x, t, M) != 0) { + wpa_printf(_MSG_EXCESSIVE_, "CCM: Auth mismatch"); + return -1; + } + + return 0; +} diff --git a/core/crypto/aes-ctr.c b/core/crypto/aes-ctr.c new file mode 100644 index 0000000..6c06851 --- /dev/null +++ b/core/crypto/aes-ctr.c @@ -0,0 +1,70 @@ +/* + * AES-128/192/256 CTR + * + * Copyright (c) 2003-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes.h" +#include "aes_wrap.h" + +/** + * aes_ctr_encrypt - AES-128/192/256 CTR mode encryption + * @key: Key for encryption (key_len bytes) + * @key_len: Length of the key (16, 24, or 32 bytes) + * @nonce: Nonce for counter mode (16 bytes) + * @data: Data to encrypt in-place + * @data_len: Length of data in bytes + * Returns: 0 on success, -1 on failure + */ +int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, + u8 *data, size_t data_len) +{ + void *ctx; + size_t j, len, left = data_len; + int i; + u8 *pos = data; + u8 counter[AES_BLOCK_SIZE], buf[AES_BLOCK_SIZE]; + + ctx = aes_encrypt_init(key, key_len); + if (ctx == NULL) + return -1; + os_memcpy(counter, nonce, AES_BLOCK_SIZE); + + while (left > 0) { + aes_encrypt(ctx, counter, buf); + + len = (left < AES_BLOCK_SIZE) ? left : AES_BLOCK_SIZE; + for (j = 0; j < len; j++) + pos[j] ^= buf[j]; + pos += len; + left -= len; + + for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) { + counter[i]++; + if (counter[i]) + break; + } + } + aes_encrypt_deinit(ctx); + return 0; +} + + +/** + * aes_128_ctr_encrypt - AES-128 CTR mode encryption + * @key: Key for encryption (key_len bytes) + * @nonce: Nonce for counter mode (16 bytes) + * @data: Data to encrypt in-place + * @data_len: Length of data in bytes + * Returns: 0 on success, -1 on failure + */ +int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, + u8 *data, size_t data_len) +{ + return aes_ctr_encrypt(key, 16, nonce, data, data_len); +} diff --git a/core/crypto/aes-gcm.c b/core/crypto/aes-gcm.c new file mode 100644 index 0000000..4708810 --- /dev/null +++ b/core/crypto/aes-gcm.c @@ -0,0 +1,326 @@ +/* + * Galois/Counter Mode (GCM) and GMAC with AES + * + * Copyright (c) 2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes.h" +#include "aes_wrap.h" + +static void inc32(u8 *block) +{ + u32 val; + val = WPA_GET_BE32(block + AES_BLOCK_SIZE - 4); + val++; + WPA_PUT_BE32(block + AES_BLOCK_SIZE - 4, val); +} + + +static void xor_block(u8 *dst, const u8 *src) +{ + u32 *d = (u32 *) dst; + u32 *s = (u32 *) src; + *d++ ^= *s++; + *d++ ^= *s++; + *d++ ^= *s++; + *d++ ^= *s++; +} + + +static void shift_right_block(u8 *v) +{ + u32 val; + + val = WPA_GET_BE32(v + 12); + val >>= 1; + if (v[11] & 0x01) + val |= 0x80000000; + WPA_PUT_BE32(v + 12, val); + + val = WPA_GET_BE32(v + 8); + val >>= 1; + if (v[7] & 0x01) + val |= 0x80000000; + WPA_PUT_BE32(v + 8, val); + + val = WPA_GET_BE32(v + 4); + val >>= 1; + if (v[3] & 0x01) + val |= 0x80000000; + WPA_PUT_BE32(v + 4, val); + + val = WPA_GET_BE32(v); + val >>= 1; + WPA_PUT_BE32(v, val); +} + + +/* Multiplication in GF(2^128) */ +static void gf_mult(const u8 *x, const u8 *y, u8 *z) +{ + u8 v[16]; + int i, j; + + os_memset(z, 0, 16); /* Z_0 = 0^128 */ + os_memcpy(v, y, 16); /* V_0 = Y */ + + for (i = 0; i < 16; i++) { + for (j = 0; j < 8; j++) { + if (x[i] & BIT(7 - j)) { + /* Z_(i + 1) = Z_i XOR V_i */ + xor_block(z, v); + } else { + /* Z_(i + 1) = Z_i */ + } + + if (v[15] & 0x01) { + /* V_(i + 1) = (V_i >> 1) XOR R */ + shift_right_block(v); + /* R = 11100001 || 0^120 */ + v[0] ^= 0xe1; + } else { + /* V_(i + 1) = V_i >> 1 */ + shift_right_block(v); + } + } + } +} + + +static void ghash_start(u8 *y) +{ + /* Y_0 = 0^128 */ + os_memset(y, 0, 16); +} + + +static void ghash(const u8 *h, const u8 *x, size_t xlen, u8 *y) +{ + size_t m, i; + const u8 *xpos = x; + u8 tmp[16]; + + m = xlen / 16; + + for (i = 0; i < m; i++) { + /* Y_i = (Y^(i-1) XOR X_i) dot H */ + xor_block(y, xpos); + xpos += 16; + + /* dot operation: + * multiplication operation for binary Galois (finite) field of + * 2^128 elements */ + gf_mult(y, h, tmp); + os_memcpy(y, tmp, 16); + } + + if (x + xlen > xpos) { + /* Add zero padded last block */ + size_t last = x + xlen - xpos; + os_memcpy(tmp, xpos, last); + os_memset(tmp + last, 0, sizeof(tmp) - last); + + /* Y_i = (Y^(i-1) XOR X_i) dot H */ + xor_block(y, tmp); + + /* dot operation: + * multiplication operation for binary Galois (finite) field of + * 2^128 elements */ + gf_mult(y, h, tmp); + os_memcpy(y, tmp, 16); + } + + /* Return Y_m */ +} + + +static void aes_gctr(void *aes, const u8 *icb, const u8 *x, size_t xlen, u8 *y) +{ + size_t i, n, last; + u8 cb[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE]; + const u8 *xpos = x; + u8 *ypos = y; + + if (xlen == 0) + return; + + n = xlen / 16; + + os_memcpy(cb, icb, AES_BLOCK_SIZE); + /* Full blocks */ + for (i = 0; i < n; i++) { + aes_encrypt(aes, cb, ypos); + xor_block(ypos, xpos); + xpos += AES_BLOCK_SIZE; + ypos += AES_BLOCK_SIZE; + inc32(cb); + } + + last = x + xlen - xpos; + if (last) { + /* Last, partial block */ + aes_encrypt(aes, cb, tmp); + for (i = 0; i < last; i++) + *ypos++ = *xpos++ ^ tmp[i]; + } +} + + +static void * aes_gcm_init_hash_subkey(const u8 *key, size_t key_len, u8 *H) +{ + void *aes; + + aes = aes_encrypt_init(key, key_len); + if (aes == NULL) + return NULL; + + /* Generate hash subkey H = AES_K(0^128) */ + os_memset(H, 0, AES_BLOCK_SIZE); + aes_encrypt(aes, H, H); + wpa_hexdump_key(_MSG_EXCESSIVE_, "Hash subkey H for GHASH", + H, AES_BLOCK_SIZE); + return aes; +} + + +static void aes_gcm_prepare_j0(const u8 *iv, size_t iv_len, const u8 *H, u8 *J0) +{ + u8 len_buf[16]; + + if (iv_len == 12) { + /* Prepare block J_0 = IV || 0^31 || 1 [len(IV) = 96] */ + os_memcpy(J0, iv, iv_len); + os_memset(J0 + iv_len, 0, AES_BLOCK_SIZE - iv_len); + J0[AES_BLOCK_SIZE - 1] = 0x01; + } else { + /* + * s = 128 * ceil(len(IV)/128) - len(IV) + * J_0 = GHASH_H(IV || 0^(s+64) || [len(IV)]_64) + */ + ghash_start(J0); + ghash(H, iv, iv_len, J0); + WPA_PUT_BE64(len_buf, 0); + WPA_PUT_BE64(len_buf + 8, iv_len * 8); + ghash(H, len_buf, sizeof(len_buf), J0); + } +} + + +static void aes_gcm_gctr(void *aes, const u8 *J0, const u8 *in, size_t len, + u8 *out) +{ + u8 J0inc[AES_BLOCK_SIZE]; + + if (len == 0) + return; + + os_memcpy(J0inc, J0, AES_BLOCK_SIZE); + inc32(J0inc); + aes_gctr(aes, J0inc, in, len, out); +} + + +static void aes_gcm_ghash(const u8 *H, const u8 *aad, size_t aad_len, + const u8 *crypt, size_t crypt_len, u8 *S) +{ + u8 len_buf[16]; + + /* + * u = 128 * ceil[len(C)/128] - len(C) + * v = 128 * ceil[len(A)/128] - len(A) + * S = GHASH_H(A || 0^v || C || 0^u || [len(A)]64 || [len(C)]64) + * (i.e., zero padded to block size A || C and lengths of each in bits) + */ + ghash_start(S); + ghash(H, aad, aad_len, S); + ghash(H, crypt, crypt_len, S); + WPA_PUT_BE64(len_buf, aad_len * 8); + WPA_PUT_BE64(len_buf + 8, crypt_len * 8); + ghash(H, len_buf, sizeof(len_buf), S); + + wpa_hexdump_key(_MSG_EXCESSIVE_, "S = GHASH_H(...)", S, 16); +} + + +/** + * aes_gcm_ae - GCM-AE_K(IV, P, A) + */ +int aes_gcm_ae(const u8 *key, size_t key_len, const u8 *iv, size_t iv_len, + const u8 *plain, size_t plain_len, + const u8 *aad, size_t aad_len, u8 *crypt, u8 *tag) +{ + u8 H[AES_BLOCK_SIZE]; + u8 J0[AES_BLOCK_SIZE]; + u8 S[16]; + void *aes; + + aes = aes_gcm_init_hash_subkey(key, key_len, H); + if (aes == NULL) + return -1; + + aes_gcm_prepare_j0(iv, iv_len, H, J0); + + /* C = GCTR_K(inc_32(J_0), P) */ + aes_gcm_gctr(aes, J0, plain, plain_len, crypt); + + aes_gcm_ghash(H, aad, aad_len, crypt, plain_len, S); + + /* T = MSB_t(GCTR_K(J_0, S)) */ + aes_gctr(aes, J0, S, sizeof(S), tag); + + /* Return (C, T) */ + + aes_encrypt_deinit(aes); + + return 0; +} + + +/** + * aes_gcm_ad - GCM-AD_K(IV, C, A, T) + */ +int aes_gcm_ad(const u8 *key, size_t key_len, const u8 *iv, size_t iv_len, + const u8 *crypt, size_t crypt_len, + const u8 *aad, size_t aad_len, const u8 *tag, u8 *plain) +{ + u8 H[AES_BLOCK_SIZE]; + u8 J0[AES_BLOCK_SIZE]; + u8 S[16], T[16]; + void *aes; + + aes = aes_gcm_init_hash_subkey(key, key_len, H); + if (aes == NULL) + return -1; + + aes_gcm_prepare_j0(iv, iv_len, H, J0); + + /* P = GCTR_K(inc_32(J_0), C) */ + aes_gcm_gctr(aes, J0, crypt, crypt_len, plain); + + aes_gcm_ghash(H, aad, aad_len, crypt, crypt_len, S); + + /* T' = MSB_t(GCTR_K(J_0, S)) */ + aes_gctr(aes, J0, S, sizeof(S), T); + + aes_encrypt_deinit(aes); + + if (os_memcmp_const(tag, T, 16) != 0) { + wpa_printf(_MSG_EXCESSIVE_, "GCM: Tag mismatch"); + return -1; + } + + return 0; +} + + +int aes_gmac(const u8 *key, size_t key_len, const u8 *iv, size_t iv_len, + const u8 *aad, size_t aad_len, u8 *tag) +{ + return aes_gcm_ae(key, key_len, iv, iv_len, NULL, 0, aad, aad_len, NULL, + tag); +} diff --git a/core/crypto/aes-internal-enc.c b/core/crypto/aes-internal-enc.c new file mode 100644 index 0000000..69e256b --- /dev/null +++ b/core/crypto/aes-internal-enc.c @@ -0,0 +1,129 @@ +/* + * AES (Rijndael) cipher - encrypt + * + * Modifications to public domain implementation: + * - cleanup + * - use C pre-processor to make it easier to change S table access + * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at + * cost of reduced throughput (quite small difference on Pentium 4, + * 10-25% when using -O1 or -O2 optimization) + * + * Copyright (c) 2003-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes_i.h" + +static void rijndaelEncrypt(const u32 rk[], int Nr, const u8 pt[16], u8 ct[16]) +{ + u32 s0, s1, s2, s3, t0, t1, t2, t3; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(pt ) ^ rk[0]; + s1 = GETU32(pt + 4) ^ rk[1]; + s2 = GETU32(pt + 8) ^ rk[2]; + s3 = GETU32(pt + 12) ^ rk[3]; + +#define ROUND(i,d,s) \ +d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \ +d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \ +d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \ +d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3] + +#ifdef FULL_UNROLL + + ROUND(1,t,s); + ROUND(2,s,t); + ROUND(3,t,s); + ROUND(4,s,t); + ROUND(5,t,s); + ROUND(6,s,t); + ROUND(7,t,s); + ROUND(8,s,t); + ROUND(9,t,s); + if (Nr > 10) { + ROUND(10,s,t); + ROUND(11,t,s); + if (Nr > 12) { + ROUND(12,s,t); + ROUND(13,t,s); + } + } + + rk += Nr << 2; + +#else /* !FULL_UNROLL */ + + /* Nr - 1 full rounds: */ + r = Nr >> 1; + for (;;) { + ROUND(1,t,s); + rk += 8; + if (--r == 0) + break; + ROUND(0,s,t); + } + +#endif /* ?FULL_UNROLL */ + +#undef ROUND + + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0]; + PUTU32(ct , s0); + s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1]; + PUTU32(ct + 4, s1); + s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2]; + PUTU32(ct + 8, s2); + s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3]; + PUTU32(ct + 12, s3); +} + + +void * aes_encrypt_init(const u8 *key, size_t len) +{ + u32 *rk; + int res; + + if (TEST_FAIL()) + return NULL; + + rk = os_malloc(AES_PRIV_SIZE); + if (rk == NULL) + return NULL; + res = rijndaelKeySetupEnc(rk, key, len * 8); + if (res < 0) { + rtw_mfree(rk, AES_PRIV_SIZE); + return NULL; + } + rk[AES_PRIV_NR_POS] = res; + return rk; +} + + +int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) +{ + u32 *rk = ctx; + rijndaelEncrypt(ctx, rk[AES_PRIV_NR_POS], plain, crypt); + return 0; +} + + +void aes_encrypt_deinit(void *ctx) +{ + os_memset(ctx, 0, AES_PRIV_SIZE); + rtw_mfree(ctx, AES_PRIV_SIZE); +} diff --git a/core/crypto/aes-internal.c b/core/crypto/aes-internal.c new file mode 100644 index 0000000..57d6539 --- /dev/null +++ b/core/crypto/aes-internal.c @@ -0,0 +1,843 @@ +/* + * AES (Rijndael) cipher + * + * Modifications to public domain implementation: + * - cleanup + * - use C pre-processor to make it easier to change S table access + * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at + * cost of reduced throughput (quite small difference on Pentium 4, + * 10-25% when using -O1 or -O2 optimization) + * + * Copyright (c) 2003-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes_i.h" + +/* + * rijndael-alg-fst.c + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +/* +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; +Te4[x] = S [x].[01, 01, 01, 01]; + +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +Td4[x] = Si[x].[01, 01, 01, 01]; +*/ + +const u32 Te0[256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +}; +#ifndef AES_SMALL_TABLES +const u32 Te1[256] = { + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, + 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, + 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, + 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, + 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, + 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, + 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, + 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, + 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, + 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, + 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, + 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, + 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, + 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, + 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, + 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, + 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, + 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, + 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, + 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, + 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, + 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, + 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, + 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, + 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, + 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, + 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, + 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, + 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, + 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, + 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, + 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, + 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, + 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, + 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, + 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, + 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, + 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, + 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, + 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, + 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, + 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, + 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, + 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, + 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, + 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, + 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, + 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, + 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, + 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, + 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, + 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, + 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, + 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, + 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, + 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, + 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, + 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, +}; +const u32 Te2[256] = { + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, + 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, + 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, + 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, + 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, + 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, + 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, + 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, + 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, + 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, + 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, + 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, + 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, + 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, + 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, + 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, + 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, + 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, + 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, + 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, + 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, + 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, + 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, + 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, + 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, + 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, + 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, + 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, + 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, + 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, + 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, + 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, + 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, + 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, + 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, + 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, + 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, + 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, + 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, + 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, + 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, + 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, + 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, + 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, + 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, + 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, + 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, + 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, + 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, + 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, + 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, + 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, + 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, + 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, + 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, + 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, + 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, + 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, +}; +const u32 Te3[256] = { + + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, + 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, + 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, + 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, + 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, + 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, + 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, + 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, + 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, + 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, + 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, + 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, + 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, + 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, + 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, + 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, + 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, + 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, + 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, + 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, + 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, + 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, + 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, + 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, + 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, + 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, + 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, + 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, + 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, + 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, + 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, + 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, + 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, + 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, + 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, + 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, + 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, + 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, + 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, + 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, + 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, + 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, + 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, + 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, + 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, + 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, + 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, + 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, + 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, + 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, + 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, + 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, + 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, + 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, + 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, + 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, + 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, + 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, +}; +const u32 Te4[256] = { + 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, + 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, + 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, + 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, + 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, + 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, + 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, + 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, + 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, + 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, + 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, + 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, + 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, + 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, + 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, + 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, + 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, + 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, + 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, + 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, + 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, + 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, + 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, + 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, + 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, + 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, + 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, + 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, + 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, + 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, + 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, + 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, + 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, + 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, + 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, + 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, + 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, + 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, + 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, + 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, + 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, + 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, + 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, + 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, + 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, + 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, + 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, + 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, + 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, + 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, + 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, + 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, + 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, + 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, + 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, + 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, + 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, + 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, + 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, + 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, + 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, + 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, + 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, + 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, +}; +#endif /* AES_SMALL_TABLES */ +const u32 Td0[256] = { + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, + 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, + 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, + 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, + 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, + 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, + 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, + 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, + 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, + 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, + 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, + 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, + 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, + 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, + 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, + 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, + 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, + 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, + 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, + 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, + 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, + 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, + 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, + 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, + 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, + 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, + 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, + 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, + 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, + 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, + 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, + 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, + 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, + 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, + 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, + 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, + 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, + 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, + 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, + 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, + 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, + 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, + 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, + 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, + 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, + 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, + 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, + 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, + 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, + 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, + 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, + 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, + 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, + 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, + 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, + 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, + 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, + 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, +}; +#ifndef AES_SMALL_TABLES +const u32 Td1[256] = { + 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, + 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, + 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, + 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, + 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, + 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, + 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, + 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, + 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, + 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, + 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, + 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, + 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, + 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, + 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, + 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, + 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, + 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, + 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, + 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, + 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, + 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, + 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, + 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, + 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, + 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, + 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, + 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, + 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, + 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, + 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, + 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, + 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, + 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, + 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, + 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, + 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, + 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, + 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, + 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, + 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, + 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, + 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, + 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, + 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, + 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, + 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, + 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, + 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, + 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, + 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, + 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, + 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, + 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, + 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, + 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, + 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, + 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, + 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, + 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, + 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, + 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, + 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, + 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, +}; +const u32 Td2[256] = { + 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, + 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, + 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, + 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, + 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, + 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, + 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, + 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, + 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, + 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, + 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, + 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, + 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, + 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, + 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, + 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, + 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, + 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, + 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, + 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, + + 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, + 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, + 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, + 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, + 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, + 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, + 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, + 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, + 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, + 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, + 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, + 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, + 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, + 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, + 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, + 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, + 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, + 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, + 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, + 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, + 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, + 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, + 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, + 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, + 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, + 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, + 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, + 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, + 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, + 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, + 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, + 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, + 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, + 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, + 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, + 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, + 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, + 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, + 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, + 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, + 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, + 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, + 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, + 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, +}; +const u32 Td3[256] = { + 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, + 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, + 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, + 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, + 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, + 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, + 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, + 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, + 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, + 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, + 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, + 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, + 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, + 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, + 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, + 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, + 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, + 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, + 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, + 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, + 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, + 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, + 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, + 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, + 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, + 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, + 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, + 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, + 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, + 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, + 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, + 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, + 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, + 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, + 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, + 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, + 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, + 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, + 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, + 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, + 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, + 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, + 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, + 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, + 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, + 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, + 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, + 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, + 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, + 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, + 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, + 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, + 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, + 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, + 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, + 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, + 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, + 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, + 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, + 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, + 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, + 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, + 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, + 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, +}; +const u32 Td4[256] = { + 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, + 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, + 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, + 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, + 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, + 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, + 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, + 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, + 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, + 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, + 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, + 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, + 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, + 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, + 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, + 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, + 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, + 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, + 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, + 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, + 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, + 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, + 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, + 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, + 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, + 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, + 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, + 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, + 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, + 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, + 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, + 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, + 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, + 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, + 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, + 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, + 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, + 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, + 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, + 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, + 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, + 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, + 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, + 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, + 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, + 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, + 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, + 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, + 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, + 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, + 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, + 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, + 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, + 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, + 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, + 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, + 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, + 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, + 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, + 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, + 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, + 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, + 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, + 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, +}; +const u32 rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; +#else /* AES_SMALL_TABLES */ +const u8 Td4s[256] = { + 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, + 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, + 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, + 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, + 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, + 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, + 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, + 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, + 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, + 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, + 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, + 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, + 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, + 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, + 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, + 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, + 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, + 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, + 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, + 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, + 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, + 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, + 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, + 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, + 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, + 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, + 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, + 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, + 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, + 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, + 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, + 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, +}; +const u8 rcons[] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 + /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; +#endif /* AES_SMALL_TABLES */ +/** + * Expand the cipher key into the encryption key schedule. + * + * @return the number of rounds for the given cipher key size. + */ +int rijndaelKeySetupEnc(u32 rk[], const u8 cipherKey[], int keyBits) +{ + int i; + u32 temp; + + rk[0] = GETU32(cipherKey ); + rk[1] = GETU32(cipherKey + 4); + rk[2] = GETU32(cipherKey + 8); + rk[3] = GETU32(cipherKey + 12); + + if (keyBits == 128) { + for (i = 0; i < 10; i++) { + temp = rk[3]; + rk[4] = rk[0] ^ TE421(temp) ^ TE432(temp) ^ + TE443(temp) ^ TE414(temp) ^ RCON(i); + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + rk += 4; + } + return 10; + } + + rk[4] = GETU32(cipherKey + 16); + rk[5] = GETU32(cipherKey + 20); + + if (keyBits == 192) { + for (i = 0; i < 8; i++) { + temp = rk[5]; + rk[6] = rk[0] ^ TE421(temp) ^ TE432(temp) ^ + TE443(temp) ^ TE414(temp) ^ RCON(i); + rk[7] = rk[1] ^ rk[6]; + rk[8] = rk[2] ^ rk[7]; + rk[9] = rk[3] ^ rk[8]; + if (i == 7) + return 12; + rk[10] = rk[4] ^ rk[9]; + rk[11] = rk[5] ^ rk[10]; + rk += 6; + } + } + + rk[6] = GETU32(cipherKey + 24); + rk[7] = GETU32(cipherKey + 28); + + if (keyBits == 256) { + for (i = 0; i < 7; i++) { + temp = rk[7]; + rk[8] = rk[0] ^ TE421(temp) ^ TE432(temp) ^ + TE443(temp) ^ TE414(temp) ^ RCON(i); + rk[9] = rk[1] ^ rk[8]; + rk[10] = rk[2] ^ rk[9]; + rk[11] = rk[3] ^ rk[10]; + if (i == 6) + return 14; + temp = rk[11]; + rk[12] = rk[4] ^ TE411(temp) ^ TE422(temp) ^ + TE433(temp) ^ TE444(temp); + rk[13] = rk[5] ^ rk[12]; + rk[14] = rk[6] ^ rk[13]; + rk[15] = rk[7] ^ rk[14]; + rk += 8; + } + } + + return -1; +} diff --git a/core/crypto/aes-omac1.c b/core/crypto/aes-omac1.c new file mode 100644 index 0000000..30b5262 --- /dev/null +++ b/core/crypto/aes-omac1.c @@ -0,0 +1,172 @@ +/* + * One-key CBC MAC (OMAC1) hash with AES + * + * Copyright (c) 2003-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes.h" +#include "aes_wrap.h" + +static void gf_mulx(u8 *pad) +{ + int i, carry; + + carry = pad[0] & 0x80; + for (i = 0; i < AES_BLOCK_SIZE - 1; i++) + pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); + pad[AES_BLOCK_SIZE - 1] <<= 1; + if (carry) + pad[AES_BLOCK_SIZE - 1] ^= 0x87; +} + + +/** + * omac1_aes_vector - One-Key CBC MAC (OMAC1) hash with AES + * @key: Key for the hash operation + * @key_len: Key length in octets + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) + * Returns: 0 on success, -1 on failure + * + * This is a mode for using block cipher (AES in this case) for authentication. + * OMAC1 was standardized with the name CMAC by NIST in a Special Publication + * (SP) 800-38B. + */ +int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac) +{ + void *ctx; + u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE]; + const u8 *pos, *end; + size_t i, e, left, total_len; + + if (TEST_FAIL()) + return -1; + + ctx = aes_encrypt_init(key, key_len); + if (ctx == NULL) + return -1; + os_memset(cbc, 0, AES_BLOCK_SIZE); + + total_len = 0; + for (e = 0; e < num_elem; e++) + total_len += len[e]; + left = total_len; + + e = 0; + pos = addr[0]; + end = pos + len[0]; + + while (left >= AES_BLOCK_SIZE) { + for (i = 0; i < AES_BLOCK_SIZE; i++) { + cbc[i] ^= *pos++; + if (pos >= end) { + /* + * Stop if there are no more bytes to process + * since there are no more entries in the array. + */ + if (i + 1 == AES_BLOCK_SIZE && + left == AES_BLOCK_SIZE) + break; + e++; + pos = addr[e]; + end = pos + len[e]; + } + } + if (left > AES_BLOCK_SIZE) + aes_encrypt(ctx, cbc, cbc); + left -= AES_BLOCK_SIZE; + } + + os_memset(pad, 0, AES_BLOCK_SIZE); + aes_encrypt(ctx, pad, pad); + gf_mulx(pad); + + if (left || total_len == 0) { + for (i = 0; i < left; i++) { + cbc[i] ^= *pos++; + if (pos >= end) { + /* + * Stop if there are no more bytes to process + * since there are no more entries in the array. + */ + if (i + 1 == left) + break; + e++; + pos = addr[e]; + end = pos + len[e]; + } + } + cbc[left] ^= 0x80; + gf_mulx(pad); + } + + for (i = 0; i < AES_BLOCK_SIZE; i++) + pad[i] ^= cbc[i]; + aes_encrypt(ctx, pad, mac); + aes_encrypt_deinit(ctx); + return 0; +} + + +/** + * omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128 + * @key: 128-bit key for the hash operation + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) + * Returns: 0 on success, -1 on failure + * + * This is a mode for using block cipher (AES in this case) for authentication. + * OMAC1 was standardized with the name CMAC by NIST in a Special Publication + * (SP) 800-38B. + */ +int omac1_aes_128_vector(const u8 *key, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac) +{ + return omac1_aes_vector(key, 16, num_elem, addr, len, mac); +} + + +/** + * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC) + * @key: 128-bit key for the hash operation + * @data: Data buffer for which a MAC is determined + * @data_len: Length of data buffer in bytes + * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) + * Returns: 0 on success, -1 on failure + * + * This is a mode for using block cipher (AES in this case) for authentication. + * OMAC1 was standardized with the name CMAC by NIST in a Special Publication + * (SP) 800-38B. + */ +int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac) +{ + return omac1_aes_128_vector(key, 1, &data, &data_len, mac); +} + + +/** + * omac1_aes_256 - One-Key CBC MAC (OMAC1) hash with AES-256 (aka AES-CMAC) + * @key: 256-bit key for the hash operation + * @data: Data buffer for which a MAC is determined + * @data_len: Length of data buffer in bytes + * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) + * Returns: 0 on success, -1 on failure + * + * This is a mode for using block cipher (AES in this case) for authentication. + * OMAC1 was standardized with the name CMAC by NIST in a Special Publication + * (SP) 800-38B. + */ +int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac) +{ + return omac1_aes_vector(key, 32, 1, &data, &data_len, mac); +} diff --git a/core/crypto/aes-siv.c b/core/crypto/aes-siv.c new file mode 100644 index 0000000..58656f2 --- /dev/null +++ b/core/crypto/aes-siv.c @@ -0,0 +1,207 @@ +/* + * AES SIV (RFC 5297) + * Copyright (c) 2013 Cozybit, Inc. + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes.h" +#include "aes_wrap.h" +#include "aes_siv.h" + + +static const u8 zero[AES_BLOCK_SIZE]; + + +static void dbl(u8 *pad) +{ + int i, carry; + + carry = pad[0] & 0x80; + for (i = 0; i < AES_BLOCK_SIZE - 1; i++) + pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); + pad[AES_BLOCK_SIZE - 1] <<= 1; + if (carry) + pad[AES_BLOCK_SIZE - 1] ^= 0x87; +} + + +static void xor(u8 *a, const u8 *b) +{ + int i; + + for (i = 0; i < AES_BLOCK_SIZE; i++) + *a++ ^= *b++; +} + + +static void xorend(u8 *a, int alen, const u8 *b, int blen) +{ + int i; + + if (alen < blen) + return; + + for (i = 0; i < blen; i++) + a[alen - blen + i] ^= b[i]; +} + + +static void pad_block(u8 *pad, const u8 *addr, size_t len) +{ + os_memset(pad, 0, AES_BLOCK_SIZE); + os_memcpy(pad, addr, len); + + if (len < AES_BLOCK_SIZE) + pad[len] = 0x80; +} + + +static int aes_s2v(const u8 *key, size_t key_len, + size_t num_elem, const u8 *addr[], size_t *len, u8 *mac) +{ + u8 tmp[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE]; + u8 *buf = NULL; + int ret; + size_t i; + const u8 *data[1]; + size_t data_len[1]; + + if (!num_elem) { + os_memcpy(tmp, zero, sizeof(zero)); + tmp[AES_BLOCK_SIZE - 1] = 1; + data[0] = tmp; + data_len[0] = sizeof(tmp); + return omac1_aes_vector(key, key_len, 1, data, data_len, mac); + } + + data[0] = zero; + data_len[0] = sizeof(zero); + ret = omac1_aes_vector(key, key_len, 1, data, data_len, tmp); + if (ret) + return ret; + + for (i = 0; i < num_elem - 1; i++) { + ret = omac1_aes_vector(key, key_len, 1, &addr[i], &len[i], + tmp2); + if (ret) + return ret; + + dbl(tmp); + xor(tmp, tmp2); + } + if (len[i] >= AES_BLOCK_SIZE) { + buf = os_memdup(addr[i], len[i]); + if (!buf) + return -ENOMEM; + + xorend(buf, len[i], tmp, AES_BLOCK_SIZE); + data[0] = buf; + ret = omac1_aes_vector(key, key_len, 1, data, &len[i], mac); + bin_clear_free(buf, len[i]); + return ret; + } + + dbl(tmp); + pad_block(tmp2, addr[i], len[i]); + xor(tmp, tmp2); + + data[0] = tmp; + data_len[0] = sizeof(tmp); + return omac1_aes_vector(key, key_len, 1, data, data_len, mac); +} + + +int aes_siv_encrypt(const u8 *key, size_t key_len, + const u8 *pw, size_t pwlen, + size_t num_elem, const u8 *addr[], const size_t *len, + u8 *out) +{ + const u8 *_addr[6]; + size_t _len[6]; + const u8 *k1, *k2; + u8 v[AES_BLOCK_SIZE]; + size_t i; + u8 *iv, *crypt_pw; + + if (num_elem > ARRAY_SIZE(_addr) - 1 || + (key_len != 32 && key_len != 48 && key_len != 64)) + return -1; + + key_len /= 2; + k1 = key; + k2 = key + key_len; + + for (i = 0; i < num_elem; i++) { + _addr[i] = addr[i]; + _len[i] = len[i]; + } + _addr[num_elem] = pw; + _len[num_elem] = pwlen; + + if (aes_s2v(k1, key_len, num_elem + 1, _addr, _len, v)) + return -1; + + iv = out; + crypt_pw = out + AES_BLOCK_SIZE; + + os_memcpy(iv, v, AES_BLOCK_SIZE); + os_memcpy(crypt_pw, pw, pwlen); + + /* zero out 63rd and 31st bits of ctr (from right) */ + v[8] &= 0x7f; + v[12] &= 0x7f; + return aes_ctr_encrypt(k2, key_len, v, crypt_pw, pwlen); +} + + +int aes_siv_decrypt(const u8 *key, size_t key_len, + const u8 *iv_crypt, size_t iv_c_len, + size_t num_elem, const u8 *addr[], const size_t *len, + u8 *out) +{ + const u8 *_addr[6]; + size_t _len[6]; + const u8 *k1, *k2; + size_t crypt_len; + size_t i; + int ret; + u8 iv[AES_BLOCK_SIZE]; + u8 check[AES_BLOCK_SIZE]; + + if (iv_c_len < AES_BLOCK_SIZE || num_elem > ARRAY_SIZE(_addr) - 1 || + (key_len != 32 && key_len != 48 && key_len != 64)) + return -1; + crypt_len = iv_c_len - AES_BLOCK_SIZE; + key_len /= 2; + k1 = key; + k2 = key + key_len; + + for (i = 0; i < num_elem; i++) { + _addr[i] = addr[i]; + _len[i] = len[i]; + } + _addr[num_elem] = out; + _len[num_elem] = crypt_len; + + os_memcpy(iv, iv_crypt, AES_BLOCK_SIZE); + os_memcpy(out, iv_crypt + AES_BLOCK_SIZE, crypt_len); + + iv[8] &= 0x7f; + iv[12] &= 0x7f; + + ret = aes_ctr_encrypt(k2, key_len, iv, out, crypt_len); + if (ret) + return ret; + + ret = aes_s2v(k1, key_len, num_elem + 1, _addr, _len, check); + if (ret) + return ret; + if (os_memcmp(check, iv_crypt, AES_BLOCK_SIZE) == 0) + return 0; + + return -1; +} diff --git a/core/crypto/aes.h b/core/crypto/aes.h new file mode 100644 index 0000000..8ab3de2 --- /dev/null +++ b/core/crypto/aes.h @@ -0,0 +1,21 @@ +/* + * AES functions + * Copyright (c) 2003-2006, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef AES_H +#define AES_H + +#define AES_BLOCK_SIZE 16 + +void * aes_encrypt_init(const u8 *key, size_t len); +int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt); +void aes_encrypt_deinit(void *ctx); +void * aes_decrypt_init(const u8 *key, size_t len); +int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain); +void aes_decrypt_deinit(void *ctx); + +#endif /* AES_H */ diff --git a/core/crypto/aes_i.h b/core/crypto/aes_i.h new file mode 100644 index 0000000..54375cf --- /dev/null +++ b/core/crypto/aes_i.h @@ -0,0 +1,125 @@ +/* + * AES (Rijndael) cipher + * Copyright (c) 2003-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef AES_I_H +#define AES_I_H + +#include "aes.h" + +/* #define FULL_UNROLL */ +#define AES_SMALL_TABLES + +extern const u32 Te0[256]; +extern const u32 Te1[256]; +extern const u32 Te2[256]; +extern const u32 Te3[256]; +extern const u32 Te4[256]; +extern const u32 Td0[256]; +extern const u32 Td1[256]; +extern const u32 Td2[256]; +extern const u32 Td3[256]; +extern const u32 Td4[256]; +extern const u32 rcon[10]; +extern const u8 Td4s[256]; +extern const u8 rcons[10]; + +#ifndef AES_SMALL_TABLES + +#define RCON(i) rcon[(i)] + +#define TE0(i) Te0[((i) >> 24) & 0xff] +#define TE1(i) Te1[((i) >> 16) & 0xff] +#define TE2(i) Te2[((i) >> 8) & 0xff] +#define TE3(i) Te3[(i) & 0xff] +#define TE41(i) (Te4[((i) >> 24) & 0xff] & 0xff000000) +#define TE42(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000) +#define TE43(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00) +#define TE44(i) (Te4[(i) & 0xff] & 0x000000ff) +#define TE421(i) (Te4[((i) >> 16) & 0xff] & 0xff000000) +#define TE432(i) (Te4[((i) >> 8) & 0xff] & 0x00ff0000) +#define TE443(i) (Te4[(i) & 0xff] & 0x0000ff00) +#define TE414(i) (Te4[((i) >> 24) & 0xff] & 0x000000ff) +#define TE411(i) (Te4[((i) >> 24) & 0xff] & 0xff000000) +#define TE422(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000) +#define TE433(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00) +#define TE444(i) (Te4[(i) & 0xff] & 0x000000ff) +#define TE4(i) (Te4[(i)] & 0x000000ff) + +#define TD0(i) Td0[((i) >> 24) & 0xff] +#define TD1(i) Td1[((i) >> 16) & 0xff] +#define TD2(i) Td2[((i) >> 8) & 0xff] +#define TD3(i) Td3[(i) & 0xff] +#define TD41(i) (Td4[((i) >> 24) & 0xff] & 0xff000000) +#define TD42(i) (Td4[((i) >> 16) & 0xff] & 0x00ff0000) +#define TD43(i) (Td4[((i) >> 8) & 0xff] & 0x0000ff00) +#define TD44(i) (Td4[(i) & 0xff] & 0x000000ff) +#define TD0_(i) Td0[(i) & 0xff] +#define TD1_(i) Td1[(i) & 0xff] +#define TD2_(i) Td2[(i) & 0xff] +#define TD3_(i) Td3[(i) & 0xff] + +#else /* AES_SMALL_TABLES */ + +#define RCON(i) (rcons[(i)] << 24) + +static inline u32 rotr(u32 val, int bits) +{ + return (val >> bits) | (val << (32 - bits)); +} + +#define TE0(i) Te0[((i) >> 24) & 0xff] +#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8) +#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16) +#define TE3(i) rotr(Te0[(i) & 0xff], 24) +#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000) +#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000) +#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00) +#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff) +#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000) +#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000) +#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00) +#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff) +#define TE411(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000) +#define TE422(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000) +#define TE433(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00) +#define TE444(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff) +#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff) + +#define TD0(i) Td0[((i) >> 24) & 0xff] +#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8) +#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16) +#define TD3(i) rotr(Td0[(i) & 0xff], 24) +#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24) +#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16) +#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8) +#define TD44(i) (Td4s[(i) & 0xff]) +#define TD0_(i) Td0[(i) & 0xff] +#define TD1_(i) rotr(Td0[(i) & 0xff], 8) +#define TD2_(i) rotr(Td0[(i) & 0xff], 16) +#define TD3_(i) rotr(Td0[(i) & 0xff], 24) + +#endif /* AES_SMALL_TABLES */ + +#ifdef _MSC_VER +#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) +#define GETU32(p) SWAP(*((u32 *)(p))) +#define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } +#else +#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \ +((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) +#define PUTU32(ct, st) { \ +(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \ +(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } +#endif + +#define AES_PRIV_SIZE (4 * 4 * 15 + 4) +#define AES_PRIV_NR_POS (4 * 15) + +int rijndaelKeySetupEnc(u32 rk[], const u8 cipherKey[], int keyBits); + +#endif /* AES_I_H */ diff --git a/core/crypto/aes_siv.h b/core/crypto/aes_siv.h new file mode 100644 index 0000000..fb05d80 --- /dev/null +++ b/core/crypto/aes_siv.h @@ -0,0 +1,21 @@ +/* + * AES SIV (RFC 5297) + * Copyright (c) 2013 Cozybit, Inc. + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef AES_SIV_H +#define AES_SIV_H + +int aes_siv_encrypt(const u8 *key, size_t key_len, + const u8 *pw, size_t pwlen, + size_t num_elem, const u8 *addr[], const size_t *len, + u8 *out); +int aes_siv_decrypt(const u8 *key, size_t key_len, + const u8 *iv_crypt, size_t iv_c_len, + size_t num_elem, const u8 *addr[], const size_t *len, + u8 *out); + +#endif /* AES_SIV_H */ diff --git a/core/crypto/aes_wrap.h b/core/crypto/aes_wrap.h new file mode 100644 index 0000000..b70b1d2 --- /dev/null +++ b/core/crypto/aes_wrap.h @@ -0,0 +1,73 @@ +/* + * AES-based functions + * + * - AES Key Wrap Algorithm (RFC3394) + * - One-Key CBC MAC (OMAC1) hash with AES-128 and AES-256 + * - AES-128/192/256 CTR mode encryption + * - AES-128 EAX mode encryption/decryption + * - AES-128 CBC + * - AES-GCM + * - AES-CCM + * + * Copyright (c) 2003-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef AES_WRAP_H +#define AES_WRAP_H + +int __must_check aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, + u8 *cipher); +int __must_check aes_unwrap(const u8 *kek, size_t kek_len, int n, + const u8 *cipher, u8 *plain); +int __must_check omac1_aes_vector(const u8 *key, size_t key_len, + size_t num_elem, const u8 *addr[], + const size_t *len, u8 *mac); +int __must_check omac1_aes_128_vector(const u8 *key, size_t num_elem, + const u8 *addr[], const size_t *len, + u8 *mac); +int __must_check omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, + u8 *mac); +int __must_check omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, + u8 *mac); +int __must_check aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out); +int __must_check aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, + u8 *data, size_t data_len); +int __must_check aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, + u8 *data, size_t data_len); +int __must_check aes_128_eax_encrypt(const u8 *key, + const u8 *nonce, size_t nonce_len, + const u8 *hdr, size_t hdr_len, + u8 *data, size_t data_len, u8 *tag); +int __must_check aes_128_eax_decrypt(const u8 *key, + const u8 *nonce, size_t nonce_len, + const u8 *hdr, size_t hdr_len, + u8 *data, size_t data_len, const u8 *tag); +int __must_check aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, + size_t data_len); +int __must_check aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, + size_t data_len); +int __must_check aes_gcm_ae(const u8 *key, size_t key_len, + const u8 *iv, size_t iv_len, + const u8 *plain, size_t plain_len, + const u8 *aad, size_t aad_len, + u8 *crypt, u8 *tag); +int __must_check aes_gcm_ad(const u8 *key, size_t key_len, + const u8 *iv, size_t iv_len, + const u8 *crypt, size_t crypt_len, + const u8 *aad, size_t aad_len, const u8 *tag, + u8 *plain); +int __must_check aes_gmac(const u8 *key, size_t key_len, + const u8 *iv, size_t iv_len, + const u8 *aad, size_t aad_len, u8 *tag); +int __must_check aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce, + size_t M, const u8 *plain, size_t plain_len, + const u8 *aad, size_t aad_len, u8 *crypt, u8 *auth); +int __must_check aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce, + size_t M, const u8 *crypt, size_t crypt_len, + const u8 *aad, size_t aad_len, const u8 *auth, + u8 *plain); + +#endif /* AES_WRAP_H */ diff --git a/core/crypto/ccmp.c b/core/crypto/ccmp.c new file mode 100644 index 0000000..3ebd487 --- /dev/null +++ b/core/crypto/ccmp.c @@ -0,0 +1,385 @@ +/* + * CTR with CBC-MAC Protocol (CCMP) + * Copyright (c) 2010-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes.h" +#include "aes_wrap.h" +#include "wlancrypto_wrap.h" + + + +static void ccmp_aad_nonce(_adapter *padapter, const struct ieee80211_hdr *hdr, const u8 *data, + u8 *aad, size_t *aad_len, u8 *nonce) +{ + u16 fc, stype, seq; + int qos = 0, addr4 = 0; + u8 *pos; + + nonce[0] = 0; + + fc = le_to_host16(hdr->frame_control); + stype = WLAN_FC_GET_STYPE(fc); + if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == + (WLAN_FC_TODS | WLAN_FC_FROMDS)) + addr4 = 1; + + if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) { + fc &= ~0x0070; /* Mask subtype bits */ + if (stype & WLAN_FC_STYPE_QOS_DATA) { + const u8 *qc; + qos = 1; + fc &= ~WLAN_FC_ORDER; + qc = (const u8 *)hdr + 24; + if (addr4) + qc += ETH_ALEN; + nonce[0] = qc[0] & 0x0f; + } + } else if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT) + nonce[0] |= 0x10; /* Management */ + + fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA); + fc |= WLAN_FC_ISWEP; + WPA_PUT_LE16(aad, fc); + pos = aad + 2; + os_memcpy(pos, GetAddr1Ptr((u8 *)hdr), 3 * ETH_ALEN); + pos += 3 * ETH_ALEN; + seq = le_to_host16(hdr->seq_ctrl); + seq &= ~0xfff0; /* Mask Seq#; do not modify Frag# */ + WPA_PUT_LE16(pos, seq); + pos += 2; + + os_memcpy(pos, (u8 *)hdr + 24, addr4 * ETH_ALEN + qos * 2); + pos += addr4 * ETH_ALEN; + if (qos) { + pos[0] &= ~0x70; + /* only spp mode need to refer QoS bit7 */ + if (padapter->registrypriv.amsdu_mode != RTW_AMSDU_MODE_SPP) + pos[0] &= ~0x80; + pos++; + *pos++ = 0x00; + } + + *aad_len = pos - aad; + + os_memcpy(nonce + 1, hdr->addr2, ETH_ALEN); + nonce[7] = data[7]; /* PN5 */ + nonce[8] = data[6]; /* PN4 */ + nonce[9] = data[5]; /* PN3 */ + nonce[10] = data[4]; /* PN2 */ + nonce[11] = data[1]; /* PN1 */ + nonce[12] = data[0]; /* PN0 */ +} + + +static void ccmp_aad_nonce_pv1(const u8 *hdr, const u8 *a1, const u8 *a2, + const u8 *a3, const u8 *pn, + u8 *aad, size_t *aad_len, u8 *nonce) +{ + u16 fc, type; + u8 *pos; + + nonce[0] = BIT(5); /* PV1 */ + /* TODO: Priority for QMF; 0 is used for Data frames */ + + fc = WPA_GET_LE16(hdr); + type = (fc & (BIT(2) | BIT(3) | BIT(4))) >> 2; + + if (type == 1) + nonce[0] |= 0x10; /* Management */ + + fc &= ~(BIT(10) | BIT(11) | BIT(13) | BIT(14) | BIT(15)); + fc |= BIT(12); + WPA_PUT_LE16(aad, fc); + pos = aad + 2; + if (type == 0 || type == 3) { + const u8 *sc; + + os_memcpy(pos, a1, ETH_ALEN); + pos += ETH_ALEN; + os_memcpy(pos, a2, ETH_ALEN); + pos += ETH_ALEN; + + if (type == 0) { + /* Either A1 or A2 contains SID */ + sc = hdr + 2 + 2 + ETH_ALEN; + } else { + /* Both A1 and A2 contain full addresses */ + sc = hdr + 2 + 2 * ETH_ALEN; + } + /* SC with Sequence Number subfield (bits 4-15 of the Sequence + * Control field) masked to 0. */ + *pos++ = *sc & 0x0f; + *pos++ = 0; + + if (a3) { + os_memcpy(pos, a3, ETH_ALEN); + pos += ETH_ALEN; + } + } + + *aad_len = pos - aad; + + os_memcpy(nonce + 1, a2, ETH_ALEN); + nonce[7] = pn[5]; /* PN5 */ + nonce[8] = pn[4]; /* PN4 */ + nonce[9] = pn[3]; /* PN3 */ + nonce[10] = pn[2]; /* PN2 */ + nonce[11] = pn[1]; /* PN1 */ + nonce[12] = pn[0]; /* PN0 */ +} + + +u8 * ccmp_decrypt(_adapter *padapter, const u8 *tk, const struct ieee80211_hdr *hdr, + const u8 *data, size_t data_len, size_t *decrypted_len) +{ + u8 aad[30], nonce[13]; + size_t aad_len; + size_t mlen; + u8 *plain; + + if (data_len < 8 + 8) + return NULL; + + plain = os_malloc(data_len + AES_BLOCK_SIZE); + if (plain == NULL) + return NULL; + + mlen = data_len - 8 - 8; + + os_memset(aad, 0, sizeof(aad)); + ccmp_aad_nonce(padapter, hdr, data, aad, &aad_len, nonce); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP AAD", aad, aad_len); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP nonce", nonce, 13); + + if (aes_ccm_ad(tk, 16, nonce, 8, data + 8, mlen, aad, aad_len, + data + 8 + mlen, plain) < 0) { + u16 seq_ctrl = le_to_host16(hdr->seq_ctrl); + wpa_printf(_MSG_INFO_, "Invalid CCMP MIC in frame: A1=" MACSTR + " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u", + MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), + MAC2STR(hdr->addr3), + WLAN_GET_SEQ_SEQ(seq_ctrl), + WLAN_GET_SEQ_FRAG(seq_ctrl)); + rtw_mfree(plain, data_len + AES_BLOCK_SIZE); + return NULL; + } + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP decrypted", plain, mlen); + + *decrypted_len = mlen; + return plain; +} + + +void ccmp_get_pn(u8 *pn, const u8 *data) +{ + pn[0] = data[7]; /* PN5 */ + pn[1] = data[6]; /* PN4 */ + pn[2] = data[5]; /* PN3 */ + pn[3] = data[4]; /* PN2 */ + pn[4] = data[1]; /* PN1 */ + pn[5] = data[0]; /* PN0 */ +} + + +u8 * ccmp_encrypt(_adapter *padapter, const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos, + u8 *pn, int keyid, size_t *encrypted_len) +{ + u8 aad[30], nonce[13]; + size_t aad_len, plen; + u8 *crypt, *pos, *pdata; + struct ieee80211_hdr *hdr; + + if (len < hdrlen || hdrlen < 24) + return NULL; + plen = len - hdrlen; + + crypt = os_malloc(hdrlen + 8 + plen + 8 + AES_BLOCK_SIZE); + if (crypt == NULL) + return NULL; + + if (pn == NULL) { + os_memcpy(crypt, frame, hdrlen + 8); + hdr = (struct ieee80211_hdr *) crypt; + hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP); + pos = crypt + hdrlen + 8; + pdata = frame + hdrlen + 8; + } else { + os_memcpy(crypt, frame, hdrlen); + hdr = (struct ieee80211_hdr *) crypt; + hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP); + pos = crypt + hdrlen; + *pos++ = pn[5]; /* PN0 */ + *pos++ = pn[4]; /* PN1 */ + *pos++ = 0x00; /* Rsvd */ + *pos++ = 0x20 | (keyid << 6); + *pos++ = pn[3]; /* PN2 */ + *pos++ = pn[2]; /* PN3 */ + *pos++ = pn[1]; /* PN4 */ + *pos++ = pn[0]; /* PN5 */ + pdata = frame + hdrlen; + } + + os_memset(aad, 0, sizeof(aad)); + ccmp_aad_nonce(padapter, hdr, crypt + hdrlen, aad, &aad_len, nonce); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP AAD", aad, aad_len); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP nonce", nonce, 13); + + if (aes_ccm_ae(tk, 16, nonce, 8, pdata, plen, aad, aad_len, + pos, pos + plen) < 0) { + rtw_mfree(crypt, hdrlen + 8 + plen + 8 + AES_BLOCK_SIZE); + return NULL; + } + + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP encrypted", crypt + hdrlen + 8, plen); + + *encrypted_len = hdrlen + 8 + plen + 8; + + return crypt; +} + + +u8 * ccmp_encrypt_pv1(const u8 *tk, const u8 *a1, const u8 *a2, const u8 *a3, + const u8 *frame, size_t len, + size_t hdrlen, const u8 *pn, int keyid, + size_t *encrypted_len) +{ + u8 aad[24], nonce[13]; + size_t aad_len, plen; + u8 *crypt, *pos; + struct ieee80211_hdr *hdr; + + if (len < hdrlen || hdrlen < 12) + return NULL; + plen = len - hdrlen; + + crypt = os_malloc(hdrlen + plen + 8 + AES_BLOCK_SIZE); + if (crypt == NULL) + return NULL; + + os_memcpy(crypt, frame, hdrlen); + hdr = (struct ieee80211_hdr *) crypt; + hdr->frame_control |= host_to_le16(BIT(12)); /* Protected Frame */ + pos = crypt + hdrlen; + + os_memset(aad, 0, sizeof(aad)); + ccmp_aad_nonce_pv1(crypt, a1, a2, a3, pn, aad, &aad_len, nonce); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP AAD", aad, aad_len); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP nonce", nonce, sizeof(nonce)); + + if (aes_ccm_ae(tk, 16, nonce, 8, frame + hdrlen, plen, aad, aad_len, + pos, pos + plen) < 0) { + rtw_mfree(crypt, hdrlen + plen + 8 + AES_BLOCK_SIZE); + return NULL; + } + + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP encrypted", crypt + hdrlen, plen); + + *encrypted_len = hdrlen + plen + 8; + + return crypt; +} + + +u8 * ccmp_256_decrypt(_adapter *padapter, const u8 *tk, const struct ieee80211_hdr *hdr, + const u8 *data, size_t data_len, size_t *decrypted_len) +{ + u8 aad[30], nonce[13]; + size_t aad_len; + size_t mlen; + u8 *plain; + + if (data_len < 8 + 16) + return NULL; + + plain = os_malloc(data_len + AES_BLOCK_SIZE); + if (plain == NULL) + return NULL; + + mlen = data_len - 8 - 16; + + os_memset(aad, 0, sizeof(aad)); + ccmp_aad_nonce(padapter, hdr, data, aad, &aad_len, nonce); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 AAD", aad, aad_len); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 nonce", nonce, 13); + + if (aes_ccm_ad(tk, 32, nonce, 16, data + 8, mlen, aad, aad_len, + data + 8 + mlen, plain) < 0) { + u16 seq_ctrl = le_to_host16(hdr->seq_ctrl); + wpa_printf(_MSG_INFO_, "Invalid CCMP-256 MIC in frame: A1=" MACSTR + " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u", + MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), + MAC2STR(hdr->addr3), + WLAN_GET_SEQ_SEQ(seq_ctrl), + WLAN_GET_SEQ_FRAG(seq_ctrl)); + rtw_mfree(plain, data_len + AES_BLOCK_SIZE); + return NULL; + } + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 decrypted", plain, mlen); + + *decrypted_len = mlen; + return plain; +} + + +u8 * ccmp_256_encrypt(_adapter *padapter, const u8 *tk, u8 *frame, size_t len, size_t hdrlen, + u8 *qos, u8 *pn, int keyid, size_t *encrypted_len) +{ + u8 aad[30], nonce[13]; + size_t aad_len, plen; + u8 *crypt, *pos, *pdata; + struct ieee80211_hdr *hdr; + + if (len < hdrlen || hdrlen < 24) + return NULL; + plen = len - hdrlen; + + crypt = os_malloc(hdrlen + 8 + plen + 16 + AES_BLOCK_SIZE); + if (crypt == NULL) + return NULL; + + if (pn == NULL) { + os_memcpy(crypt, frame, hdrlen + 8); + hdr = (struct ieee80211_hdr *) crypt; + hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP); + pos = crypt + hdrlen + 8; + pdata = frame + hdrlen + 8; + } else { + os_memcpy(crypt, frame, hdrlen); + hdr = (struct ieee80211_hdr *) crypt; + hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP); + pos = crypt + hdrlen; + *pos++ = pn[5]; /* PN0 */ + *pos++ = pn[4]; /* PN1 */ + *pos++ = 0x00; /* Rsvd */ + *pos++ = 0x20 | (keyid << 6); + *pos++ = pn[3]; /* PN2 */ + *pos++ = pn[2]; /* PN3 */ + *pos++ = pn[1]; /* PN4 */ + *pos++ = pn[0]; /* PN5 */ + pdata = frame + hdrlen; + } + + os_memset(aad, 0, sizeof(aad)); + ccmp_aad_nonce(padapter, hdr, crypt + hdrlen, aad, &aad_len, nonce); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 AAD", aad, aad_len); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 nonce", nonce, 13); + + if (aes_ccm_ae(tk, 32, nonce, 16, pdata, plen, aad, aad_len, + pos, pos + plen) < 0) { + rtw_mfree(crypt, hdrlen + 8 + plen + 16 + AES_BLOCK_SIZE); + return NULL; + } + + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 encrypted", crypt + hdrlen + 8, + plen); + + *encrypted_len = hdrlen + 8 + plen + 16; + + return crypt; +} diff --git a/core/crypto/gcmp.c b/core/crypto/gcmp.c new file mode 100644 index 0000000..9141d55 --- /dev/null +++ b/core/crypto/gcmp.c @@ -0,0 +1,194 @@ +/* + * GCM with GMAC Protocol (GCMP) + * Copyright (c) 2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes.h" +#include "aes_wrap.h" +#include "wlancrypto_wrap.h" + + +static void gcmp_aad_nonce(_adapter * padapter, const struct ieee80211_hdr *hdr, const u8 *data, + u8 *aad, size_t *aad_len, u8 *nonce) +{ + u16 fc, stype, seq; + int qos = 0, addr4 = 0; + u8 *pos; + + fc = le_to_host16(hdr->frame_control); + stype = WLAN_FC_GET_STYPE(fc); + if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == + (WLAN_FC_TODS | WLAN_FC_FROMDS)) + addr4 = 1; + + if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) { + fc &= ~0x0070; /* Mask subtype bits */ + if (stype & WLAN_FC_STYPE_QOS_DATA) { + const u8 *qc; + qos = 1; + fc &= ~WLAN_FC_ORDER; + qc = (const u8 *)hdr + 24; + if (addr4) + qc += ETH_ALEN; + } + } + + fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA); + WPA_PUT_LE16(aad, fc); + pos = aad + 2; + os_memcpy(pos, GetAddr1Ptr((u8 *)hdr), 3 * ETH_ALEN); + pos += 3 * ETH_ALEN; + seq = le_to_host16(hdr->seq_ctrl); + seq &= ~0xfff0; /* Mask Seq#; do not modify Frag# */ + WPA_PUT_LE16(pos, seq); + pos += 2; + + wpa_printf(_MSG_INFO_, "pos - aad = %u, qos(%d)\n", (pos - aad), qos); + + os_memcpy(pos, (u8 *)hdr + 24, addr4 * ETH_ALEN + qos * 2); + pos += addr4 * ETH_ALEN; + if (qos) { + pos[0] &= ~0x70; + /* only spp mode need to refer QoS bit7 */ + if (padapter->registrypriv.amsdu_mode != RTW_AMSDU_MODE_SPP) + pos[0] &= ~0x80; + pos++; + *pos++ = 0x00; + } + + wpa_printf(_MSG_INFO_, "pos - aad = %u\n", (pos - aad)); + *aad_len = pos - aad; + + os_memcpy(nonce, hdr->addr2, ETH_ALEN); + nonce[6] = data[7]; /* PN5 */ + nonce[7] = data[6]; /* PN4 */ + nonce[8] = data[5]; /* PN3 */ + nonce[9] = data[4]; /* PN2 */ + nonce[10] = data[1]; /* PN1 */ + nonce[11] = data[0]; /* PN0 */ +} + +/** + * gcmp_decrypt - + * @tk: the temporal key + * @tk_len: length of @tk + * @hdr: the mac header + * @data: payload after mac header (PN + enc_data + MIC) + * @data_len: length of @data (PN + enc_data + MIC) + * @decrypted_len: length of the data decrypted + */ +u8 * gcmp_decrypt(_adapter *padapter, const u8 *tk, size_t tk_len, const struct ieee80211_hdr *hdr, + const u8 *data, size_t data_len, size_t *decrypted_len) +{ + u8 aad[30], nonce[12], *plain; + size_t aad_len, mlen; + const u8 *m; + + if (data_len < 8 + 16) + return NULL; + + plain = os_malloc(data_len + AES_BLOCK_SIZE); + if (plain == NULL) + return NULL; + + m = data + 8; + mlen = data_len - 8 - 16; + + os_memset(aad, 0, sizeof(aad)); + gcmp_aad_nonce(padapter, hdr, data, aad, &aad_len, nonce); + wpa_hexdump(_MSG_EXCESSIVE_, "GCMP AAD", aad, aad_len); + wpa_hexdump(_MSG_EXCESSIVE_, "GCMP nonce", nonce, sizeof(nonce)); + + if (aes_gcm_ad(tk, tk_len, nonce, sizeof(nonce), m, mlen, aad, aad_len, + m + mlen, plain) < 0) { + u16 seq_ctrl = le_to_host16(hdr->seq_ctrl); + wpa_printf(_MSG_INFO_, "Invalid GCMP frame: A1=" MACSTR + " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u", + MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), + MAC2STR(hdr->addr3), + WLAN_GET_SEQ_SEQ(seq_ctrl), + WLAN_GET_SEQ_FRAG(seq_ctrl)); + rtw_mfree(plain, data_len + AES_BLOCK_SIZE); + return NULL; + } + + *decrypted_len = mlen; + return plain; +} + +/** + * gcmp_encrypt - + * @tk: the temporal key + * @tk_len: length of @tk + * @frame: the point to mac header, the frame including mac header and payload, + * if @pn is NULL, then the frame including pn + * @len: length of @frame + * length = mac header + payload + * @hdrlen: length of the mac header + * @qos: pointer to the QOS field of the frame + * @pn: packet number + * @keyid: key id + * @encrypted_len: length of the encrypted frame + * including mac header, pn, payload and MIC + */ +u8 * gcmp_encrypt(_adapter *padapter, const u8 *tk, size_t tk_len, const u8 *frame, size_t len, + size_t hdrlen, const u8 *qos, + const u8 *pn, int keyid, size_t *encrypted_len) +{ + u8 aad[30], nonce[12], *crypt, *pos; + const u8 *pdata; + size_t aad_len, plen; + struct ieee80211_hdr *hdr; + + if (len < hdrlen || hdrlen < 24) + return NULL; + plen = len - hdrlen; + + crypt = os_malloc(hdrlen + 8 + plen + 16 + AES_BLOCK_SIZE); + if (crypt == NULL) + return NULL; + + if (pn == NULL) { + os_memcpy(crypt, frame, hdrlen + 8); + hdr = (struct ieee80211_hdr *)crypt; + pos = crypt + hdrlen + 8; + pdata = frame + hdrlen + 8; + } else { + os_memcpy(crypt, frame, hdrlen); + hdr = (struct ieee80211_hdr *)crypt; + pos = crypt + hdrlen; + + *pos++ = pn[5]; /* PN0 */ + *pos++ = pn[4]; /* PN1 */ + *pos++ = 0x00; /* Rsvd */ + *pos++ = 0x20 | (keyid << 6); + *pos++ = pn[3]; /* PN2 */ + *pos++ = pn[2]; /* PN3 */ + *pos++ = pn[1]; /* PN4 */ + *pos++ = pn[0]; /* PN5 */ + pdata = frame + hdrlen; + } + + os_memset(aad, 0, sizeof(aad)); + gcmp_aad_nonce(padapter, hdr, crypt + hdrlen, aad, &aad_len, nonce); + wpa_hexdump(_MSG_EXCESSIVE_, "GCMP AAD", aad, aad_len); + wpa_hexdump(_MSG_EXCESSIVE_, "GCMP nonce", nonce, sizeof(nonce)); + + if (aes_gcm_ae(tk, tk_len, nonce, sizeof(nonce), pdata, plen, + aad, aad_len, pos, pos + plen) < 0) { + rtw_mfree(crypt, hdrlen + 8 + plen + 16 + AES_BLOCK_SIZE); + return NULL; + } + + wpa_hexdump(_MSG_EXCESSIVE_, "GCMP MIC", pos + plen, 16); + wpa_hexdump(_MSG_EXCESSIVE_, "GCMP encrypted", pos, plen); + + *encrypted_len = hdrlen + 8 + plen + 16; + + return crypt; +} diff --git a/core/crypto/rtw_crypto_wrap.c b/core/crypto/rtw_crypto_wrap.c new file mode 100644 index 0000000..8fdb3c9 --- /dev/null +++ b/core/crypto/rtw_crypto_wrap.c @@ -0,0 +1,85 @@ +#include "rtw_crypto_wrap.h" + +#ifndef DEBUG_CRYPTO +#define DEBUG_CRYPTO 0 +#endif /* DEBUG_CRYTO */ + +int os_memcmp(const void *s1, const void *s2, size_t n) +{ + return _rtw_memcmp2(s1, s2, n); +} + +int os_memcmp_const(const void *a, const void *b, size_t len) +{ + const u8 *aa = a; + const u8 *bb = b; + size_t i; + u8 res; + + for (res = 0, i = 0; i < len; i++) + res |= aa[i] ^ bb[i]; + + return res; +} + +void* os_memdup(const void *src, u32 sz) +{ + void *r = rtw_malloc(sz); + + if (r && src) + _rtw_memcpy(r, src, sz); + return r; +} + +size_t os_strlen(const char *s) +{ + const char *p = s; + while (*p) + p++; + return p - s; +} + + +void forced_memzero(void *ptr, size_t len) +{ + _rtw_memset(ptr, 0, len); +} + +void bin_clear_free(void *bin, size_t len) +{ + if (bin) { + forced_memzero(bin, len); + rtw_mfree(bin, len); + } +} + +void wpa_printf(int level, const char *fmt, ...) +{ +#if DEBUG_CRYPTO +#define MSG_LEN 100 + va_list args; + u8 buf[MSG_LEN] = { 0 }; + int err; + + va_start(args, fmt); + err = vsnprintf(buf, MSG_LEN, fmt, args); + va_end(args); + + RTW_INFO("%s", buf); +#undef MSG_LEN +#endif /* DEBUG_CRYPTO */ +} + +void wpa_hexdump(int level, const char *title, const void *buf, size_t len) +{ +#if DEBUG_CRYPTO + RTW_INFO_DUMP((u8 *)title, buf, len); +#endif /* DEBUG_CRYPTO */ +} + +void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len) +{ +#if DEBUG_CRYPTO + RTW_INFO_DUMP((u8 *)title, buf, len); +#endif /* DEBUG_CRYPTO */ +} diff --git a/core/crypto/rtw_crypto_wrap.h b/core/crypto/rtw_crypto_wrap.h new file mode 100644 index 0000000..9b64a14 --- /dev/null +++ b/core/crypto/rtw_crypto_wrap.h @@ -0,0 +1,64 @@ +#ifndef RTW_CRYTO_WRAP_H +#define RTW_CRYTO_WRAP_H + +#include + +#define TEST_FAIL() 0 + +#define os_memset _rtw_memset +#define os_memcpy _rtw_memcpy +#define os_malloc rtw_malloc + +#define le_to_host16 le16_to_cpu +#define host_to_le16 cpu_to_le16 + +#define WPA_PUT_LE16 RTW_PUT_LE16 +#define WPA_GET_LE16 RTW_GET_LE16 +#define WPA_PUT_LE32 RTW_PUT_LE32 +#define WPA_GET_LE32 RTW_GET_LE32 +#define WPA_PUT_LE64 RTW_PUT_LE64 +#define WPA_GET_LE64 RTW_GET_LE64 +#define WPA_PUT_BE16 RTW_PUT_BE16 +#define WPA_GET_BE16 RTW_GET_BE16 +#define WPA_PUT_BE32 RTW_PUT_BE32 +#define WPA_GET_BE32 RTW_GET_BE32 +#define WPA_PUT_BE64 RTW_PUT_BE64 +#define WPA_GET_BE64 RTW_GET_BE64 + +#ifndef MAC2STR +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" +#endif + +#define WLAN_FC_PVER 0x0003 +#define WLAN_FC_TODS 0x0100 +#define WLAN_FC_FROMDS 0x0200 +#define WLAN_FC_MOREFRAG 0x0400 +#define WLAN_FC_RETRY 0x0800 +#define WLAN_FC_PWRMGT 0x1000 +#define WLAN_FC_MOREDATA 0x2000 +#define WLAN_FC_ISWEP 0x4000 +#define WLAN_FC_ORDER 0x8000 + +#define WLAN_FC_TYPE_DATA RTW_IEEE80211_FTYPE_DATA +#define WLAN_FC_TYPE_MGMT RTW_IEEE80211_FTYPE_MGMT + +#define WLAN_FC_STYPE_QOS_DATA RTW_IEEE80211_STYPE_QOS_DATA + +enum { + _MSG_EXCESSIVE_, _MSG_MSGDUMP_, _MSG_DEBUG_, _MSG_INFO_, _MSG_WARNING_, _MSG_ERROR_ +}; + +int os_memcmp(const void *s1, const void *s2, size_t n); +int os_memcmp_const(const void *a, const void *b, size_t len); +void* os_memdup(const void *src, u32 sz); +size_t os_strlen(const char *s); + +void forced_memzero(void *ptr, size_t len); +void bin_clear_free(void *bin, size_t len); + +void wpa_printf(int level, const char *fmt, ...); +void wpa_hexdump(int level, const char *title, const void *buf, size_t len); +void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len); + +#endif /* RTW_CRYTO_WRAP_H */ diff --git a/core/crypto/sha256-internal.c b/core/crypto/sha256-internal.c new file mode 100644 index 0000000..98228ea --- /dev/null +++ b/core/crypto/sha256-internal.c @@ -0,0 +1,230 @@ +/* + * SHA-256 hash implementation and interface functions + * Copyright (c) 2003-2011, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +//#include "common.h" +#include "sha256.h" +#include "sha256_i.h" +//#include "crypto.h" +#include "wlancrypto_wrap.h" + + +/** + * sha256_vector - SHA256 hash for data vector + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 of failure + */ +int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, + u8 *mac) +{ + struct _sha256_state ctx; + size_t i; + + if (TEST_FAIL()) + return -1; + + _sha256_init(&ctx); + for (i = 0; i < num_elem; i++) + if (sha256_process(&ctx, addr[i], len[i])) + return -1; + if (sha256_done(&ctx, mac)) + return -1; + return 0; +} + + +/* ===== start - public domain SHA256 implementation ===== */ + +/* This is based on SHA256 implementation in LibTomCrypt that was released into + * public domain by Tom St Denis. */ + +/* the K array */ +static const unsigned long K[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, + 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, + 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, + 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, + 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, + 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, + 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, + 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, + 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + + +/* Various logical functions */ +#define RORc(x, y) \ +( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \ + ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL) +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) RORc((x), (n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif + +/* compress 512-bits */ +static int sha256_compress(struct _sha256_state *md, unsigned char *buf) +{ + u32 S[8], W[64], t0, t1; + u32 t; + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->state[i]; + } + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) + W[i] = WPA_GET_BE32(buf + (4 * i)); + + /* fill W[16..63] */ + for (i = 16; i < 64; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + + W[i - 16]; + } + + /* Compress */ +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < 64; ++i) { + RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); + t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; + S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; + } + + /* feedback */ + for (i = 0; i < 8; i++) { + md->state[i] = md->state[i] + S[i]; + } + return 0; +} + + +/* Initialize the hash state */ +void _sha256_init(struct _sha256_state *md) +{ + md->curlen = 0; + md->length = 0; + md->state[0] = 0x6A09E667UL; + md->state[1] = 0xBB67AE85UL; + md->state[2] = 0x3C6EF372UL; + md->state[3] = 0xA54FF53AUL; + md->state[4] = 0x510E527FUL; + md->state[5] = 0x9B05688CUL; + md->state[6] = 0x1F83D9ABUL; + md->state[7] = 0x5BE0CD19UL; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +int sha256_process(struct _sha256_state *md, const unsigned char *in, + unsigned long inlen) +{ + unsigned long n; + + if (md->curlen >= sizeof(md->buf)) + return -1; + + while (inlen > 0) { + if (md->curlen == 0 && inlen >= SHA256_BLOCK_SIZE) { + if (sha256_compress(md, (unsigned char *) in) < 0) + return -1; + md->length += SHA256_BLOCK_SIZE * 8; + in += SHA256_BLOCK_SIZE; + inlen -= SHA256_BLOCK_SIZE; + } else { + n = MIN(inlen, (SHA256_BLOCK_SIZE - md->curlen)); + os_memcpy(md->buf + md->curlen, in, n); + md->curlen += n; + in += n; + inlen -= n; + if (md->curlen == SHA256_BLOCK_SIZE) { + if (sha256_compress(md, md->buf) < 0) + return -1; + md->length += 8 * SHA256_BLOCK_SIZE; + md->curlen = 0; + } + } + } + + return 0; +} + + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (32 bytes) + @return CRYPT_OK if successful +*/ +int sha256_done(struct _sha256_state *md, unsigned char *out) +{ + int i; + + if (md->curlen >= sizeof(md->buf)) + return -1; + + /* increase the length of the message */ + md->length += md->curlen * 8; + + /* append the '1' bit */ + md->buf[md->curlen++] = (unsigned char) 0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->curlen > 56) { + while (md->curlen < SHA256_BLOCK_SIZE) { + md->buf[md->curlen++] = (unsigned char) 0; + } + sha256_compress(md, md->buf); + md->curlen = 0; + } + + /* pad up to 56 bytes of zeroes */ + while (md->curlen < 56) { + md->buf[md->curlen++] = (unsigned char) 0; + } + + /* store length */ + WPA_PUT_BE64(md->buf + 56, md->length); + sha256_compress(md, md->buf); + + /* copy output */ + for (i = 0; i < 8; i++) + WPA_PUT_BE32(out + (4 * i), md->state[i]); + + return 0; +} + +/* ===== end - public domain SHA256 implementation ===== */ diff --git a/core/crypto/sha256-prf.c b/core/crypto/sha256-prf.c new file mode 100644 index 0000000..642b38f --- /dev/null +++ b/core/crypto/sha256-prf.c @@ -0,0 +1,109 @@ +/* + * SHA256-based PRF (IEEE 802.11r) + * Copyright (c) 2003-2016, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +//#include "common.h" +#include "sha256.h" +//#include "crypto.h" +#include "wlancrypto_wrap.h" + + +/** + * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2) + * @key: Key for PRF + * @key_len: Length of the key in bytes + * @label: A unique label for each purpose of the PRF + * @data: Extra data to bind into the key + * @data_len: Length of the data + * @buf: Buffer for the generated pseudo-random key + * @buf_len: Number of bytes of key to generate + * Returns: 0 on success, -1 on failure + * + * This function is used to derive new, cryptographically separate keys from a + * given key. + */ +int sha256_prf(const u8 *key, size_t key_len, const char *label, + const u8 *data, size_t data_len, u8 *buf, size_t buf_len) +{ + return sha256_prf_bits(key, key_len, label, data, data_len, buf, + buf_len * 8); +} + + +/** + * sha256_prf_bits - IEEE Std 802.11-2012, 11.6.1.7.2 Key derivation function + * @key: Key for KDF + * @key_len: Length of the key in bytes + * @label: A unique label for each purpose of the PRF + * @data: Extra data to bind into the key + * @data_len: Length of the data + * @buf: Buffer for the generated pseudo-random key + * @buf_len: Number of bits of key to generate + * Returns: 0 on success, -1 on failure + * + * This function is used to derive new, cryptographically separate keys from a + * given key. If the requested buf_len is not divisible by eight, the least + * significant 1-7 bits of the last octet in the output are not part of the + * requested output. + */ +int sha256_prf_bits(const u8 *key, size_t key_len, const char *label, + const u8 *data, size_t data_len, u8 *buf, + size_t buf_len_bits) +{ + u16 counter = 1; + size_t pos, plen; + u8 hash[SHA256_MAC_LEN]; + const u8 *addr[4]; + size_t len[4]; + u8 counter_le[2], length_le[2]; + size_t buf_len = (buf_len_bits + 7) / 8; + + addr[0] = counter_le; + len[0] = 2; + addr[1] = (u8 *) label; + len[1] = os_strlen(label); + addr[2] = data; + len[2] = data_len; + addr[3] = length_le; + len[3] = sizeof(length_le); + + WPA_PUT_LE16(length_le, buf_len_bits); + pos = 0; + while (pos < buf_len) { + plen = buf_len - pos; + WPA_PUT_LE16(counter_le, counter); + if (plen >= SHA256_MAC_LEN) { + if (hmac_sha256_vector(key, key_len, 4, addr, len, + &buf[pos]) < 0) + return -1; + pos += SHA256_MAC_LEN; + } else { + if (hmac_sha256_vector(key, key_len, 4, addr, len, + hash) < 0) + return -1; + os_memcpy(&buf[pos], hash, plen); + pos += plen; + break; + } + counter++; + } + + /* + * Mask out unused bits in the last octet if it does not use all the + * bits. + */ + if (buf_len_bits % 8) { + u8 mask = 0xff << (8 - buf_len_bits % 8); + buf[pos - 1] &= mask; + } + + forced_memzero(hash, sizeof(hash)); + + return 0; +} diff --git a/core/crypto/sha256.c b/core/crypto/sha256.c new file mode 100644 index 0000000..ea5d9e3 --- /dev/null +++ b/core/crypto/sha256.c @@ -0,0 +1,104 @@ +/* + * SHA-256 hash implementation and interface functions + * Copyright (c) 2003-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "sha256.h" +//#include "crypto.h" +#include "wlancrypto_wrap.h" + + +/** + * hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104) + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash (32 bytes) + * Returns: 0 on success, -1 on failure + */ +int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac) +{ + unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */ + unsigned char tk[32]; + const u8 *_addr[6]; + size_t _len[6], i; + + if (num_elem > 5) { + /* + * Fixed limit on the number of fragments to avoid having to + * allocate memory (which could fail). + */ + return -1; + } + + /* if key is longer than 64 bytes reset it to key = SHA256(key) */ + if (key_len > 64) { + if (sha256_vector(1, &key, &key_len, tk) < 0) + return -1; + key = tk; + key_len = 32; + } + + /* the HMAC_SHA256 transform looks like: + * + * SHA256(K XOR opad, SHA256(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected */ + + /* start out by storing key in ipad */ + os_memset(k_pad, 0, sizeof(k_pad)); + os_memcpy(k_pad, key, key_len); + /* XOR key with ipad values */ + for (i = 0; i < 64; i++) + k_pad[i] ^= 0x36; + + /* perform inner SHA256 */ + _addr[0] = k_pad; + _len[0] = 64; + for (i = 0; i < num_elem; i++) { + _addr[i + 1] = addr[i]; + _len[i + 1] = len[i]; + } + if (sha256_vector(1 + num_elem, _addr, _len, mac) < 0) + return -1; + + os_memset(k_pad, 0, sizeof(k_pad)); + os_memcpy(k_pad, key, key_len); + /* XOR key with opad values */ + for (i = 0; i < 64; i++) + k_pad[i] ^= 0x5c; + + /* perform outer SHA256 */ + _addr[0] = k_pad; + _len[0] = 64; + _addr[1] = mac; + _len[1] = SHA256_MAC_LEN; + return sha256_vector(2, _addr, _len, mac); +} + + +/** + * hmac_sha256 - HMAC-SHA256 over data buffer (RFC 2104) + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @data: Pointers to the data area + * @data_len: Length of the data area + * @mac: Buffer for the hash (32 bytes) + * Returns: 0 on success, -1 on failure + */ +int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, + size_t data_len, u8 *mac) +{ + return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac); +} diff --git a/core/crypto/sha256.h b/core/crypto/sha256.h new file mode 100644 index 0000000..5219022 --- /dev/null +++ b/core/crypto/sha256.h @@ -0,0 +1,30 @@ +/* + * SHA256 hash implementation and interface functions + * Copyright (c) 2003-2016, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef SHA256_H +#define SHA256_H + +#define SHA256_MAC_LEN 32 + +int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac); +int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, + size_t data_len, u8 *mac); +int sha256_prf(const u8 *key, size_t key_len, const char *label, + const u8 *data, size_t data_len, u8 *buf, size_t buf_len); +int sha256_prf_bits(const u8 *key, size_t key_len, const char *label, + const u8 *data, size_t data_len, u8 *buf, + size_t buf_len_bits); +void tls_prf_sha256(const u8 *secret, size_t secret_len, + const char *label, const u8 *seed, size_t seed_len, + u8 *out, size_t outlen); +int hmac_sha256_kdf(const u8 *secret, size_t secret_len, + const char *label, const u8 *seed, size_t seed_len, + u8 *out, size_t outlen); + +#endif /* SHA256_H */ diff --git a/core/crypto/sha256_i.h b/core/crypto/sha256_i.h new file mode 100644 index 0000000..11ddd6b --- /dev/null +++ b/core/crypto/sha256_i.h @@ -0,0 +1,25 @@ +/* + * SHA-256 internal definitions + * Copyright (c) 2003-2011, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef SHA256_I_H +#define SHA256_I_H + +#define SHA256_BLOCK_SIZE 64 + +struct _sha256_state { + u64 length; + u32 state[8], curlen; + u8 buf[SHA256_BLOCK_SIZE]; +}; + +void _sha256_init(struct _sha256_state *md); +int sha256_process(struct _sha256_state *md, const unsigned char *in, + unsigned long inlen); +int sha256_done(struct _sha256_state *md, unsigned char *out); + +#endif /* SHA256_I_H */ diff --git a/core/crypto/wlancrypto_wrap.h b/core/crypto/wlancrypto_wrap.h new file mode 100644 index 0000000..b909a43 --- /dev/null +++ b/core/crypto/wlancrypto_wrap.h @@ -0,0 +1,34 @@ +/* + * wlantest - IEEE 802.11 protocol monitoring and testing tool + * Copyright (c) 2010-2013, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef WLANCRYPTO_WRAP_H +#define WLANCRYPTO_WRAP_H + +int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, + u8 *mac); + +u8* ccmp_decrypt(_adapter *padapter, const u8 *tk, const struct ieee80211_hdr *hdr, + const u8 *data, size_t data_len, size_t *decrypted_len); +u8* ccmp_encrypt(_adapter *padapter, const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos, + u8 *pn, int keyid, size_t *encrypted_len); +u8* ccmp_encrypt_pv1(const u8 *tk, const u8 *a1, const u8 *a2, const u8 *a3, + const u8 *frame, size_t len, + size_t hdrlen, const u8 *pn, int keyid, + size_t *encrypted_len); +u8* ccmp_256_decrypt(_adapter *padapter, const u8 *tk, const struct ieee80211_hdr *hdr, + const u8 *data, size_t data_len, size_t *decrypted_len); +u8* ccmp_256_encrypt(_adapter *padapter, const u8 *tk, u8 *frame, size_t len, size_t hdrlen, + u8 *qos, u8 *pn, int keyid, size_t *encrypted_len); + +u8* gcmp_decrypt(_adapter *padapter, const u8 *tk, size_t tk_len, const struct ieee80211_hdr *hdr, + const u8 *data, size_t data_len, size_t *decrypted_len); +u8* gcmp_encrypt(_adapter *padapter, const u8 *tk, size_t tk_len, const u8 *frame, size_t len, + size_t hdrlen, const u8 *qos, + const u8 *pn, int keyid, size_t *encrypted_len); + +#endif /* WLANCRYPTO_WRAP_H */ diff --git a/core/efuse/rtw_efuse.c b/core/efuse/rtw_efuse.c index a97abc2..ff699f0 100644 --- a/core/efuse/rtw_efuse.c +++ b/core/efuse/rtw_efuse.c @@ -56,6 +56,7 @@ BOOLEAN rtw_file_efuse_IsMasked(PADAPTER pAdapter, u16 Offset, u8 *maskbuf) return (result > 0) ? 0 : 1; } + BOOLEAN efuse_IsBT_Masked(PADAPTER pAdapter, u16 Offset) { PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter); @@ -64,6 +65,7 @@ BOOLEAN efuse_IsBT_Masked(PADAPTER pAdapter, u16 Offset) return FALSE; #ifdef CONFIG_BT_EFUSE_MASK +#ifdef CONFIG_RTL8822C #ifdef CONFIG_USB_HCI if (IS_HARDWARE_TYPE_8822C(pAdapter)) return (IS_BT_MASKED(8822C, _MUSB, Offset)) ? TRUE : FALSE; @@ -76,6 +78,17 @@ BOOLEAN efuse_IsBT_Masked(PADAPTER pAdapter, u16 Offset) if (IS_HARDWARE_TYPE_8822C(pAdapter)) return (IS_BT_MASKED(8822C, _MSDIO, Offset)) ? TRUE : FALSE; #endif +#endif /*#ifdef CONFIG_RTL8822C*/ +#ifdef CONFIG_RTL8723F +#ifdef CONFIG_USB_HCI + if (IS_HARDWARE_TYPE_8723F(pAdapter)) + return (IS_BT_MASKED(8723F, _MUSB, Offset)) ? TRUE : FALSE; +#endif +#ifdef CONFIG_SDIO_HCI + if (IS_HARDWARE_TYPE_8723F(pAdapter)) + return (IS_BT_MASKED(8723F, _MSDIO, Offset)) ? TRUE : FALSE; +#endif +#endif /*#ifdef CONFIG_RTL8723F*/ #endif /* CONFIG_BT_EFUSE_MASK */ return FALSE; } @@ -85,18 +98,30 @@ void rtw_bt_efuse_mask_array(PADAPTER pAdapter, u8 *pArray) PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter); #ifdef CONFIG_BT_EFUSE_MASK +#ifdef CONFIG_RTL8822C #ifdef CONFIG_USB_HCI if (IS_HARDWARE_TYPE_8822CU(pAdapter)) - GET_MASK_ARRAY(8822C, _MUSB, pArray); + GET_BT_MASK_ARRAY(8822C, _MUSB, pArray); #endif #ifdef CONFIG_PCI_HCI if (IS_HARDWARE_TYPE_8822CE(pAdapter)) - GET_MASK_ARRAY(8822C, _MPCIE, pArray); + GET_BT_MASK_ARRAY(8822C, _MPCIE, pArray); #endif #ifdef CONFIG_SDIO_HCI if (IS_HARDWARE_TYPE_8822CS(pAdapter)) - GET_MASK_ARRAY(8822C, _MSDIO, pArray); + GET_BT_MASK_ARRAY(8822C, _MSDIO, pArray); #endif +#endif /*#ifdef CONFIG_RTL8822C*/ +#ifdef CONFIG_RTL8723F +#ifdef CONFIG_USB_HCI + if (IS_HARDWARE_TYPE_8723FU(pAdapter)) + GET_BT_MASK_ARRAY(8723F, _MUSB, pArray); +#endif +#ifdef CONFIG_SDIO_HCI + if (IS_HARDWARE_TYPE_8723FS(pAdapter)) + GET_BT_MASK_ARRAY(8723F, _MSDIO, pArray); +#endif +#endif /*#ifdef CONFIG_RTL8723F*/ #endif /* CONFIG_BT_EFUSE_MASK */ } @@ -106,6 +131,7 @@ u16 rtw_get_bt_efuse_mask_arraylen(PADAPTER pAdapter) HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); #ifdef CONFIG_BT_EFUSE_MASK +#ifdef CONFIG_RTL8822C #ifdef CONFIG_USB_HCI if (IS_HARDWARE_TYPE_8822CU(pAdapter)) return GET_BT_MASK_ARRAY_LEN(8822C, _MUSB); @@ -118,6 +144,17 @@ u16 rtw_get_bt_efuse_mask_arraylen(PADAPTER pAdapter) if (IS_HARDWARE_TYPE_8822CS(pAdapter)) return GET_BT_MASK_ARRAY_LEN(8822C, _MSDIO); #endif +#endif /*#ifdef CONFIG_RTL8822C*/ +#ifdef CONFIG_RTL8723F +#ifdef CONFIG_USB_HCI + if (IS_HARDWARE_TYPE_8723FU(pAdapter)) + return GET_BT_MASK_ARRAY_LEN(8723F, _MUSB); +#endif +#ifdef CONFIG_SDIO_HCI + if (IS_HARDWARE_TYPE_8723FS(pAdapter)) + return GET_BT_MASK_ARRAY_LEN(8723F, _MSDIO); +#endif +#endif /*CONFIG_RTL8723F*/ #endif /* CONFIG_BT_EFUSE_MASK */ return 0; @@ -199,6 +236,10 @@ BOOLEAN efuse_IsMasked(PADAPTER pAdapter, u16 Offset) if (IS_HARDWARE_TYPE_8814B(pAdapter)) return (IS_MASKED(8814B, _MUSB, Offset)) ? TRUE : FALSE; #endif +#if defined(CONFIG_RTL8723F) + if (IS_HARDWARE_TYPE_8723F(pAdapter)) + return (IS_MASKED(8723F, _MUSB, Offset)) ? TRUE : FALSE; +#endif #endif /*CONFIG_USB_HCI*/ #ifdef CONFIG_PCI_HCI @@ -290,6 +331,10 @@ BOOLEAN efuse_IsMasked(PADAPTER pAdapter, u16 Offset) if (IS_HARDWARE_TYPE_8822C(pAdapter)) return (IS_MASKED(8822C, _MSDIO, Offset)) ? TRUE : FALSE; #endif +#if defined(CONFIG_RTL8723F) + if (IS_HARDWARE_TYPE_8723F(pAdapter)) + return (IS_MASKED(8723F, _MSDIO, Offset)) ? TRUE : FALSE; +#endif #endif /*CONFIG_SDIO_HCI*/ return FALSE; @@ -355,6 +400,10 @@ void rtw_efuse_mask_array(PADAPTER pAdapter, u8 *pArray) if (IS_HARDWARE_TYPE_8814B(pAdapter)) GET_MASK_ARRAY(8814B, _MUSB, pArray); #endif +#if defined(CONFIG_RTL8723F) + if (IS_HARDWARE_TYPE_8723F(pAdapter)) + GET_MASK_ARRAY(8723F, _MUSB, pArray); +#endif #endif /*CONFIG_USB_HCI*/ #ifdef CONFIG_PCI_HCI @@ -445,6 +494,10 @@ void rtw_efuse_mask_array(PADAPTER pAdapter, u8 *pArray) if (IS_HARDWARE_TYPE_8822C(pAdapter)) GET_MASK_ARRAY(8822C , _MSDIO, pArray); #endif +#if defined(CONFIG_RTL8723F) + if (IS_HARDWARE_TYPE_8723F(pAdapter)) + GET_MASK_ARRAY(8723F, _MSDIO, pArray); +#endif #endif /*CONFIG_SDIO_HCI*/ } @@ -509,6 +562,10 @@ u16 rtw_get_efuse_mask_arraylen(PADAPTER pAdapter) return GET_MASK_ARRAY_LEN(8814B, _MUSB); } #endif +#if defined(CONFIG_RTL8723F) + if (IS_HARDWARE_TYPE_8723F(pAdapter)) + return GET_MASK_ARRAY_LEN(8723F, _MUSB); +#endif #endif /*CONFIG_USB_HCI*/ #ifdef CONFIG_PCI_HCI @@ -599,6 +656,10 @@ u16 rtw_get_efuse_mask_arraylen(PADAPTER pAdapter) if (IS_HARDWARE_TYPE_8822C(pAdapter)) return GET_MASK_ARRAY_LEN(8822C, _MSDIO); #endif +#if defined(CONFIG_RTL8723F) + if (IS_HARDWARE_TYPE_8723F(pAdapter)) + return GET_MASK_ARRAY_LEN(8723F, _MSDIO); +#endif #endif/*CONFIG_SDIO_HCI*/ return 0; } @@ -716,6 +777,11 @@ void rtw_efuse_analyze(PADAPTER padapter, u8 Type, u8 Fake) eFuseWord = rtw_zmalloc(EFUSE_MAX_SECTION_NUM * (EFUSE_MAX_WORD_UNIT * 2)); + if (eFuseWord == NULL) { + RTW_INFO("%s:rtw_zmalloc eFuseWord = NULL !!\n", __func__); + return; + } + RTW_INFO("\n"); if (Type == 0) { if (Fake == 0) { @@ -1032,7 +1098,7 @@ u8 efuse_bt_GetCurrentSize(PADAPTER adapter, u16 *usesize) u16 efuse_bt_GetMaxSize(PADAPTER adapter) { - return EFUSE_BT_REAL_CONTENT_LEN; + return EFUSE_BT_REAL_CONTENT_LEN - EFUSE_PROTECT_BYTES_BANK; } void EFUSE_GetEfuseDefinition(PADAPTER adapter, u8 efusetype, u8 type, void *out, BOOLEAN test) @@ -1237,6 +1303,7 @@ exit: return status; } + u8 rtw_efuse_map_write(PADAPTER adapter, u16 addr, u16 cnts, u8 *data) { struct dvobj_priv *d; @@ -1323,22 +1390,23 @@ static void rtw_bt_mask_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data { u16 i = 0; +#ifdef CONFIG_BT_EFUSE_MASK if (padapter->registrypriv.boffefusemask == 0) { for (i = 0; i < cnts; i++) { if (padapter->registrypriv.bBTFileMaskEfuse == _TRUE) { if (rtw_file_efuse_IsMasked(padapter, addr + i, btmaskfileBuffer)) /*use BT file efuse mask.*/ data[i] = 0xff; else - RTW_DBG("data[%x] = %x\n", i, data[i]); + RTW_INFO("data[%x] = %x\n", i, data[i]); } else { if (efuse_IsBT_Masked(padapter, addr + i)) /*use drv internal efuse mask.*/ data[i] = 0xff; else - RTW_DBG("data[%x] = %x\n", i, data[i]); + RTW_INFO("data[%x] = %x\n", i, data[i]); } } } - +#endif /*CONFIG_BT_EFUSE_MASK*/ } u8 rtw_BT_efuse_map_read(PADAPTER adapter, u16 addr, u16 cnts, u8 *data) @@ -1350,6 +1418,7 @@ u8 rtw_BT_efuse_map_read(PADAPTER adapter, u16 addr, u16 cnts, u8 *data) return _SUCCESS; } + static u16 hal_EfuseGetCurrentSize_BT( PADAPTER padapter, @@ -1435,6 +1504,28 @@ hal_EfuseGetCurrentSize_BT( return retU2; } +#ifdef CONFIG_RTL8822C +void rtw_pre_bt_efuse(PADAPTER padapter) +{ + char pgdata[4] = {0x72, 0x80, 0x14, 0x90}; /*BT 5M PLL*/ + u8 status = 1; + u8 bkmask; + BOOLEAN bt_en; + + bkmask = padapter->registrypriv.boffefusemask; + padapter->registrypriv.boffefusemask = 1; + + bt_en = rtw_read8(padapter, 0x6A) & BIT2 ? _TRUE : _FALSE; + if (IS_HARDWARE_TYPE_8822C(padapter) && bt_en == _TRUE) { + status = rtw_BT_efuse_map_write(padapter, 0x1f8, 4, pgdata); + RTW_INFO("%s done!!!\n", __FUNCTION__); + } + if (status == _FAIL) + RTW_INFO("%s: fail\n", __FUNCTION__); + padapter->registrypriv.boffefusemask = bkmask; +} +#endif + u8 rtw_BT_efuse_map_write(PADAPTER adapter, u16 addr, u16 cnts, u8 *data) { #define RT_ASSERT_RET(expr) \ @@ -1477,10 +1568,10 @@ u8 rtw_BT_efuse_map_write(PADAPTER adapter, u16 addr, u16 cnts, u8 *data) _rtw_memcpy(efuse , map, mapLen); _rtw_memcpy(efuse + addr, data, cnts); - +#ifdef CONFIG_BT_EFUSE_MASK if (adapter->registrypriv.boffefusemask == 0) { for (i = 0; i < cnts; i++) { - if (adapter->registrypriv.bFileMaskEfuse == _TRUE) { + if (adapter->registrypriv.bBTFileMaskEfuse == _TRUE) { if (rtw_file_efuse_IsMasked(adapter, addr + i, btmaskfileBuffer)) /*use file efuse mask. */ efuse[addr + i] = map[addr + i]; } else { @@ -1490,6 +1581,7 @@ u8 rtw_BT_efuse_map_write(PADAPTER adapter, u16 addr, u16 cnts, u8 *data) RTW_INFO("%s , efuse[%x] = %x, map = %x\n", __func__, addr + i, efuse[ addr + i], map[addr + i]); } } +#endif /*CONFIG_BT_EFUSE_MASK*/ /* precheck pg efuse data byte*/ chk_total_byte = 0; idx = 0; @@ -1533,9 +1625,9 @@ u8 rtw_BT_efuse_map_write(PADAPTER adapter, u16 addr, u16 cnts, u8 *data) j = (addr + idx) & 0x7; _rtw_memcpy(newdata, &map[offset << 3], PGPKT_DATA_SIZE); for (i = j; i < PGPKT_DATA_SIZE && idx < cnts; i++, idx++) { - if (efuse[idx] != map[addr + idx]) { + if (efuse[addr + idx] != map[addr + idx]) { word_en &= ~BIT(i >> 1); - newdata[i] = efuse[idx]; + newdata[i] = efuse[addr + idx]; } } @@ -1553,7 +1645,10 @@ u8 rtw_BT_efuse_map_write(PADAPTER adapter, u16 addr, u16 cnts, u8 *data) offset++; } exit: - rtw_mfree(map, mapLen); + if (efuse) + rtw_mfree(efuse, mapLen); + if (map) + rtw_mfree(map, mapLen); return ret; } @@ -3267,7 +3362,7 @@ int retriveAdaptorInfoFile(char *path, u8 *efuse_data) } #endif /* CONFIG_ADAPTOR_INFO_CACHING_FILE */ -u8 rtw_efuse_file_read(PADAPTER padapter, u8 *filepatch, u8 *buf, u32 len) +u8 rtw_efuse_file_read(PADAPTER padapter, u8 *filepath, u8 *buf, u32 len) { char *ptmpbuf = NULL, *ptr; u8 val8; @@ -3279,27 +3374,24 @@ u8 rtw_efuse_file_read(PADAPTER padapter, u8 *filepatch, u8 *buf, u32 len) if (ptmpbuf == NULL) return _FALSE; - count = rtw_retrieve_from_file(filepatch, ptmpbuf, bufsize); + count = rtw_retrieve_from_file(filepath, ptmpbuf, bufsize); if (count <= 90) { rtw_mfree(ptmpbuf, bufsize); - RTW_ERR("%s, filepatch %s, size=%d, FAIL!!\n", __FUNCTION__, filepatch, count); + RTW_ERR("%s, filepatch %s, size=%d, FAIL!!\n", __FUNCTION__, filepath, count); return _FALSE; } - i = 0; j = 0; ptr = ptmpbuf; while ((j < len) && (i < count)) { if (ptmpbuf[i] == '\0') break; - ptr = strpbrk(&ptmpbuf[i], " \t\n\r"); if (ptr) { if (ptr == &ptmpbuf[i]) { i++; continue; } - /* Add string terminating null */ *ptr = 0; } else { @@ -3314,15 +3406,50 @@ u8 rtw_efuse_file_read(PADAPTER padapter, u8 *filepatch, u8 *buf, u32 len) RTW_DBG("i=%d, j=%d, 0x%02x\n", i, j, buf[j]); j++; } - i = ptr - ptmpbuf + 1; } - rtw_mfree(ptmpbuf, bufsize); - RTW_INFO("%s, filepatch %s, size=%d, done\n", __FUNCTION__, filepatch, count); + RTW_INFO("%s, filepatch %s, size=%d, done\n", __FUNCTION__, filepath, count); return _TRUE; } + +u8 rtw_efuse_file_store(PADAPTER padapter, u8 *filepath, u8 *buf, u32 len) +{ + int err = 0, i = 0, j = 0, mapLen = 0 ; + char *cbuf, *pchr; + + cbuf = rtw_zmalloc(len * 3); + pchr = cbuf; + + if (filepath && buf) { + if (cbuf == NULL) { + RTW_INFO("%s, malloc cbuf _FAIL\n", __FUNCTION__); + err = _FAIL; + } else { + for (i = 0; i <= len; i += 16) { + for (j = 0; j < 16; j++) + pchr += sprintf(pchr, "%02X ", buf[i + j]); + pchr += sprintf(pchr, "\n"); + } + + err = rtw_store_to_file(filepath, cbuf, strlen(cbuf)); + RTW_INFO("%s, rtw_store_to_file len=%d,err =%d, len(cbuf)=%zd\n", __FUNCTION__, len, err, strlen(cbuf)); + if (err == strlen(cbuf)) { + err = _SUCCESS; + RTW_INFO("%s, filepatch %s, len=%d, done\n", __FUNCTION__, filepath, len); + } else { + err = _FAIL; + RTW_INFO("%s, filepatch %s, len=%d,err =%d, _FAIL\n", __FUNCTION__, filepath, len, err); + } + } + } + if (cbuf) + rtw_mfree(cbuf, len * 3); + + return err; +} + #ifdef CONFIG_EFUSE_CONFIG_FILE u32 rtw_read_efuse_from_file(const char *path, u8 *buf, int map_size) { diff --git a/core/mesh/rtw_mesh.c b/core/mesh/rtw_mesh.c index 4842206..25c17cf 100644 --- a/core/mesh/rtw_mesh.c +++ b/core/mesh/rtw_mesh.c @@ -143,7 +143,7 @@ exit: return ret; } -int rtw_bss_is_same_mbss(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b) +int _rtw_bss_is_same_mbss(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b, u8 **a_mconf_ie_r, u8 **b_mconf_ie_r) { int ret = 0; u8 *a_mconf_ie, *b_mconf_ie; @@ -154,11 +154,16 @@ int rtw_bss_is_same_mbss(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b) a_mconf_ie = rtw_get_ie(BSS_EX_TLV_IES(a), WLAN_EID_MESH_CONFIG, &a_mconf_ie_len, BSS_EX_TLV_IES_LEN(a)); if (!a_mconf_ie || a_mconf_ie_len != 7) goto exit; + if (a_mconf_ie_r) + *a_mconf_ie_r = a_mconf_ie; + if (b->InfrastructureMode != Ndis802_11_mesh) goto exit; b_mconf_ie = rtw_get_ie(BSS_EX_TLV_IES(b), WLAN_EID_MESH_CONFIG, &b_mconf_ie_len, BSS_EX_TLV_IES_LEN(b)); if (!b_mconf_ie || b_mconf_ie_len != 7) goto exit; + if (b_mconf_ie_r) + *b_mconf_ie_r = b_mconf_ie; if (a->mesh_id.SsidLength != b->mesh_id.SsidLength || _rtw_memcmp(a->mesh_id.Ssid, b->mesh_id.Ssid, a->mesh_id.SsidLength) == _FALSE) @@ -173,25 +178,28 @@ exit: return ret; } -int rtw_bss_is_candidate_mesh_peer(WLAN_BSSID_EX *self, WLAN_BSSID_EX *target, u8 ch, u8 add_peer) +int rtw_bss_is_same_mbss(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b) +{ + return _rtw_bss_is_same_mbss(a, b, NULL, NULL); +} + +int rtw_bss_is_candidate_mesh_peer(_adapter *adapter, WLAN_BSSID_EX *target, u8 ch, u8 add_peer) { int ret = 0; - u8 *mconf_ie; - sint mconf_ie_len; + WLAN_BSSID_EX *self = &adapter->mlmepriv.cur_network.network; + u8 *s_mconf_ie, *t_mconf_ie; + u8 auth_pid; int i, j; - if (!rtw_bss_is_same_mbss(self, target)) - goto exit; - if (ch && self->Configuration.DSConfig != target->Configuration.DSConfig) goto exit; + if (!_rtw_bss_is_same_mbss(self, target, &s_mconf_ie, &t_mconf_ie)) + goto exit; + if (add_peer) { /* Accept additional mesh peerings */ - mconf_ie = rtw_get_ie(BSS_EX_TLV_IES(target), WLAN_EID_MESH_CONFIG, &mconf_ie_len, BSS_EX_TLV_IES_LEN(target)); - if (!mconf_ie || mconf_ie_len != 7) - goto exit; - if (GET_MESH_CONF_ELE_ACCEPT_PEERINGS(mconf_ie + 2) == 0) + if (GET_MESH_CONF_ELE_ACCEPT_PEERINGS(t_mconf_ie + 2) == 0) goto exit; } @@ -223,10 +231,38 @@ int rtw_bss_is_candidate_mesh_peer(WLAN_BSSID_EX *self, WLAN_BSSID_EX *target, u } } - /* BSSBasicMCSSet */ - /* 802.1X connected to AS ? */ + + auth_pid = GET_MESH_CONF_ELE_AUTH_PROTO_ID(s_mconf_ie + 2); + if (auth_pid && auth_pid <= 2) { + struct security_priv *sec = &adapter->securitypriv; + u8 *rsn_ie; + int rsn_ie_len; + int group_cipher = 0, pairwise_cipher = 0, gmcs = 0; + u8 mfp_opt = MFP_NO; + + /* 802.1X connected to AS ? */ + + /* RSN */ + rsn_ie = rtw_get_wpa2_ie(BSS_EX_TLV_IES(target), &rsn_ie_len, BSS_EX_TLV_IES_LEN(target)); + if (!rsn_ie || rsn_ie_len == 0) + goto exit; + if (rtw_parse_wpa2_ie(rsn_ie, rsn_ie_len + 2, &group_cipher, &pairwise_cipher, &gmcs, NULL, &mfp_opt, NULL) != _SUCCESS) + goto exit; + if ((sec->mfp_opt == MFP_REQUIRED && mfp_opt < MFP_OPTIONAL) + || (mfp_opt == MFP_REQUIRED && sec->mfp_opt < MFP_OPTIONAL)) + goto exit; + if (!(sec->wpa2_group_cipher & group_cipher)) + goto exit; + if (!(sec->wpa2_pairwise_cipher & pairwise_cipher)) + goto exit; + #ifdef CONFIG_IEEE80211W + if ((sec->mfp_opt >= MFP_OPTIONAL && mfp_opt >= MFP_OPTIONAL) + && security_type_bip_to_gmcs(sec->dot11wCipher) != gmcs) + goto exit; + #endif + } ret = 1; @@ -339,7 +375,7 @@ static bool rtw_mesh_acnode_candidate_exist(_adapter *adapter) #if CONFIG_RTW_MACADDR_ACL && rtw_access_ctrl(adapter, scanned->network.MacAddress) == _TRUE #endif - && rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &scanned->network, 1, 1) + && rtw_bss_is_candidate_mesh_peer(adapter, &scanned->network, 1, 1) #if CONFIG_RTW_MESH_PEER_BLACKLIST && !rtw_mesh_peer_blacklist_search(adapter, scanned->network.MacAddress) #endif @@ -679,7 +715,7 @@ void rtw_chk_candidate_peer_notify(_adapter *adapter, struct wlan_network *scann if (rtw_get_passing_time_ms(scanned->last_scanned) >= mcfg->peer_sel_policy.scanr_exp_ms || (mcfg->rssi_threshold && mcfg->rssi_threshold > scanned->network.Rssi) - || !rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &scanned->network, 1, 1) + || !rtw_bss_is_candidate_mesh_peer(adapter, &scanned->network, 1, 1) #if CONFIG_RTW_MACADDR_ACL || rtw_access_ctrl(adapter, scanned->network.MacAddress) == _FALSE #endif @@ -760,7 +796,7 @@ void rtw_mesh_peer_status_chk(_adapter *adapter) flush = 0; /* remove unsuitable peer */ - if (!rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &plink->scanned->network, 1, 0) + if (!rtw_bss_is_candidate_mesh_peer(adapter, &plink->scanned->network, 1, 0) #if CONFIG_RTW_MACADDR_ACL || rtw_access_ctrl(adapter, plink->addr) == _FALSE #endif @@ -809,6 +845,10 @@ flush_add: if (flush) { rtw_list_delete(&sta->asoc_list); stapriv->asoc_list_cnt--; +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (sta->tbtx_enable) + stapriv->tbtx_asoc_list_cnt--; +#endif STA_SET_MESH_PLINK(sta, NULL); stainfo_offset = rtw_stainfo_offset(stapriv, sta); @@ -828,7 +868,7 @@ flush_add: continue; /* remove unsuitable peer */ - if (!rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &plink->scanned->network, 1, 1) + if (!rtw_bss_is_candidate_mesh_peer(adapter, &plink->scanned->network, 1, 1) #if CONFIG_RTW_MACADDR_ACL || rtw_access_ctrl(adapter, plink->addr) == _FALSE #endif @@ -901,7 +941,7 @@ static u8 rtw_mesh_offch_cto_mgate_required(_adapter *adapter) #if CONFIG_RTW_MACADDR_ACL && rtw_access_ctrl(adapter, scanned->network.MacAddress) == _TRUE #endif - && rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &scanned->network, 1, 1) + && rtw_bss_is_candidate_mesh_peer(adapter, &scanned->network, 1, 1) && rtw_bss_is_cto_mgate(&scanned->network) #if CONFIG_RTW_MESH_PEER_BLACKLIST && !rtw_mesh_peer_blacklist_search(adapter, scanned->network.MacAddress) @@ -988,7 +1028,7 @@ u8 rtw_mesh_select_operating_ch(_adapter *adapter) #if CONFIG_RTW_MACADDR_ACL && rtw_access_ctrl(adapter, scanned->network.MacAddress) == _TRUE #endif - && rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &scanned->network, 0, 0) + && rtw_bss_is_candidate_mesh_peer(adapter, &scanned->network, 0, 0) #if CONFIG_RTW_MESH_PEER_BLACKLIST && !rtw_mesh_peer_blacklist_search(adapter, scanned->network.MacAddress) #endif @@ -999,7 +1039,7 @@ u8 rtw_mesh_select_operating_ch(_adapter *adapter) int ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, scanned->network.Configuration.DSConfig); if (ch_set_idx >= 0 - && rfctl->channel_set[ch_set_idx].ScanType != SCAN_PASSIVE + && !(rfctl->channel_set[ch_set_idx].flags & RTW_CHF_NO_IR) && !CH_IS_NON_OCP(&rfctl->channel_set[ch_set_idx]) ) { u8 nop, accept; @@ -1074,6 +1114,11 @@ void dump_mesh_networks(void *sel, _adapter *adapter) #endif u8 *mesh_conf_ie; sint mesh_conf_ie_len; + u8 auth_pid; + u8 *rsn_ie; + int rsn_ie_len; + int gcs, pcs, gmcs; + u8 mfp_opt; struct wlan_network **mesh_networks; u8 mesh_network_cnt = 0; int i; @@ -1103,13 +1148,54 @@ void dump_mesh_networks(void *sel, _adapter *adapter) exit_critical_bh(&queue->lock); - RTW_PRINT_SEL(sel, " %-17s %-3s %-4s %-5s %-32s %-3s %-3s %-3s" + RTW_PRINT_SEL(sel, " %-17s %-3s %-4s %-5s %-32s %-10s" + " %-3s %-3s %-4s" + " %-3s %-3s %-3s" NSTATE_TITLE_FMT_ACN "\n" - , "bssid", "ch", "rssi", "age", "mesh_id", "nop", "fwd", "cto" + , "bssid", "ch", "rssi", "age", "mesh_id", "P M C S A " + , "pcs", "gcs", "gmcs" + , "nop", "fwd", "cto" NSTATE_TITLE_ARG_ACN ); + if (MLME_IS_MESH(adapter) && MLME_IS_ASOC(adapter)) { + network = &mlme->cur_network; + mesh_conf_ie = rtw_get_ie(BSS_EX_TLV_IES(&network->network), WLAN_EID_MESH_CONFIG + , &mesh_conf_ie_len, BSS_EX_TLV_IES_LEN(&network->network)); + if (mesh_conf_ie && mesh_conf_ie_len == 7) { + gcs = pcs = gmcs = 0; + mfp_opt = MFP_NO; + auth_pid = GET_MESH_CONF_ELE_AUTH_PROTO_ID(mesh_conf_ie + 2); + if (auth_pid && auth_pid <= 2) { + rsn_ie = rtw_get_wpa2_ie(BSS_EX_TLV_IES(&network->network) + , &rsn_ie_len, BSS_EX_TLV_IES_LEN(&network->network)); + if (rsn_ie && rsn_ie_len) + rtw_parse_wpa2_ie(rsn_ie, rsn_ie_len + 2, &gcs, &pcs, &gmcs, NULL, &mfp_opt, NULL); + } + RTW_PRINT_SEL(sel, "* "MAC_FMT" %3d %-32s %2x%2x%2x%2x%2x" + " %03x %03x %c%03x" + " %c%2u %3u %c%c " + "\n" + , MAC_ARG(network->network.MacAddress) + , network->network.Configuration.DSConfig + , network->network.mesh_id.Ssid + , GET_MESH_CONF_ELE_PATH_SEL_PROTO_ID(mesh_conf_ie + 2) + , GET_MESH_CONF_ELE_PATH_SEL_METRIC_ID(mesh_conf_ie + 2) + , GET_MESH_CONF_ELE_CONGEST_CTRL_MODE_ID(mesh_conf_ie + 2) + , GET_MESH_CONF_ELE_SYNC_METHOD_ID(mesh_conf_ie + 2) + , auth_pid + , pcs, gcs, mfp_opt == MFP_REQUIRED ? 'R' : (mfp_opt == MFP_OPTIONAL ? 'C' : ' ') + , mfp_opt >= MFP_OPTIONAL ? gmcs : 0 + , GET_MESH_CONF_ELE_ACCEPT_PEERINGS(mesh_conf_ie + 2) ? '+' : ' ' + , GET_MESH_CONF_ELE_NUM_OF_PEERINGS(mesh_conf_ie + 2) + , GET_MESH_CONF_ELE_FORWARDING(mesh_conf_ie + 2) + , GET_MESH_CONF_ELE_CTO_MGATE(mesh_conf_ie + 2) ? 'G' : ' ' + , GET_MESH_CONF_ELE_CTO_AS(mesh_conf_ie + 2) ? 'A' : ' ' + ); + } + } + for (i = 0; i < mesh_network_cnt; i++) { network = mesh_networks[i]; @@ -1121,6 +1207,14 @@ void dump_mesh_networks(void *sel, _adapter *adapter) if (!mesh_conf_ie || mesh_conf_ie_len != 7) continue; + gcs = pcs = gmcs = 0; + mfp_opt = MFP_NO; + auth_pid = GET_MESH_CONF_ELE_AUTH_PROTO_ID(mesh_conf_ie + 2); + if (auth_pid && auth_pid <= 2) { + rsn_ie = rtw_get_wpa2_ie(BSS_EX_TLV_IES(&network->network), &rsn_ie_len, BSS_EX_TLV_IES_LEN(&network->network)); + if (rsn_ie && rsn_ie_len) + rtw_parse_wpa2_ie(rsn_ie, rsn_ie_len + 2, &gcs, &pcs, &gmcs, NULL, &mfp_opt, NULL); + } age_ms = rtw_get_passing_time_ms(network->last_scanned); #if CONFIG_RTW_MESH_ACNODE_PREVENT if (network->acnode_stime == 0) @@ -1142,13 +1236,15 @@ void dump_mesh_networks(void *sel, _adapter *adapter) blocked = 1; else if (plink) ; - else if (rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &network->network, 0, 1)) + else if (rtw_bss_is_candidate_mesh_peer(adapter, &network->network, 0, 1)) candidate = 1; else if (rtw_bss_is_same_mbss(&mlme->cur_network.network, &network->network)) same_mbss = 1; } - RTW_PRINT_SEL(sel, "%c "MAC_FMT" %3d %4ld %5d %-32s %c%2u %3u %c%c " + RTW_PRINT_SEL(sel, "%c "MAC_FMT" %3d %4ld %5d %-32s %2x%2x%2x%2x%2x" + " %03x %03x %c%03x" + " %c%2u %3u %c%c " NSTATE_VALUE_FMT_ACN "\n" , established ? 'E' : (blocked ? 'B' : (plink ? 'N' : (candidate ? 'C' : (same_mbss ? 'S' : ' ')))) @@ -1157,6 +1253,13 @@ void dump_mesh_networks(void *sel, _adapter *adapter) , network->network.Rssi , age_ms < 99999 ? age_ms : 99999 , network->network.mesh_id.Ssid + , GET_MESH_CONF_ELE_PATH_SEL_PROTO_ID(mesh_conf_ie + 2) + , GET_MESH_CONF_ELE_PATH_SEL_METRIC_ID(mesh_conf_ie + 2) + , GET_MESH_CONF_ELE_CONGEST_CTRL_MODE_ID(mesh_conf_ie + 2) + , GET_MESH_CONF_ELE_SYNC_METHOD_ID(mesh_conf_ie + 2) + , auth_pid + , pcs, gcs, mfp_opt == MFP_REQUIRED ? 'R' : (mfp_opt == MFP_OPTIONAL ? 'C' : ' ') + , mfp_opt >= MFP_OPTIONAL ? gmcs : 0 , GET_MESH_CONF_ELE_ACCEPT_PEERINGS(mesh_conf_ie + 2) ? '+' : ' ' , GET_MESH_CONF_ELE_NUM_OF_PEERINGS(mesh_conf_ie + 2) , GET_MESH_CONF_ELE_FORWARDING(mesh_conf_ie + 2) @@ -1205,7 +1308,7 @@ static int rtw_mpm_ampe_dec(_adapter *adapter, struct mesh_plink_ent *plink _rtw_memcpy(iv_crypt, mic_ie + 2, iv_crypt_len); - verify_ret = aes_siv_decrypt(plink->aek, iv_crypt, iv_crypt_len + verify_ret = rtw_aes_siv_decrypt(plink->aek, 32, iv_crypt, iv_crypt_len , 3, aad, aad_len, ampe_buf); rtw_mfree(iv_crypt, iv_crypt_len); @@ -1216,7 +1319,7 @@ static int rtw_mpm_ampe_dec(_adapter *adapter, struct mesh_plink_ent *plink } else if (*ampe_buf != WLAN_EID_AMPE) { RTW_WARN("plaintext is not AMPE IE\n"); goto exit; - } else if (AES_BLOCK_SIZE + 2 + *(ampe_buf + 1) > iv_crypt_len) { + } else if ( 16 /* AES_BLOCK_SIZE*/ + 2 + *(ampe_buf + 1) > iv_crypt_len) { RTW_WARN("plaintext AMPE IE length is not valid\n"); goto exit; } @@ -1251,7 +1354,7 @@ static int rtw_mpm_ampe_enc(_adapter *adapter, struct mesh_plink_ent *plink _rtw_memcpy(ampe_ie, ampe_buf, ampe_ie_len); - protect_ret = aes_siv_encrypt(plink->aek, ampe_ie, ampe_ie_len + protect_ret = rtw_aes_siv_encrypt(plink->aek, 32, ampe_ie, ampe_ie_len , 3, aad, aad_len, mic_ie + 2); rtw_mfree(ampe_ie, ampe_ie_len); @@ -1296,7 +1399,7 @@ static int rtw_mpm_tx_ies_sync_bss(_adapter *adapter, struct mesh_plink_ent *pli /* decode */ if (mic_ie) { - ampe_buf_len = flen - (mic_ie + 2 + AES_BLOCK_SIZE - fhead); + ampe_buf_len = flen - (mic_ie + 2 + 16 /* AES_BLOCK_SIZE */ - fhead); ampe_buf = rtw_malloc(ampe_buf_len); if (!ampe_buf) goto exit; @@ -1340,7 +1443,7 @@ static int rtw_mpm_tx_ies_sync_bss(_adapter *adapter, struct mesh_plink_ent *pli } new_len += mpm_ielen + 2; if (mic_ie) - new_len += AES_BLOCK_SIZE + 2 + ampe_buf_len; + new_len += 16 /* AES_BLOCK_SIZE*/ + 2 + ampe_buf_len; /* alloc new frame */ new_buf = rtw_malloc(new_len); @@ -1385,7 +1488,7 @@ static int rtw_mpm_tx_ies_sync_bss(_adapter *adapter, struct mesh_plink_ent *pli if (mic_ie) { new_mic_ie = fpos; *fpos++ = WLAN_EID_MIC; - *fpos++ = AES_BLOCK_SIZE; + *fpos++ = 16 /* AES_BLOCK_SIZE */; } #ifdef CONFIG_RTW_MESH_AEK @@ -1585,7 +1688,7 @@ static int rtw_mpm_check_frames(_adapter *adapter, u8 action, const u8 **buf, si mic_ie = rtw_get_ie(fhead + sizeof(struct rtw_ieee80211_hdr_3addr) + tlv_ies_offset , WLAN_EID_MIC, &mic_ielen , flen - sizeof(struct rtw_ieee80211_hdr_3addr) - tlv_ies_offset); - if (!mic_ie || mic_ielen != AES_BLOCK_SIZE) + if (!mic_ie || mic_ielen != 16 /* AES_BLOCK_SIZE */) goto exit; } @@ -1661,6 +1764,10 @@ bypass_sync_bss: if (!rtw_is_list_empty(&sac->asoc_list)) { rtw_list_delete(&sac->asoc_list); stapriv->asoc_list_cnt--; + #ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (sac->tbtx_enable) + stapriv->tbtx_asoc_list_cnt--; + #endif STA_SET_MESH_PLINK(sac, NULL); } _exit_critical_bh(&stapriv->asoc_list_lock, &irqL); @@ -2357,7 +2464,7 @@ void dump_mesh_plink_ctl(void *sel, _adapter *adapter) } /* this function is called with plink_ctl being locked */ -int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, struct sta_info *sta) +static int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, struct sta_info *sta) { #ifndef DBG_RTW_MESH_PEER_ESTABLISH #define DBG_RTW_MESH_PEER_ESTABLISH 0 @@ -2372,7 +2479,11 @@ int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, str struct rtw_ieee802_11_elems elems; _irqL irqL; int i; + u16 status = 0; int ret = _FAIL; +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + u8 sta_tbtx_enable = _FALSE; +#endif if (!plink->rx_conf_ies || !plink->rx_conf_ies_len) { RTW_INFO(FUNC_ADPT_FMT" no rx confirm from sta "MAC_FMT"\n" @@ -2424,11 +2535,15 @@ int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, str rtw_ap_parse_sta_capability(adapter, sta, plink->rx_conf_ies); - if (rtw_ap_parse_sta_supported_rates(adapter, sta, tlv_ies, tlv_ieslen) != _STATS_SUCCESSFUL_) + status = rtw_ap_parse_sta_supported_rates(adapter, sta, tlv_ies, tlv_ieslen); + if (status != _STATS_SUCCESSFUL_) goto exit; - - if (rtw_ap_parse_sta_security_ie(adapter, sta, &elems) != _STATS_SUCCESSFUL_) + + status = rtw_ap_parse_sta_security_ie(adapter, sta, &elems); + if (status != _STATS_SUCCESSFUL_) { + RTW_INFO(FUNC_ADPT_FMT" security check fail, status=%u\n", FUNC_ADPT_ARG(adapter), status); goto exit; + } rtw_ap_parse_sta_wmm_ie(adapter, sta, tlv_ies, tlv_ieslen); #ifdef CONFIG_RTS_FULL_BW @@ -2436,6 +2551,14 @@ int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, str rtw_parse_sta_vendor_ie_8812(adapter, sta, tlv_ies, tlv_ieslen); #endif/*CONFIG_RTS_FULL_BW*/ +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (elems.tbtx_cap && elems.tbtx_cap_len != 0) { + if(rtw_is_tbtx_capabilty(elems.tbtx_cap, elems.tbtx_cap_len)) { + sta_tbtx_enable = _TRUE; + } + } +#endif + rtw_ap_parse_sta_ht_ie(adapter, sta, &elems); rtw_ap_parse_sta_vht_ie(adapter, sta, &elems); @@ -2467,6 +2590,12 @@ int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, str /* sta->expire_to = mcfg->plink_timeout / 2; */ rtw_list_insert_tail(&sta->asoc_list, &stapriv->asoc_list); stapriv->asoc_list_cnt++; +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (sta_tbtx_enable) { + sta->tbtx_enable = _TRUE; + stapriv->tbtx_asoc_list_cnt++; + } +#endif } _exit_critical_bh(&stapriv->asoc_list_lock, &irqL); @@ -2480,6 +2609,167 @@ exit: return ret; } +int rtw_mesh_set_plink_state(_adapter *adapter, const u8 *mac, u8 plink_state) +{ + struct rtw_mesh_info *minfo = &adapter->mesh_info; + struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl; + struct mesh_plink_ent *plink = NULL; + _irqL irqL2; + struct sta_priv *stapriv = &adapter->stapriv; + struct sta_info *sta = NULL; + _irqL irqL; + struct sta_info *del_sta = NULL; + int ret = _SUCCESS; + + _enter_critical_bh(&(plink_ctl->lock), &irqL2); + + plink = _rtw_mesh_plink_get(adapter, mac); + if (!plink) { + ret = _FAIL; + goto release_plink_ctl; + } + + plink->plink_state = plink_state; + + #if CONFIG_RTW_MESH_ACNODE_PREVENT + if (plink_state == RTW_MESH_PLINK_OPN_SNT) { + if (rtw_mesh_scanned_is_acnode_confirmed(adapter, plink->scanned) + && rtw_mesh_acnode_prevent_allow_sacrifice(adapter) + ) { + struct sta_info *sac = rtw_mesh_acnode_prevent_pick_sacrifice(adapter); + + if (sac) { + del_sta = sac; + _enter_critical_bh(&stapriv->asoc_list_lock, &irqL); + if (!rtw_is_list_empty(&del_sta->asoc_list)) { + rtw_list_delete(&del_sta->asoc_list); + stapriv->asoc_list_cnt--; + #ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (del_sta->tbtx_enable) + stapriv->tbtx_asoc_list_cnt--; + #endif + STA_SET_MESH_PLINK(del_sta, NULL); + } + _exit_critical_bh(&stapriv->asoc_list_lock, &irqL); + RTW_INFO(FUNC_ADPT_FMT" sacrifice "MAC_FMT" for acnode\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(del_sta->cmn.mac_addr)); + } + } + } else + #endif + if (plink_state == RTW_MESH_PLINK_OPN_RCVD + || plink_state == RTW_MESH_PLINK_CNF_RCVD + || plink_state == RTW_MESH_PLINK_ESTAB + ) { + sta = rtw_get_stainfo(stapriv, mac); + if (!sta) { + sta = rtw_alloc_stainfo(stapriv, mac); + if (!sta) + goto release_plink_ctl; + } + + if (plink_state == RTW_MESH_PLINK_ESTAB) { + if (rtw_mesh_peer_establish(adapter, plink, sta) != _SUCCESS) { + del_sta = sta; + ret = _FAIL; + goto release_plink_ctl; + } + } + } + else if (plink_state == RTW_MESH_PLINK_HOLDING) { + del_sta = rtw_get_stainfo(stapriv, mac); + if (!del_sta) + goto release_plink_ctl; + + _enter_critical_bh(&stapriv->asoc_list_lock, &irqL); + if (!rtw_is_list_empty(&del_sta->asoc_list)) { + rtw_list_delete(&del_sta->asoc_list); + stapriv->asoc_list_cnt--; + #ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (del_sta->tbtx_enable) + stapriv->tbtx_asoc_list_cnt--; + #endif + STA_SET_MESH_PLINK(del_sta, NULL); + } + _exit_critical_bh(&stapriv->asoc_list_lock, &irqL); + } + +release_plink_ctl: + _exit_critical_bh(&(plink_ctl->lock), &irqL2); + + if (del_sta) { + u8 sta_addr[ETH_ALEN]; + u8 updated = _FALSE; + + _rtw_memcpy(sta_addr, del_sta->cmn.mac_addr, ETH_ALEN); + updated = ap_free_sta(adapter, del_sta, 0, 0, 1); + rtw_mesh_expire_peer(stapriv->padapter, sta_addr); + + associated_clients_update(adapter, updated, STA_INFO_UPDATE_ALL); + } + + return ret; +} + +struct mesh_set_plink_cmd_parm { + const u8 *mac; + u8 plink_state; +}; + +u8 rtw_mesh_set_plink_state_cmd_hdl(_adapter *adapter, u8 *parmbuf) +{ + struct mesh_set_plink_cmd_parm *parm = (struct mesh_set_plink_cmd_parm *)parmbuf; + + if (rtw_mesh_set_plink_state(adapter, parm->mac, parm->plink_state) == _SUCCESS) + return H2C_SUCCESS; + + return H2C_CMD_FAIL; +} + +u8 rtw_mesh_set_plink_state_cmd(_adapter *adapter, const u8 *mac, u8 plink_state) +{ + struct cmd_obj *cmdobj; + struct mesh_set_plink_cmd_parm *parm; + struct cmd_priv *cmdpriv = &adapter->cmdpriv; + struct submit_ctx sctx; + u8 res = _SUCCESS; + + /* prepare cmd parameter */ + parm = rtw_zmalloc(sizeof(*parm)); + if (parm == NULL) { + res = _FAIL; + goto exit; + } + parm->mac = mac; + parm->plink_state = plink_state; + + /* need enqueue, prepare cmd_obj and enqueue */ + cmdobj = rtw_zmalloc(sizeof(*cmdobj)); + if (cmdobj == NULL) { + res = _FAIL; + rtw_mfree(parm, sizeof(*parm)); + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_SET_MESH_PLINK_STATE); + cmdobj->sctx = &sctx; + rtw_sctx_init(&sctx, 2000); + + res = rtw_enqueue_cmd(cmdpriv, cmdobj); + if (res == _SUCCESS) { + rtw_sctx_wait(&sctx, __func__); + _enter_critical_mutex(&cmdpriv->sctx_mutex, NULL); + if (sctx.status == RTW_SCTX_SUBMITTED) + cmdobj->sctx = NULL; + _exit_critical_mutex(&cmdpriv->sctx_mutex, NULL); + if (sctx.status != RTW_SCTX_DONE_SUCCESS) + res = _FAIL; + } + +exit: + return res; +} + void rtw_mesh_expire_peer_notify(_adapter *adapter, const u8 *peer_addr) { u8 null_ssid[2] = {0, 0}; @@ -2511,7 +2801,7 @@ static u8 *rtw_mesh_construct_peer_mesh_close(_adapter *adapter, struct mesh_pli + 2 /* category, action */ + 2 + minfo->mesh_id_len /* mesh id */ + 2 + 8 + (minfo->mesh_auth_id ? 16 : 0) /* mpm */ - + (minfo->mesh_auth_id ? 2 + AES_BLOCK_SIZE : 0) /* mic */ + + (minfo->mesh_auth_id ? 2 + 16 /* AES_BLOCK_SIZE */ : 0) /* mic */ + (minfo->mesh_auth_id ? 70 : 0) /* ampe */ ; @@ -2545,7 +2835,7 @@ static u8 *rtw_mesh_construct_peer_mesh_close(_adapter *adapter, struct mesh_pli int enc_ret; *pos = WLAN_EID_MIC; - *(pos + 1) = AES_BLOCK_SIZE; + *(pos + 1) = 16 /* AES_BLOCK_SIZE */; ampe_buf[0] = WLAN_EID_AMPE; ampe_buf[1] = 68; @@ -3017,6 +3307,7 @@ void rtw_mesh_cfg_init_peer_sel_policy(struct rtw_mesh_cfg *mcfg) void rtw_mesh_cfg_init(_adapter *adapter) { + struct registry_priv *regsty = adapter_to_regsty(adapter); struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg; mcfg->max_peer_links = RTW_MESH_MAX_PEER_LINKS; @@ -3047,8 +3338,8 @@ void rtw_mesh_cfg_init(_adapter *adapter) #endif #if CONFIG_RTW_MESH_DATA_BMC_TO_UC - mcfg->b2u_flags_msrc = 0; - mcfg->b2u_flags_mfwd = RTW_MESH_B2U_GA_UCAST; + mcfg->b2u_flags_msrc = regsty->msrc_b2u_flags; + mcfg->b2u_flags_mfwd = regsty->mfwd_b2u_flags; #endif } @@ -3256,7 +3547,7 @@ endlookup: static bool rtw_mesh_data_bmc_to_uc(_adapter *adapter , const u8 *da, const u8 *sa, const u8 *mda, const u8 *msa , u8 ae_need, const u8 *ori_ta, u8 mfwd_ttl - , _list *b2u_list, u8 *b2u_num, u32 *b2u_mseq) + , u16 os_qid, _list *b2u_list, u8 *b2u_num, u32 *b2u_mseq) { struct sta_priv *stapriv = &adapter->stapriv; struct xmit_priv *xmitpriv = &adapter->xmitpriv; @@ -3292,14 +3583,14 @@ static bool rtw_mesh_data_bmc_to_uc(_adapter *adapter struct pkt_attrib *attrib; sta = rtw_get_stainfo_by_offset(stapriv, b2u_sta_id[i]); - if (!(sta->state & _FW_LINKED) + if (!(sta->state & WIFI_ASOC_STATE) || _rtw_memcmp(sta->cmn.mac_addr, msa, ETH_ALEN) == _TRUE || (ori_ta && _rtw_memcmp(sta->cmn.mac_addr, ori_ta, ETH_ALEN) == _TRUE) || is_broadcast_mac_addr(sta->cmn.mac_addr) || is_zero_mac_addr(sta->cmn.mac_addr)) continue; - b2uframe = rtw_alloc_xmitframe(xmitpriv); + b2uframe = rtw_alloc_xmitframe(xmitpriv, os_qid); if (!b2uframe) { bmc_need = _TRUE; break; @@ -3339,7 +3630,7 @@ void dump_mesh_b2u_flags(void *sel, _adapter *adapter) } #endif /* CONFIG_RTW_MESH_DATA_BMC_TO_UC */ -int rtw_mesh_addr_resolve(_adapter *adapter, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list) +int rtw_mesh_addr_resolve(_adapter *adapter, u16 os_qid, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list) { struct pkt_file pktfile; struct ethhdr etherhdr; @@ -3401,7 +3692,7 @@ int rtw_mesh_addr_resolve(_adapter *adapter, struct xmit_frame *xframe, _pkt *pk bmc_need = rtw_mesh_data_bmc_to_uc(adapter , etherhdr.h_dest, etherhdr.h_source , etherhdr.h_dest, adapter_mac_addr(adapter), ae_need, NULL, 0 - , b2u_list, &b2u_num, &b2u_mseq); + , os_qid, b2u_list, &b2u_num, &b2u_mseq); if (bmc_need == _FALSE) { res = RTW_BMC_NO_NEED; goto exit; @@ -3578,7 +3869,7 @@ int rtw_mesh_rx_data_validate_hdr(_adapter *adapter, union recv_frame *rframe, s goto exit; switch (rattrib->to_fr_ds) { - case 1: + case 2: if (!IS_MCAST(GetAddr1Ptr(whdr))) goto exit; *sta = rtw_get_stainfo(stapriv, get_addr2_ptr(whdr)); @@ -3666,7 +3957,7 @@ int rtw_mesh_rx_data_validate_mctrl(_adapter *adapter, union recv_frame *rframe ae = mctrl->flags & MESH_FLAGS_AE; mlen = ae_to_mesh_ctrl_len[ae]; switch (rattrib->to_fr_ds) { - case 1: + case 2: *da = mda; if (ae == MESH_FLAGS_AE_A4) *sa = mctrl->eaddr1; @@ -3776,6 +4067,7 @@ int rtw_mesh_rx_msdu_act_check(union recv_frame *rframe , const u8 *mda, const u8 *msa , const u8 *da, const u8 *sa , struct rtw_ieee80211s_hdr *mctrl + , u8 *msdu, enum rtw_rx_llc_hdl llc_hdl , struct xmit_frame **fwd_frame, _list *b2u_list) { _adapter *adapter = rframe->u.hdr.adapter; @@ -3785,6 +4077,7 @@ int rtw_mesh_rx_msdu_act_check(union recv_frame *rframe struct rtw_mesh_path *mppath; u8 is_mda_bmc = IS_MCAST(mda); u8 is_mda_self = !is_mda_bmc && _rtw_memcmp(mda, adapter_mac_addr(adapter), ETH_ALEN); + u16 os_qid; struct xmit_frame *xframe; struct pkt_attrib *xattrib; u8 fwd_ra[ETH_ALEN] = {0}; @@ -4012,6 +4305,8 @@ fwd_chk: goto exit; } + os_qid = rtw_os_recv_select_queue(msdu, llc_hdl); + #if CONFIG_RTW_MESH_DATA_BMC_TO_UC _rtw_init_listhead(b2u_list); #endif @@ -4025,13 +4320,13 @@ fwd_chk: ) { bmc_need = rtw_mesh_data_bmc_to_uc(adapter , da, sa, mda, msa, ae_need, rframe->u.hdr.psta->cmn.mac_addr, mctrl->ttl - 1 - , b2u_list, &b2u_num, &fwd_mseq); + , os_qid, b2u_list, &b2u_num, &fwd_mseq); } if (bmc_need == _TRUE) #endif { - xframe = rtw_alloc_xmitframe(&adapter->xmitpriv); + xframe = rtw_alloc_xmitframe(&adapter->xmitpriv, os_qid); if (!xframe) { #ifdef DBG_TX_DROP_FRAME RTW_INFO("DBG_TX_DROP_FRAME "FUNC_ADPT_FMT" rtw_alloc_xmitframe fail\n" diff --git a/core/mesh/rtw_mesh.h b/core/mesh/rtw_mesh.h index 1b060e7..5410ba4 100644 --- a/core/mesh/rtw_mesh.h +++ b/core/mesh/rtw_mesh.h @@ -412,7 +412,7 @@ u8 *rtw_set_ie_mesh_config(u8 *buf, u32 *buf_len , bool mbca_en, bool tbtt_adj, bool ps_level); int rtw_bss_is_same_mbss(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b); -int rtw_bss_is_candidate_mesh_peer(WLAN_BSSID_EX *self, WLAN_BSSID_EX *target, u8 ch, u8 add_peer); +int rtw_bss_is_candidate_mesh_peer(_adapter *adapter, WLAN_BSSID_EX *target, u8 ch, u8 add_peer); void rtw_chk_candidate_peer_notify(_adapter *adapter, struct wlan_network *scanned); @@ -484,7 +484,8 @@ void rtw_mesh_plink_ctl_init(_adapter *adapter); void rtw_mesh_plink_ctl_deinit(_adapter *adapter); void dump_mesh_plink_ctl(void *sel, _adapter *adapter); -int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, struct sta_info *sta); +u8 rtw_mesh_set_plink_state_cmd(_adapter *adapter, const u8 *mac, u8 plink_state); + void _rtw_mesh_expire_peer_ent(_adapter *adapter, struct mesh_plink_ent *plink); void rtw_mesh_expire_peer(_adapter *adapter, const u8 *peer_addr); u8 rtw_mesh_ps_annc(_adapter *adapter, u8 ps); @@ -501,7 +502,7 @@ void rtw_mesh_deinit_mesh_info(_adapter *adapter); void dump_mesh_b2u_flags(void *sel, _adapter *adapter); #endif -int rtw_mesh_addr_resolve(_adapter *adapter, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list); +int rtw_mesh_addr_resolve(_adapter *adapter, u16 os_qid, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list); s8 rtw_mesh_tx_set_whdr_mctrl_len(u8 mesh_frame_mode, struct pkt_attrib *attrib); void rtw_mesh_tx_build_mctrl(_adapter *adapter, struct pkt_attrib *attrib, u8 *buf); @@ -518,6 +519,7 @@ int rtw_mesh_rx_msdu_act_check(union recv_frame *rframe , const u8 *mda, const u8 *msa , const u8 *da, const u8 *sa , struct rtw_ieee80211s_hdr *mctrl + , u8 *msdu, enum rtw_rx_llc_hdl llc_hdl , struct xmit_frame **fwd_frame, _list *b2u_list); void dump_mesh_stats(void *sel, _adapter *adapter); diff --git a/core/mesh/rtw_mesh_hwmp.c b/core/mesh/rtw_mesh_hwmp.c index 449e838..04be425 100644 --- a/core/mesh/rtw_mesh_hwmp.c +++ b/core/mesh/rtw_mesh_hwmp.c @@ -394,162 +394,6 @@ int rtw_mesh_path_error_tx(_adapter *adapter, return 0; } -static u32 rtw_get_vht_bitrate(u8 mcs, u8 bw, u8 nss, u8 sgi) -{ - static const u32 base[4][10] = { - { 6500000, - 13000000, - 19500000, - 26000000, - 39000000, - 52000000, - 58500000, - 65000000, - 78000000, - /* not in the spec, but some devices use this: */ - 86500000, - }, - { 13500000, - 27000000, - 40500000, - 54000000, - 81000000, - 108000000, - 121500000, - 135000000, - 162000000, - 180000000, - }, - { 29300000, - 58500000, - 87800000, - 117000000, - 175500000, - 234000000, - 263300000, - 292500000, - 351000000, - 390000000, - }, - { 58500000, - 117000000, - 175500000, - 234000000, - 351000000, - 468000000, - 526500000, - 585000000, - 702000000, - 780000000, - }, - }; - u32 bitrate; - int bw_idx; - - if (mcs > 9) { - RTW_HWMP_INFO("Invalid mcs = %d\n", mcs); - return 0; - } - - if (nss > 4 || nss < 1) { - RTW_HWMP_INFO("Now only support nss = 1, 2, 3, 4\n"); - } - - switch (bw) { - case CHANNEL_WIDTH_160: - bw_idx = 3; - break; - case CHANNEL_WIDTH_80: - bw_idx = 2; - break; - case CHANNEL_WIDTH_40: - bw_idx = 1; - break; - case CHANNEL_WIDTH_20: - bw_idx = 0; - break; - default: - RTW_HWMP_INFO("bw = %d currently not supported\n", bw); - return 0; - } - - bitrate = base[bw_idx][mcs]; - bitrate *= nss; - - if (sgi) - bitrate = (bitrate / 9) * 10; - - /* do NOT round down here */ - return (bitrate + 50000) / 100000; -} - -static u32 rtw_get_ht_bitrate(u8 mcs, u8 bw, u8 sgi) -{ - int modulation, streams, bitrate; - - /* the formula below does only work for MCS values smaller than 32 */ - if (mcs >= 32) { - RTW_HWMP_INFO("Invalid mcs = %d\n", mcs); - return 0; - } - - if (bw > 1) { - RTW_HWMP_INFO("Now HT only support bw = 0(20Mhz), 1(40Mhz)\n"); - return 0; - } - - modulation = mcs & 7; - streams = (mcs >> 3) + 1; - - bitrate = (bw == 1) ? 13500000 : 6500000; - - if (modulation < 4) - bitrate *= (modulation + 1); - else if (modulation == 4) - bitrate *= (modulation + 2); - else - bitrate *= (modulation + 3); - - bitrate *= streams; - - if (sgi) - bitrate = (bitrate / 9) * 10; - - /* do NOT round down here */ - return (bitrate + 50000) / 100000; -} - -/** - * @bw: 0(20Mhz), 1(40Mhz), 2(80Mhz), 3(160Mhz) - * @rate_idx: DESC_RATEXXXX & 0x7f - * @sgi: DESC_RATEXXXX >> 7 - * Returns: bitrate in 100kbps - */ -static u32 rtw_desc_rate_to_bitrate(u8 bw, u8 rate_idx, u8 sgi) -{ - u32 bitrate; - - if (rate_idx <= DESC_RATE54M){ - u16 ofdm_rate[12] = {10, 20, 55, 110, - 60, 90, 120, 180, 240, 360, 480, 540}; - bitrate = ofdm_rate[rate_idx]; - } else if ((DESC_RATEMCS0 <= rate_idx) && - (rate_idx <= DESC_RATEMCS31)) { - u8 mcs = rate_idx - DESC_RATEMCS0; - bitrate = rtw_get_ht_bitrate(mcs, bw, sgi); - } else if ((DESC_RATEVHTSS1MCS0 <= rate_idx) && - (rate_idx <= DESC_RATEVHTSS4MCS9)) { - u8 mcs = (rate_idx - DESC_RATEVHTSS1MCS0) % 10; - u8 nss = ((rate_idx - DESC_RATEVHTSS1MCS0) / 10) + 1; - bitrate = rtw_get_vht_bitrate(mcs, bw, nss, sgi); - } else { - /* 60Ghz ??? */ - bitrate = 1; - } - - return bitrate; -} - static u32 rtw_airtime_link_metric_get(_adapter *adapter, struct sta_info *sta) { struct dm_struct *dm = adapter_to_phydm(adapter); diff --git a/core/monitor/rtw_radiotap.c b/core/monitor/rtw_radiotap.c new file mode 100644 index 0000000..e9ebc7d --- /dev/null +++ b/core/monitor/rtw_radiotap.c @@ -0,0 +1,615 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#define _RTW_RADIOTAP_C_ + +#ifdef CONFIG_WIFI_MONITOR + +#include +#include + +#define CHAN2FREQ(a) ((a < 14) ? (2407+5*a) : (5000+5*a)) + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)) +#define IEEE80211_RADIOTAP_ZERO_LEN_PSDU 26 +#define IEEE80211_RADIOTAP_LSIG 27 +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)) +#define IEEE80211_RADIOTAP_TIMESTAMP 22 +/* For IEEE80211_RADIOTAP_TIMESTAMP */ +#define IEEE80211_RADIOTAP_TIMESTAMP_UNIT_MASK 0x000F +#define IEEE80211_RADIOTAP_TIMESTAMP_UNIT_MS 0x0000 +#define IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US 0x0001 +#define IEEE80211_RADIOTAP_TIMESTAMP_UNIT_NS 0x0003 +#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_MASK 0x00F0 +#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_BEGIN_MDPU 0x0000 +#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_EO_MPDU 0x0010 +#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_EO_PPDU 0x0020 +#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_PLCP_SIG_ACQ 0x0030 +#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_UNKNOWN 0x00F0 + +#define IEEE80211_RADIOTAP_TIMESTAMP_FLAG_64BIT 0x00 +#define IEEE80211_RADIOTAP_TIMESTAMP_FLAG_32BIT 0x01 +#define IEEE80211_RADIOTAP_TIMESTAMP_FLAG_ACCURACY 0x02 +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)) +/* for IEEE80211_RADIOTAP_CHANNEL */ +#define IEEE80211_CHAN_GSM 0x1000 /* GSM (900 MHz) */ +#define IEEE80211_CHAN_STURBO 0x2000 /* Static Turbo */ +#define IEEE80211_CHAN_HALF 0x4000 /* Half channel (10 MHz wide) */ +#define IEEE80211_CHAN_QUARTER 0x8000 /* Quarter channel (5 MHz wide) */ +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) +#define IEEE80211_RADIOTAP_VHT 21 +/* For IEEE80211_RADIOTAP_VHT */ +#define IEEE80211_RADIOTAP_VHT_KNOWN_STBC 0x0001 +#define IEEE80211_RADIOTAP_VHT_KNOWN_TXOP_PS_NA 0x0002 +#define IEEE80211_RADIOTAP_VHT_KNOWN_GI 0x0004 +#define IEEE80211_RADIOTAP_VHT_KNOWN_SGI_NSYM_DIS 0x0008 +#define IEEE80211_RADIOTAP_VHT_KNOWN_LDPC_EXTRA_OFDM_SYM 0x0010 +#define IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED 0x0020 +#define IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH 0x0040 +#define IEEE80211_RADIOTAP_VHT_KNOWN_GROUP_ID 0x0080 +#define IEEE80211_RADIOTAP_VHT_KNOWN_PARTIAL_AID 0x0100 + +#define IEEE80211_RADIOTAP_VHT_FLAG_STBC 0x01 +#define IEEE80211_RADIOTAP_VHT_FLAG_TXOP_PS_NA 0x02 +#define IEEE80211_RADIOTAP_VHT_FLAG_SGI 0x04 +#define IEEE80211_RADIOTAP_VHT_FLAG_SGI_NSYM_M10_9 0x08 +#define IEEE80211_RADIOTAP_VHT_FLAG_LDPC_EXTRA_OFDM_SYM 0x10 +#define IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED 0x20 +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)) +#define IEEE80211_RADIOTAP_CODING_LDPC_USER0 0x01 +#define IEEE80211_RADIOTAP_CODING_LDPC_USER1 0x02 +#define IEEE80211_RADIOTAP_CODING_LDPC_USER2 0x04 +#define IEEE80211_RADIOTAP_CODING_LDPC_USER3 0x08 +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) +#define IEEE80211_RADIOTAP_AMPDU_STATUS 20 +/* For IEEE80211_RADIOTAP_AMPDU_STATUS */ +#define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN 0x0001 +#define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN 0x0002 +#define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN 0x0004 +#define IEEE80211_RADIOTAP_AMPDU_IS_LAST 0x0008 +#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010 +#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020 +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)) +#define IEEE80211_RADIOTAP_AMPDU_EOF 0x0040 +#define IEEE80211_RADIOTAP_AMPDU_EOF_KNOWN 0x0080 +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)) +#define IEEE80211_RADIOTAP_MCS 19 +/* For IEEE80211_RADIOTAP_MCS */ +#define IEEE80211_RADIOTAP_MCS_HAVE_BW 0x01 +#define IEEE80211_RADIOTAP_MCS_HAVE_MCS 0x02 +#define IEEE80211_RADIOTAP_MCS_HAVE_GI 0x04 +#define IEEE80211_RADIOTAP_MCS_HAVE_FMT 0x08 +#define IEEE80211_RADIOTAP_MCS_HAVE_FEC 0x10 + +#define IEEE80211_RADIOTAP_MCS_BW_MASK 0x03 +#define IEEE80211_RADIOTAP_MCS_BW_20 0 +#define IEEE80211_RADIOTAP_MCS_BW_40 1 +#define IEEE80211_RADIOTAP_MCS_BW_20L 2 +#define IEEE80211_RADIOTAP_MCS_BW_20U 3 +#define IEEE80211_RADIOTAP_MCS_SGI 0x04 +#define IEEE80211_RADIOTAP_MCS_FMT_GF 0x08 +#define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10 +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0)) +#define IEEE80211_RADIOTAP_MCS_HAVE_STBC 0x20 + +#define IEEE80211_RADIOTAP_MCS_STBC_MASK 0x60 +#define IEEE80211_RADIOTAP_MCS_STBC_1 1 +#define IEEE80211_RADIOTAP_MCS_STBC_2 2 +#define IEEE80211_RADIOTAP_MCS_STBC_3 3 +#define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5 +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)) +#define IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE 29 +#define IEEE80211_RADIOTAP_VENDOR_NAMESPACE 30 +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)) +#define IEEE80211_RADIOTAP_F_BADFCS 0x40 +#endif + +static inline void _rtw_radiotap_fill_flags(struct rx_pkt_attrib *a, u8 *flags) +{ + struct moinfo *moif = (struct moinfo *)&a->moif; + + if (0) + *flags |= IEEE80211_RADIOTAP_F_CFP; + + if (0) + *flags |= IEEE80211_RADIOTAP_F_SHORTPRE; + + if ((a->encrypt == 1) || (a->encrypt == 5)) + *flags |= IEEE80211_RADIOTAP_F_WEP; + + if (a->mfrag) + *flags |= IEEE80211_RADIOTAP_F_FRAG; + + if (1) + *flags |= IEEE80211_RADIOTAP_F_FCS; + + if (0) + *flags |= IEEE80211_RADIOTAP_F_DATAPAD; + + if (a->crc_err) + *flags |= IEEE80211_RADIOTAP_F_BADFCS; + + /* Currently unspecified but used + for short guard interval (HT) */ + if (moif->u.snif_info.sgi || a->sgi) + *flags |= 0x80; + +} + +sint rtw_fill_radiotap_hdr(_adapter *padapter, struct rx_pkt_attrib *a, u8 *buf) +{ +#define RTAP_HDR_MAX 64 + + sint ret = _SUCCESS; + struct moinfo *moif = (struct moinfo *)&a->moif; + + u8 rx_cnt = 0; + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + int i = 0; + u8 tmp_8bit = 0; + u16 tmp_16bit = 0; + u32 tmp_32bit = 0; + u64 tmp_64bit = 0; + + _pkt *pskb = NULL; + + struct ieee80211_radiotap_header *rtap_hdr = NULL; + u8 *ptr = NULL; + + /* + radiotap length (include header 8) + 11G length: 36 (0x0040002f) + 11N length: + 11AC length: 60 (0x0070002b) + */ + u8 hdr_buf[RTAP_HDR_MAX] = { 0 }; + u16 rt_len = 8; + + /* create header */ + rtap_hdr = (struct ieee80211_radiotap_header *)&hdr_buf[0]; + rtap_hdr->it_version = PKTHDR_RADIOTAP_VERSION; + + /* each antenna information */ + rx_cnt = rf_type_to_rf_rx_cnt(pHalData->rf_type); +#if 0 + if (rx_cnt > 1) { + rtap_hdr->it_present |= BIT(IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE) | + BIT(IEEE80211_RADIOTAP_EXT); + + for (i = 1; i < rx_cnt; i++) { + tmp_32bit = (BIT(IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | + BIT(IEEE80211_RADIOTAP_LOCK_QUALITY) | + BIT(IEEE80211_RADIOTAP_ANTENNA) | + BIT(IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE) | + BIT(IEEE80211_RADIOTAP_EXT)); + _rtw_memcpy(&hdr_buf[rt_len], &tmp_32bit, 4); + rt_len += 4; + } + + tmp_32bit = (BIT(IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | + BIT(IEEE80211_RADIOTAP_LOCK_QUALITY) | + BIT(IEEE80211_RADIOTAP_ANTENNA)); + _rtw_memcpy(&hdr_buf[rt_len], &tmp_32bit, 4); + rt_len += 4; + } +#endif + + /* tsft, Required Alignment: 8 bytes */ + if (0) { //(a->free_cnt) { + /* TSFT + free_cnt */ + rtap_hdr->it_present |= BIT(IEEE80211_RADIOTAP_TSFT); + if (!IS_ALIGNED(rt_len, 8)) + rt_len = ((rt_len + 7) & 0xFFF8); /* Alignment */ + + tmp_64bit = cpu_to_le64(a->free_cnt); + _rtw_memcpy(&hdr_buf[rt_len], &tmp_64bit, 8); + rt_len += 8; + } + + /* flags */ + rtap_hdr->it_present |= BIT(IEEE80211_RADIOTAP_FLAGS); + _rtw_radiotap_fill_flags(a, &hdr_buf[rt_len]); + rt_len += 1; + + /* rate */ + if (a->data_rate <= DESC_RATE54M) { + rtap_hdr->it_present |= BIT(IEEE80211_RADIOTAP_RATE); + hdr_buf[rt_len] = hw_rate_to_m_rate(a->data_rate); + rt_len += 1; + } + + /* channel & flags, Required Alignment: 2 bytes */ + if (1) { + rtap_hdr->it_present |= BIT(IEEE80211_RADIOTAP_CHANNEL); + rt_len += (rt_len % 2); /* Alignment */ + + tmp_16bit = CHAN2FREQ(rtw_get_oper_ch(padapter)); + _rtw_memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); + rt_len += 2; + + /* channel flags */ + tmp_16bit = 0; + if (pHalData->current_band_type == 0) + tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_2GHZ); + else + tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_5GHZ); + + if (a->data_rate <= DESC_RATE11M) { + /* CCK */ + tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_CCK); + } else { + /* OFDM */ + tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_OFDM); + } + + if (rtw_get_oper_bw(padapter) == CHANNEL_WIDTH_10) { + /* 10Mhz Channel Width */ + tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_HALF); + } + + if (rtw_get_oper_bw(padapter) == CHANNEL_WIDTH_5) { + /* 5Mhz Channel Width */ + tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_QUARTER); + } + _rtw_memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); + rt_len += 2; + } + + /* dBm Antenna Signal */ + rtap_hdr->it_present |= BIT(IEEE80211_RADIOTAP_DBM_ANTSIGNAL); + hdr_buf[rt_len] = a->phy_info.recv_signal_power; + rt_len += 1; + +#if 0 + /* dBm Antenna Noise */ + rtap_hdr->it_present |= BIT(IEEE80211_RADIOTAP_DBM_ANTNOISE); + hdr_buf[rt_len] = 0; + rt_len += 1; +#endif +#if 0 + /* Signal Quality, Required Alignment: 2 bytes */ + rtap_hdr->it_present |= BIT(IEEE80211_RADIOTAP_LOCK_QUALITY); + if (!IS_ALIGNED(rt_len, 2)) + rt_len++; + hdr_buf[rt_len] = a->phy_info.signal_quality; + rt_len += 2; + +#endif + +#if 0 + /* Antenna */ + rtap_hdr->it_present |= BIT(IEEE80211_RADIOTAP_ANTENNA); + hdr_buf[rt_len] = 0; /* pHalData->rf_type; */ + rt_len += 1; +#endif +#if 0 + /* RX flags, Required Alignment: 2 bytes */ + rtap_hdr->it_present |= BIT(IEEE80211_RADIOTAP_RX_FLAGS); + tmp_16bit = 0; + _rtw_memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); + rt_len += 2; +#endif + + /* MCS information, Required Alignment: 1 bytes */ + if (a->data_rate >= DESC_RATEMCS0 && a->data_rate <= DESC_RATEMCS31) { + rtap_hdr->it_present |= BIT(IEEE80211_RADIOTAP_MCS); + /* Structure u8 known, u8 flags, u8 mcs */ + + /* known.bandwidth */ + hdr_buf[rt_len] |= IEEE80211_RADIOTAP_MCS_HAVE_BW; + if (moif->u.snif_info.ofdm_bw) + hdr_buf[rt_len + 1] |= IEEE80211_RADIOTAP_MCS_BW_40; + if (a->bw == CHANNEL_WIDTH_40) + hdr_buf[rt_len + 1] |= IEEE80211_RADIOTAP_MCS_BW_40; + else + hdr_buf[rt_len + 1] |= IEEE80211_RADIOTAP_MCS_BW_20; + + + /* known.guard interval */ + hdr_buf[rt_len] |= IEEE80211_RADIOTAP_MCS_HAVE_GI; + if (moif->u.snif_info.sgi) { + hdr_buf[rt_len + 1] |= IEEE80211_RADIOTAP_MCS_SGI; + } else { + hdr_buf[rt_len + 1] |= ((a->sgi & 0x01) << 2); + } + + /* FEC Type */ + hdr_buf[rt_len] |= IEEE80211_RADIOTAP_MCS_HAVE_FEC; + if (moif->u.snif_info.ldpc) { + hdr_buf[rt_len + 1] |= ((moif->u.snif_info.ldpc & 0x01) << 4); + } else { + hdr_buf[rt_len + 1] |= ((a->ldpc & 0x01) << 4); + } + + /* STBC */ + hdr_buf[rt_len] |= IEEE80211_RADIOTAP_MCS_HAVE_STBC; + if (moif->u.snif_info.stbc) { + hdr_buf[rt_len + 1] |= ((moif->u.snif_info.stbc & 0x03) << 5); + } else { + hdr_buf[rt_len + 1] |= ((a->stbc & 0x03) << 5); + } + + /* known.MCS index */ + hdr_buf[rt_len] |= IEEE80211_RADIOTAP_MCS_HAVE_MCS; + + /* u8 mcs */ + hdr_buf[rt_len + 2] = a->data_rate - DESC_RATEMCS0; + + rt_len += 3; + } + + /* AMPDU, Required Alignment: 4 bytes */ + if (a->ampdu) { + static u32 ref_num = 0x10000000; + static u8 ppdu_cnt = 0; + + /* Structure u32 reference number, u16 flags, u8 delimiter CRC value, u8 reserved */ + rtap_hdr->it_present |= BIT(IEEE80211_RADIOTAP_AMPDU_STATUS); + if (!IS_ALIGNED(rt_len, 4)) + rt_len = ((rt_len + 3) & 0xFFFC); /* Alignment */ + + /* u32 reference number */ + if (a->ppdu_cnt != ppdu_cnt) { + ppdu_cnt = a->ppdu_cnt; + ref_num += 1; + } + tmp_32bit = cpu_to_le32(ref_num); + _rtw_memcpy(&hdr_buf[rt_len], &tmp_32bit, 4); + rt_len += 4; + + /* u16 flags */ + tmp_16bit = 0; + if (0) { + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN); + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN); + } + + if (0) { + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_AMPDU_IS_LAST); + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN); + } + + if (0) { + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR); + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN); + } + + if (a->ampdu_eof) { + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_AMPDU_EOF_KNOWN); + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_AMPDU_EOF); + } + + _rtw_memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); + rt_len += 2; + + /* u8 delimiter CRC value, u8 reserved */ + rt_len += 2; + } + + /* VHT, Required Alignment: 2 bytes */ + if (a->data_rate >= DESC_RATEVHTSS1MCS0 && a->data_rate <= DESC_RATEVHTSS4MCS9) { + rtap_hdr->it_present |= BIT(IEEE80211_RADIOTAP_VHT); + + rt_len += (rt_len % 2); /* Alignment */ + + /* Structure + u16 known, u8 flags, u8 bandwidth, u8 mcs_nss[4], + u8 coding, u8 group_id, u16 partial_aid */ + + tmp_16bit = 0; + + /* STBC */ + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_VHT_KNOWN_STBC); + if (moif->u.snif_info.stbc) { + hdr_buf[rt_len + 2] |= IEEE80211_RADIOTAP_VHT_FLAG_STBC; + } else { + hdr_buf[rt_len + 2] |= (a->stbc & 0x01); + } + + /* TXOP_PS_NOT_ALLOWED */ + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_VHT_KNOWN_TXOP_PS_NA); + if (moif->u.snif_info.vht_txop_not_allow) { + hdr_buf[rt_len + 2] |= IEEE80211_RADIOTAP_VHT_FLAG_TXOP_PS_NA; + } + + + /* Guard interval */ + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_VHT_KNOWN_GI); + if (moif->u.snif_info.sgi) { + hdr_buf[rt_len + 2] |= IEEE80211_RADIOTAP_VHT_FLAG_SGI; + } else { + hdr_buf[rt_len + 2] |= ((a->sgi & 0x01) << 2); + } + + /* Short GI NSYM */ + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_VHT_KNOWN_SGI_NSYM_DIS); + if (moif->u.snif_info.vht_nsym_dis) { + hdr_buf[rt_len + 2] |= IEEE80211_RADIOTAP_VHT_FLAG_SGI_NSYM_M10_9; + } + + /* LDPC extra OFDM symbol */ + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_VHT_KNOWN_LDPC_EXTRA_OFDM_SYM); + if (moif->u.snif_info.vht_ldpc_extra) { + hdr_buf[rt_len + 2] |= IEEE80211_RADIOTAP_VHT_FLAG_LDPC_EXTRA_OFDM_SYM; + } else { + hdr_buf[rt_len + 2] |= ((a->ldpc & 0x01) << 4); + } + + /* Short GI NSYM */ + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED); + if (moif->u.snif_info.vht_beamformed) { + hdr_buf[rt_len + 2] |= IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED; + } + + /* know.Bandwidth */ + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH); + + /* Group ID */ + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_VHT_KNOWN_GROUP_ID); + + /* Partial AID */ + tmp_16bit |= cpu_to_le16(IEEE80211_RADIOTAP_VHT_KNOWN_PARTIAL_AID); + + _rtw_memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); + rt_len += 3; + + /* u8 bandwidth */ + if (moif->u.snif_info.ofdm_bw) + tmp_8bit = moif->u.snif_info.ofdm_bw; + else + tmp_8bit = a->bw; + + switch (tmp_8bit) { + case CHANNEL_WIDTH_20: + hdr_buf[rt_len] |= 0; + break; + case CHANNEL_WIDTH_40: + hdr_buf[rt_len] |= 1; + break; + case CHANNEL_WIDTH_80: + hdr_buf[rt_len] |= 4; + break; + case CHANNEL_WIDTH_160: + hdr_buf[rt_len] |= 11; + break; + default: + hdr_buf[rt_len] |= 0; + } + rt_len += 1; + + /* u8 mcs_nss[4] */ + if ((DESC_RATEVHTSS1MCS0 <= a->data_rate) && + (a->data_rate <= DESC_RATEVHTSS4MCS9)) { + /* User 0 */ + /* MCS */ + hdr_buf[rt_len] = ((a->data_rate - DESC_RATEVHTSS1MCS0) % 10) << 4; + /* NSS */ + hdr_buf[rt_len] |= (((a->data_rate - DESC_RATEVHTSS1MCS0) / 10) + 1); + } + rt_len += 4; + + /* u8 coding, phystat? */ + hdr_buf[rt_len] = 0; + rt_len += 1; + + /* u8 group_id */ + hdr_buf[rt_len] = moif->u.snif_info.vht_group_id; + rt_len += 1; + + /* u16 partial_aid */ + tmp_16bit = cpu_to_le16(moif->u.snif_info.vht_nsts_aid); + _rtw_memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); + rt_len += 2; + } + + /* frame timestamp, Required Alignment: 8 bytes */ + if (0) { //(a->free_cnt) { + rtap_hdr->it_present |= BIT(IEEE80211_RADIOTAP_TIMESTAMP); + if (!IS_ALIGNED(rt_len, 8)) + rt_len = ((rt_len + 7) & 0xFFF8); /* Alignment */ + + /* u64 timestamp */ + tmp_64bit = cpu_to_le64(a->free_cnt); + _rtw_memcpy(&hdr_buf[rt_len], &tmp_64bit, 8); + rt_len += 8; + + /* u16 accuracy */ + tmp_16bit = cpu_to_le16(22); + _rtw_memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); + rt_len += 2; + + /* u8 unit/position */ + hdr_buf[rt_len] |= IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US; + rt_len += 1; + + /* u8 flags */ + hdr_buf[rt_len] |= IEEE80211_RADIOTAP_TIMESTAMP_FLAG_32BIT; + hdr_buf[rt_len] |= IEEE80211_RADIOTAP_TIMESTAMP_FLAG_ACCURACY; + rt_len += 1; + } + + /* each antenna information */ +#if 0 + if (rx_cnt > 1) { + for (i = 0; i <= rx_cnt; i++) { + /* dBm Antenna Signal */ + hdr_buf[rt_len] = a->phy_info.rx_mimo_signal_strength[i]; + rt_len += 1; + + /* Signal Quality */ + if (!IS_ALIGNED(rt_len, 2)) + rt_len++; + hdr_buf[rt_len] = cpu_to_le16(a->phy_info.rx_mimo_signal_quality[i]); + rt_len += 2; + + /* Antenna */ + hdr_buf[rt_len] = i; /* pHalData->rf_type; */ + rt_len += 1; + } + } +#endif + + /* push to skb */ + pskb = (_pkt *)buf; + if (skb_headroom(pskb) < rt_len) { + RTW_INFO("%s:%d %s headroom is too small.\n", __FILE__, __LINE__, __func__); + ret = _FAIL; + return ret; + } + + ptr = skb_push(pskb, rt_len); + if (ptr) { + rtap_hdr->it_len = cpu_to_le16(rt_len); + rtap_hdr->it_present = cpu_to_le32(rtap_hdr->it_present); + memcpy(ptr, rtap_hdr, rt_len); + } else + ret = _FAIL; + + return ret; + +} + +void rx_query_moinfo(struct rx_pkt_attrib *a, u8 *desc) +{ + switch (a->drvinfo_sz) { + case 40: + _rtw_memcpy(a->moif, &desc[32], 8); + break; + case 48: + _rtw_memcpy(a->moif, &desc[32], 12); + break; + case 32: + /* passthrough */ + default: + break; + } +} + +#endif /* CONFIG_WIFI_MONITOR */ diff --git a/core/monitor/rtw_radiotap.h b/core/monitor/rtw_radiotap.h new file mode 100644 index 0000000..affacd1 --- /dev/null +++ b/core/monitor/rtw_radiotap.h @@ -0,0 +1,63 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#ifndef __RTW_RADIOTAP_H_ +#define __RTW_RADIOTAP_H_ + +struct mon_reg_backup { + /* flags */ + u8 known_rcr:1; + u8 known_drvinfo:1; + u8 known_rxfilter:1; + u8 known_misc0:1; + /* data */ + u8 drvinfo; + u16 rxfilter0; + u16 rxfilter1; + u16 rxfilter2; + u32 rcr; + u32 misc0; +}; + +struct moinfo { + union { + struct { + u32 sgi:1; + u32 ldpc:1; + u32 stbc:2; + u32 not_sounding:1; + u32 ofdm_bw:2; + u32 vht_group_id:2; + u32 vht_nsts_aid:12; + u32 vht_txop_not_allow:1; + u32 vht_nsym_dis:1; + u32 vht_ldpc_extra:1; + u32 vht_su_mcs:12; + u32 vht_beamformed:1; + }snif_info; + + struct { + u32 A; + u32 B; + u32 C; + }plcp_info; + }u; +}; + +sint rtw_fill_radiotap_hdr(_adapter *padapter, struct rx_pkt_attrib *a, u8 *buf); + +void rx_query_moinfo(struct rx_pkt_attrib *a, u8 *desc); + +#endif /* __RTW_RADIOTAP_H_ */ + diff --git a/core/rtw_ap.c b/core/rtw_ap.c index 96dee53..ec72564 100644 --- a/core/rtw_ap.c +++ b/core/rtw_ap.c @@ -171,7 +171,7 @@ void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *d u8 bmatch = _FALSE; u8 *pie = pnetwork->IEs; u8 *p = NULL, *dst_ie = NULL, *premainder_ie = NULL, *pbackup_remainder_ie = NULL; - u32 i, offset, ielen, ie_offset, remainder_ielen = 0; + u32 i, offset, ielen = 0, ie_offset, remainder_ielen = 0; for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;) { pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i); @@ -406,6 +406,9 @@ void expire_timeout_chk(_adapter *padapter) u8 chk_alive_num = 0; char chk_alive_list[NUM_STA]; int i; + int stainfo_offset; + u8 flush_num = 0; + char flush_list[NUM_STA]={0}; #ifdef CONFIG_RTW_MESH if (MLME_IS_MESH(padapter) @@ -424,6 +427,10 @@ void expire_timeout_chk(_adapter *padapter) } #endif +#ifdef CONFIG_RTW_WDS + rtw_wds_path_expire(padapter); +#endif + #ifdef CONFIG_MCC_MODE /* then driver may check fail due to not recv client's frame under sitesurvey, * don't expire timeout chk under MCC under sitesurvey */ @@ -459,27 +466,24 @@ void expire_timeout_chk(_adapter *padapter) if (psta->expire_to > 0) { psta->expire_to--; if (psta->expire_to == 0) { - rtw_list_delete(&psta->auth_list); - pstapriv->auth_list_cnt--; - - RTW_INFO(FUNC_ADPT_FMT" auth expire "MAC_FMT"\n" - , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)); - - _exit_critical_bh(&pstapriv->auth_list_lock, &irqL); - - /* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */ - rtw_free_stainfo(padapter, psta); - /* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */ - - _enter_critical_bh(&pstapriv->auth_list_lock, &irqL); + stainfo_offset = rtw_stainfo_offset(pstapriv, psta); + if (stainfo_offset_valid(stainfo_offset)) + flush_list[flush_num++] = stainfo_offset; + else + rtw_warn_on(1); } } } _exit_critical_bh(&pstapriv->auth_list_lock, &irqL); - psta = NULL; - + for (i = 0; i < flush_num; i++) { + psta = rtw_get_stainfo_by_offset(pstapriv, flush_list[i]); + RTW_INFO(FUNC_ADPT_FMT" auth expire "MAC_FMT"\n" + , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)); + rtw_free_stainfo(padapter, psta); + psta = NULL; + } _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); @@ -512,20 +516,17 @@ void expire_timeout_chk(_adapter *padapter) if (chk_sta_is_alive(psta) || !psta->expire_to) { psta->expire_to = pstapriv->expire_to; psta->keep_alive_trycnt = 0; -#ifdef CONFIG_TX_MCAST2UNI + #if !defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && defined(CONFIG_80211N_HT) psta->under_exist_checking = 0; -#endif /* CONFIG_TX_MCAST2UNI */ + #endif } else psta->expire_to--; -#ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK -#ifdef CONFIG_80211N_HT -#ifdef CONFIG_TX_MCAST2UNI +#if !defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && defined(CONFIG_80211N_HT) if ((psta->flags & WLAN_STA_HT) && (psta->htpriv.agg_enable_bitmap || psta->under_exist_checking)) { /* check sta by delba(addba) for 11n STA */ /* ToDo: use CCX report to check for all STAs */ /* RTW_INFO("asoc check by DELBA/ADDBA! (pstapriv->expire_to=%d s)(psta->expire_to=%d s), [%02x, %d]\n", pstapriv->expire_to*2, psta->expire_to*2, psta->htpriv.agg_enable_bitmap, psta->under_exist_checking); */ - if (psta->expire_to <= (pstapriv->expire_to - 50)) { RTW_INFO("asoc expire by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to - psta->expire_to) * 2); psta->under_exist_checking = 0; @@ -539,9 +540,7 @@ void expire_timeout_chk(_adapter *padapter) psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */ } } -#endif /* CONFIG_TX_MCAST2UNI */ -#endif /* CONFIG_80211N_HT */ -#endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */ +#endif /* !defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && defined(CONFIG_80211N_HT) */ if (psta->expire_to <= 0) { struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -694,7 +693,7 @@ void expire_timeout_chk(_adapter *padapter) continue; #endif - if (!(psta->state & _FW_LINKED)) + if (!(psta->state & WIFI_ASOC_STATE)) continue; #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK @@ -724,6 +723,10 @@ void expire_timeout_chk(_adapter *padapter) if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) { rtw_list_delete(&psta->asoc_list); pstapriv->asoc_list_cnt--; + #ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (psta->tbtx_enable) + pstapriv->tbtx_asoc_list_cnt--; + #endif STA_SET_MESH_PLINK(psta, NULL); } _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); @@ -773,7 +776,7 @@ void rtw_ap_update_sta_ra_info(_adapter *padapter, struct sta_info *psta) if (!psta) return; - if (!(psta->state & _FW_LINKED)) + if (!(psta->state & WIFI_ASOC_STATE)) return; rtw_hal_update_sta_ra_info(padapter, psta); @@ -1024,7 +1027,7 @@ void update_bmc_sta(_adapter *padapter) rtw_hal_update_sta_ra_info(padapter, psta); _enter_critical_bh(&psta->lock, &irqL); - psta->state = _FW_LINKED; + psta->state = WIFI_ASOC_STATE; _exit_critical_bh(&psta->lock, &irqL); rtw_sta_media_status_rpt(padapter, psta, 1); @@ -1199,11 +1202,24 @@ void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta) if (!MLME_IS_MESH(padapter) && psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) psta->state |= WIFI_UNDER_KEY_HANDSHAKE; - psta->state |= _FW_LINKED; + psta->state |= WIFI_ASOC_STATE; _exit_critical_bh(&psta->lock, &irqL); } +#ifdef CONFIG_RTW_80211K +static void update_rm_cap(u8 *frame_head, _adapter *pa, u32 pktlen, int offset) +{ + u8 *res; + sint len; + + res = rtw_get_ie(frame_head + offset, _EID_RRM_EN_CAP_IE_, &len, + pktlen - offset); + if (res != NULL) + _rtw_memcpy((void *)pa->rmpriv.rm_en_cap_def, (res + 2), len); +} +#endif + static void update_ap_info(_adapter *padapter, struct sta_info *psta) { struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); @@ -1617,7 +1633,7 @@ static void _rtw_iface_undersurvey_chk(const char *func, _adapter *adapter) iface = dvobj->padapters[i]; if ((iface) && rtw_is_adapter_up(iface)) { pmlmepriv = &iface->mlmepriv; - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)) RTW_ERR("%s ("ADPT_FMT") under survey\n", func, ADPT_ARG(iface)); } } @@ -1638,7 +1654,8 @@ void start_bss_network(_adapter *padapter, struct createbss_parm *parm) WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network); struct dvobj_priv *pdvobj = padapter->dvobj; s16 req_ch = REQ_CH_NONE, req_bw = REQ_BW_NONE, req_offset = REQ_OFFSET_NONE; - u8 ch_to_set = 0, bw_to_set, offset_to_set; + u8 u_ch = 0, u_bw, u_offset; + bool set_u_ch; u8 doiqk = _FALSE; /* use for check ch bw offset can be allowed or not */ u8 chbw_allow = _TRUE; @@ -1721,7 +1738,7 @@ void start_bss_network(_adapter *padapter, struct createbss_parm *parm) chbw_decision: ifbmp_ch_changed = rtw_ap_chbw_decision(padapter, parm->ifbmp, parm->excl_ifbmp , req_ch, req_bw, req_offset - , &ch_to_set, &bw_to_set, &offset_to_set, &chbw_allow); + , &u_ch, &u_bw, &u_offset, &chbw_allow, &set_u_ch); for (i = 0; i < pdvobj->iface_nums; i++) { if (!(parm->ifbmp & BIT(i)) || !pdvobj->padapters[i]) @@ -1768,17 +1785,36 @@ chbw_decision: rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk); } - if (ch_to_set != 0) { - set_channel_bwmode(padapter, ch_to_set, offset_to_set, bw_to_set); - rtw_mi_update_union_chan_inf(padapter, ch_to_set, offset_to_set, bw_to_set); - } + if (set_u_ch) + set_channel_bwmode(padapter, u_ch, u_offset, u_bw); doiqk = _FALSE; rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk); #ifdef CONFIG_MCC_MODE /* after set_channel_bwmode for backup IQK */ - rtw_hal_set_mcc_setting_start_bss_network(padapter, chbw_allow); + if (rtw_hal_set_mcc_setting_start_bss_network(padapter, chbw_allow) == _FAIL) { + /* MCC setting fail, update to buddy's channel */ + rtw_mi_get_ch_setting_union_no_self(padapter, &u_ch, &u_bw, &u_offset); + pnetwork->Configuration.DSConfig = u_ch; + padapter->mlmeextpriv.cur_channel = u_ch; + padapter->mlmeextpriv.cur_bwmode = u_bw; + padapter->mlmeextpriv.cur_ch_offset = u_offset; + + if (ifbmp_ch_changed == 0) { + u8 ht_option = 0; + +#ifdef CONFIG_80211N_HT + ht_option = padapter->mlmepriv.htpriv.ht_option; +#endif + + rtw_cfg80211_ch_switch_notify(padapter + , padapter->mlmeextpriv.cur_channel + , padapter->mlmeextpriv.cur_bwmode + , padapter->mlmeextpriv.cur_ch_offset + , ht_option, 0); + } + } #endif #if defined(CONFIG_IOCTL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) @@ -1802,6 +1838,8 @@ chbw_decision: } #endif /* defined(CONFIG_IOCTL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) */ + rtw_rfctl_update_op_mode(adapter_to_rfctl(padapter), parm->ifbmp, 1); + if (DUMP_ADAPTERS_STATUS) { RTW_INFO(FUNC_ADPT_FMT" done\n", FUNC_ADPT_ARG(padapter)); dump_adapters_status(RTW_DBGDUMP , adapter_to_dvobj(padapter)); @@ -1892,10 +1930,17 @@ update_beacon: #endif /* !defined(CONFIG_INTERRUPT_BASED_TXBCN) */ #ifdef CONFIG_FW_HANDLE_TXBCN - if (mlme_act != MLME_OPCH_SWITCH) + if (mlme_act != MLME_OPCH_SWITCH + && pmlmeext->bstart_bss == _TRUE) rtw_ap_mbid_bcn_en(padapter, padapter->vap_id); #endif } +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (MLME_IS_AP(padapter) && padapter->tbtx_capability == _TRUE) { + _set_timer(&pmlmeext->tbtx_token_dispatch_timer, 1); + RTW_INFO("Start token dispatch\n"); + } +#endif } int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) @@ -1906,7 +1951,7 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) u8 *pHT_info_ie = NULL; u16 cap, ht_cap = _FALSE; uint ie_len = 0; - int group_cipher, pairwise_cipher; + int group_cipher, pairwise_cipher, gmcs; u32 akm; u8 mfp_opt = MFP_NO; u8 channel, network_type; @@ -1931,6 +1976,7 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) /* ERP Information element */ /* Extended supported rates */ /* WPA/WPA2 */ + /* Radio Resource Management */ /* Wi-Fi Wireless Multimedia Extensions */ /* ht_capab, ht_oper */ /* WPS IE */ @@ -2035,13 +2081,15 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) /* wpa2 */ akm = 0; + gmcs = 0; group_cipher = 0; pairwise_cipher = 0; psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_; psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_; + psecuritypriv->akmp = 0; p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); if (p && ie_len > 0) { - if (rtw_parse_wpa2_ie(p, ie_len + 2, &group_cipher, &pairwise_cipher, &akm, &mfp_opt) == _SUCCESS) { + if (rtw_parse_wpa2_ie(p, ie_len + 2, &group_cipher, &pairwise_cipher, &gmcs, &akm, &mfp_opt, NULL) == _SUCCESS) { psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK; psecuritypriv->dot8021xalg = 1;/* psk, todo:802.1x */ @@ -2049,17 +2097,22 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) psecuritypriv->wpa2_group_cipher = group_cipher; psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher; + psecuritypriv->akmp = akm; #ifdef CONFIG_IOCTL_CFG80211 - /* - Kernel < v5.1, the auth_type set as NL80211_AUTHTYPE_AUTOMATIC - in cfg80211_rtw_start_ap(). - if the AKM SAE in the RSN IE, we have to update the auth_type for SAE - in rtw_check_beacon_data(). - */ - if (CHECK_BIT(WLAN_AKM_TYPE_SAE, akm)) - psecuritypriv->auth_type = NL80211_AUTHTYPE_SAE; -#endif + /** + * Kernel < v5.x, the auth_type set as + * NL80211_AUTHTYPE_AUTOMATIC in + * cfg80211_rtw_start_ap(). if the AKM SAE in the RSN + * IE, we have to update the auth_type for SAE in + * rtw_check_beacon_data() + */ + if (CHECK_BIT(WLAN_AKM_TYPE_SAE, akm)) { + RTW_INFO("%s: Auth type as SAE\n", __func__); + psecuritypriv->auth_type = MLME_AUTHTYPE_SAE; + psecuritypriv->auth_alg = WLAN_AUTH_SAE; + } +#endif /* CONFIG_IOCTL_CFG80211 */ #if 0 switch (group_cipher) { case WPA_CIPHER_NONE: @@ -2168,19 +2221,18 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) } -#ifdef CONFIG_RTW_MESH - if (MLME_IS_MESH(padapter)) { - /* MFP is mandatory for secure mesh */ - if (padapter->mesh_info.mesh_auth_id) - mfp_opt = MFP_REQUIRED; - } else -#endif if (mfp_opt == MFP_INVALID) { RTW_INFO(FUNC_ADPT_FMT" invalid MFP setting\n", FUNC_ADPT_ARG(padapter)); return _FAIL; } psecuritypriv->mfp_opt = mfp_opt; +#ifdef CONFIG_RTW_80211K + /* RRM */ + update_rm_cap(pbuf, padapter, len, _BEACON_IE_OFFSET_); + +#endif /* CONFIG_RTW_80211K */ + /* wmm */ ie_len = 0; pmlmepriv->qospriv.qos_option = 0; @@ -2220,11 +2272,12 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor = MAX_AMPDU_FACTOR_64K; struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p + 2); +#ifdef CONFIG_RTW_DEBUG if (0) { RTW_INFO(FUNC_ADPT_FMT" HT_CAP_IE from upper layer:\n", FUNC_ADPT_ARG(padapter)); dump_ht_cap_ie_content(RTW_DBGDUMP, p + 2, ie_len); } - +#endif /* CONFIG_RTW_DEBUG */ pHT_caps_ie = p; ht_cap = _TRUE; @@ -2320,11 +2373,12 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) #endif /* CONFIG_BEAMFORMING */ _rtw_memcpy(&pmlmepriv->htpriv.ht_cap, p + 2, ie_len); - +#ifdef CONFIG_RTW_DEBUG if (0) { RTW_INFO(FUNC_ADPT_FMT" HT_CAP_IE driver masked:\n", FUNC_ADPT_ARG(padapter)); dump_ht_cap_ie_content(RTW_DBGDUMP, p + 2, ie_len); } +#endif /* CONFIG_RTW_DEBUG */ } /* parsing HT_INFO_IE */ @@ -2692,12 +2746,15 @@ u8 rtw_ap_set_sta_key(_adapter *adapter, const u8 *addr, u8 alg, const u8 *key, goto exit; } - init_h2fwcmd_w_parm_no_rsp(cmd, param, _SetStaKey_CMD_); + init_h2fwcmd_w_parm_no_rsp(cmd, param, CMD_SET_STAKEY); _rtw_memcpy(param->addr, addr, ETH_ALEN); param->algorithm = alg; param->keyid = keyid; - _rtw_memcpy(param->key, key, 16); + if (!!(alg & _SEC_TYPE_256_)) + _rtw_memcpy(param->key, key, 32); + else + _rtw_memcpy(param->key, key, 16); param->gk = gk; res = rtw_enqueue_cmd(cmdpriv, cmd); @@ -2756,16 +2813,21 @@ static int rtw_ap_set_key(_adapter *padapter, u8 *key, u8 alg, int keyid, u8 set case _WEP104_: keylen = 13; break; + case _GCMP_256_: + case _CCMP_256_: + keylen = 32; + break; case _TKIP_: case _TKIP_WTMIC_: case _AES_: + case _GCMP_: default: keylen = 16; } _rtw_memcpy(&(psetkeyparm->key[0]), key, keylen); - pcmd->cmdcode = _SetKey_CMD_; + pcmd->cmdcode = CMD_SET_KEY; /*_SetKey_CMD_;*/ pcmd->parmbuf = (u8 *)psetkeyparm; pcmd->cmdsz = (sizeof(struct setkey_parm)); pcmd->rsp = NULL; @@ -3825,7 +3887,7 @@ u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reaso _enter_critical_bh(&psta->lock, &irqL); - psta->state &= ~(_FW_LINKED | WIFI_UNDER_KEY_HANDSHAKE); + psta->state &= ~(WIFI_ASOC_STATE | WIFI_UNDER_KEY_HANDSHAKE); #ifdef CONFIG_IOCTL_CFG80211 if ((psta->auth_len != 0) && (psta->pauth_frame != NULL)) { @@ -3833,10 +3895,19 @@ u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reaso psta->pauth_frame = NULL; psta->auth_len = 0; } + if (psta->passoc_req && psta->assoc_req_len > 0) { + rtw_mfree(psta->passoc_req , psta->assoc_req_len); + psta->passoc_req = NULL; + psta->assoc_req_len = 0; + } #endif /* CONFIG_IOCTL_CFG80211 */ _exit_critical_bh(&psta->lock, &irqL); if (!MLME_IS_MESH(padapter)) { + #ifdef CONFIG_RTW_WDS + rtw_wds_path_flush_by_nexthop(psta); + #endif + #ifdef CONFIG_IOCTL_CFG80211 #ifdef COMPAT_KERNEL_RELEASE rtw_cfg80211_indicate_sta_disassoc(padapter, psta->cmn.mac_addr, reason); @@ -3853,10 +3924,10 @@ u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reaso beacon_updated = bss_cap_update_on_sta_leave(padapter, psta); report_del_sta_event(padapter, psta->cmn.mac_addr, reason, enqueue, _FALSE); - + /* clear cam entry / key */ rtw_clearstakey_cmd(padapter, psta, enqueue); - + return beacon_updated; } @@ -3926,6 +3997,10 @@ int rtw_sta_flush(_adapter *padapter, bool enqueue) rtw_list_delete(&psta->asoc_list); pstapriv->asoc_list_cnt--; + #ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (psta->tbtx_enable) + pstapriv->tbtx_asoc_list_cnt--; + #endif STA_SET_MESH_PLINK(psta, NULL); stainfo_offset = rtw_stainfo_offset(pstapriv, psta); @@ -4006,7 +4081,7 @@ void sta_info_update(_adapter *padapter, struct sta_info *psta) /* called >= TSR LEVEL for USB or SDIO Interface*/ void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta) { - if (psta->state & _FW_LINKED) + if (psta->state & WIFI_ASOC_STATE) rtw_hal_update_ra_mask(psta); /* DM_RATR_STA_INIT */ } /* restore hw setting from sw data structures */ @@ -4060,7 +4135,7 @@ void rtw_ap_restore_network(_adapter *padapter) if (psta == NULL) RTW_INFO(FUNC_ADPT_FMT" sta_info is null\n", FUNC_ADPT_ARG(padapter)); - else if (psta->state & _FW_LINKED) { + else if (psta->state & WIFI_ASOC_STATE) { rtw_sta_media_status_rpt(padapter, psta, 1); Update_RA_Entry(padapter, psta); /* pairwise key */ @@ -4081,9 +4156,7 @@ void start_ap_mode(_adapter *padapter) struct sta_priv *pstapriv = &padapter->stapriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); -#ifdef CONFIG_CONCURRENT_MODE struct security_priv *psecuritypriv = &padapter->securitypriv; -#endif pmlmepriv->update_bcn = _FALSE; @@ -4120,13 +4193,16 @@ void start_ap_mode(_adapter *padapter) _rtw_memset(pmlmepriv->ext_capab_ie_data, 0, sizeof(pmlmepriv->ext_capab_ie_data)); pmlmepriv->ext_capab_ie_len = 0; -#ifdef CONFIG_CONCURRENT_MODE psecuritypriv->dot118021x_bmc_cam_id = INVALID_SEC_MAC_CAM_ID; -#endif for (i = 0 ; i < pstapriv->max_aid; i++) pstapriv->sta_aid[i] = NULL; +#ifdef CONFIG_RTW_WDS + if (MLME_IS_AP(padapter)) + rtw_wds_pathtbl_init(padapter); +#endif + psta = rtw_get_bcmc_stainfo(padapter); /*_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);*/ if (psta) @@ -4140,25 +4216,6 @@ void start_ap_mode(_adapter *padapter) } -void rtw_ap_bcmc_sta_flush(_adapter *padapter) -{ -#ifdef CONFIG_CONCURRENT_MODE - int cam_id = -1; - u8 *addr = adapter_mac_addr(padapter); - - cam_id = rtw_iface_bcmc_id_get(padapter); - if (cam_id != INVALID_SEC_MAC_CAM_ID) { - RTW_PRINT("clear group key for "ADPT_FMT" addr:"MAC_FMT", camid:%d\n", - ADPT_ARG(padapter), MAC_ARG(addr), cam_id); - clear_cam_entry(padapter, cam_id); - rtw_camid_free(padapter, cam_id); - rtw_iface_bcmc_id_set(padapter, INVALID_SEC_MAC_CAM_ID); /*init default value*/ - } -#else - invalidate_cam_all(padapter); -#endif -} - void stop_ap_mode(_adapter *padapter) { u8 self_action = MLME_ACTION_UNKNOWN; @@ -4193,6 +4250,8 @@ void stop_ap_mode(_adapter *padapter) rtw_dfs_rd_en_decision(padapter, self_action, 0); #endif + rtw_rfctl_update_op_mode(adapter_to_rfctl(padapter), BIT(padapter->iface_id), 0); + /* free scan queue */ rtw_free_network_queue(padapter, _TRUE); @@ -4201,7 +4260,6 @@ void stop_ap_mode(_adapter *padapter) #endif rtw_sta_flush(padapter, _TRUE); - rtw_ap_bcmc_sta_flush(padapter); /* free_assoc_sta_resources */ rtw_free_all_stainfo(padapter); @@ -4215,6 +4273,12 @@ void stop_ap_mode(_adapter *padapter) } pmlmepriv->ap_isolate = 0; +#ifdef CONFIG_RTW_WDS + adapter_set_use_wds(padapter, 0); +#endif +#ifdef CONFIG_RTW_MULTI_AP + padapter->multi_ap = 0; +#endif rtw_free_mlme_priv_ie_data(pmlmepriv); #ifdef CONFIG_SUPPORT_MULTI_BCN @@ -4261,6 +4325,10 @@ void stop_ap_mode(_adapter *padapter) rtw_btcoex_MediaStatusNotify(padapter, 0); /* disconnect */ #endif +#ifdef CONFIG_RTW_WDS + if (MLME_IS_AP(padapter)) + rtw_wds_pathtbl_unregister(padapter); +#endif } #endif /* CONFIG_NATIVEAP_MLME */ @@ -4401,7 +4469,7 @@ static u8 rtw_ap_update_chbw_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp int i; for (i = 0; i < dvobj->iface_nums; i++) { - if (!(ifbmp & BIT(i)) || &(dvobj->padapters) == NULL) + if (!(ifbmp & BIT(i)) || !dvobj->padapters[i]) continue; iface = dvobj->padapters[i]; @@ -4421,7 +4489,7 @@ static u8 rtw_ap_update_chbw_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp } for (i = 0; i < dvobj->iface_nums; i++) { - if (!(ifbmp & BIT(i)) || &(dvobj->padapters) == NULL) + if (!(ifbmp & BIT(i)) || !dvobj->padapters[i]) continue; iface = dvobj->padapters[i]; @@ -4473,7 +4541,7 @@ static u8 rtw_ap_ch_specific_chk(_adapter *adapter, u8 ch, u8 *bw, u8 *offset, c ret = _FAIL; goto exit; } - if (chset[ch_idx].ScanType == SCAN_PASSIVE) { + if (chset[ch_idx].flags & RTW_CHF_NO_IR) { RTW_WARN("%s ch:%u is passive\n", caller, ch); ret = _FAIL; goto exit; @@ -4521,7 +4589,7 @@ static bool rtw_ap_choose_chbw(_adapter *adapter, u8 sel_ch, u8 max_bw, u8 cur_c ) { ch_avail = rtw_choose_shortest_waiting_ch(rfctl, sel_ch, max_bw , ch, bw, offset - , RTW_CHF_2G | RTW_CHF_NON_DFS + , RTW_CHF_DFS, 0 , cur_ch, by_int_info, mesh_only); if (ch_avail == _TRUE) { RTW_INFO("%s choose 5G DFS channel for debug\n", caller); @@ -4530,29 +4598,29 @@ static bool rtw_ap_choose_chbw(_adapter *adapter, u8 sel_ch, u8 max_bw, u8 cur_c } if (rfctl->radar_detected - && rfctl->dfs_ch_sel_d_flags + && (rfctl->dfs_ch_sel_e_flags || rfctl->dfs_ch_sel_d_flags) ) { ch_avail = rtw_choose_shortest_waiting_ch(rfctl, sel_ch, max_bw , ch, bw, offset - , rfctl->dfs_ch_sel_d_flags + , rfctl->dfs_ch_sel_e_flags, rfctl->dfs_ch_sel_d_flags , cur_ch, by_int_info, mesh_only); if (ch_avail == _TRUE) { - RTW_INFO("%s choose with dfs_ch_sel_d_flags:0x%02x for debug\n" - , caller, rfctl->dfs_ch_sel_d_flags); + RTW_INFO("%s choose with dfs_ch_sel_ e_flags:0x%02x d_flags:0x%02x for debug\n" + , caller, rfctl->dfs_ch_sel_e_flags, rfctl->dfs_ch_sel_d_flags); goto exit; } } ch_avail = rtw_choose_shortest_waiting_ch(rfctl, sel_ch, max_bw , ch, bw, offset - , 0 + , 0, 0 , cur_ch, by_int_info, mesh_only); } else #endif /* defined(CONFIG_DFS_MASTER) */ { ch_avail = rtw_choose_shortest_waiting_ch(rfctl, sel_ch, max_bw , ch, bw, offset - , RTW_CHF_DFS + , 0, RTW_CHF_DFS , cur_ch, by_int_info, mesh_only); } #if defined(CONFIG_DFS_MASTER) @@ -4566,7 +4634,7 @@ exit: u8 rtw_ap_chbw_decision(_adapter *adapter, u8 ifbmp, u8 excl_ifbmp , s16 req_ch, s8 req_bw, s8 req_offset - , u8 *ch, u8 *bw, u8 *offset, u8 *chbw_allow) + , u8 *ch, u8 *bw, u8 *offset, u8 *chbw_allow, bool *set_u_ch) { struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); RT_CHANNEL_INFO *chset = adapter_to_chset(adapter); @@ -4583,13 +4651,14 @@ u8 rtw_ap_chbw_decision(_adapter *adapter, u8 ifbmp, u8 excl_ifbmp WLAN_BSSID_EX *network; struct mi_state mstate; struct mi_state mstate_others; - bool set_u_ch = _FALSE; u8 ifbmp_others = 0xFF & ~ifbmp & ~excl_ifbmp; u8 ifbmp_ch_changed = 0; bool ifbmp_all_mesh = 0; _adapter *iface; int i; + *set_u_ch = _FALSE; + #ifdef CONFIG_RTW_MESH for (i = 0; i < dvobj->iface_nums; i++) if ((ifbmp & BIT(i)) && dvobj->padapters) @@ -4692,7 +4761,7 @@ u8 rtw_ap_chbw_decision(_adapter *adapter, u8 ifbmp, u8 excl_ifbmp rtw_chset_sync_chbw(chset , &dec_ch[i], &dec_bw[i], &dec_offset[i] , &u_ch, &u_bw, &u_offset, 1, 0); - set_u_ch = _TRUE; + *set_u_ch = _TRUE; /* channel bw offset can be allowed, not need MCC */ *chbw_allow = _TRUE; @@ -4766,7 +4835,7 @@ u8 rtw_ap_chbw_decision(_adapter *adapter, u8 ifbmp, u8 excl_ifbmp , &u_ch, &u_bw, &u_offset, 1, 0); } - set_u_ch = _TRUE; + *set_u_ch = _TRUE; } else { /* autonomous decision */ @@ -4886,7 +4955,7 @@ update_bss_chbw: #endif } - set_u_ch = _TRUE; + *set_u_ch = _TRUE; } ifbmp_ch_changed = rtw_ap_update_chbw_by_ifbmp(dvobj, ifbmp @@ -4897,16 +4966,18 @@ update_bss_chbw: if (u_ch != 0) RTW_INFO("%s union:%u,%u,%u\n", __func__, u_ch, u_bw, u_offset); - if (rtw_mi_check_fwstate(adapter, _FW_UNDER_SURVEY)) { - /* scanning, leave ch setting to scan state machine */ - set_u_ch = _FALSE; - } - - if (set_u_ch == _TRUE) { + if (*set_u_ch == _TRUE) { + rtw_mi_update_union_chan_inf(adapter, u_ch, u_offset, u_bw); *ch = u_ch; *bw = u_bw; *offset = u_offset; } + + if (rtw_mi_check_fwstate(adapter, WIFI_UNDER_SURVEY)) { + /* scanning, leave ch setting to scan state machine */ + *set_u_ch = _FALSE; + } + exit: return ifbmp_ch_changed; } @@ -4933,7 +5004,7 @@ u8 rtw_ap_sta_states_check(_adapter *adapter) psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); plist = get_next(plist); - if (!(psta->state & _FW_LINKED)) { + if (!(psta->state & WIFI_ASOC_STATE)) { RTW_INFO(ADPT_FMT"- SoftAP/Mesh - sta under linking, its state = 0x%x\n", ADPT_ARG(adapter), psta->state); rst = _TRUE; break; @@ -5156,9 +5227,10 @@ u16 rtw_ap_parse_sta_security_ie(_adapter *adapter, struct sta_info *sta, struct struct security_priv *sec = &adapter->securitypriv; u8 *wpa_ie; int wpa_ie_len; - int group_cipher = 0, pairwise_cipher = 0; + int group_cipher = 0, pairwise_cipher = 0, gmcs = 0; u32 akm = 0; u8 mfp_opt = MFP_NO; + u8 spp_opt = 0; u16 status = _STATS_SUCCESSFUL_; sta->dot8021xalg = 0; @@ -5173,7 +5245,7 @@ u16 rtw_ap_parse_sta_security_ie(_adapter *adapter, struct sta_info *sta, struct wpa_ie = elems->rsn_ie; wpa_ie_len = elems->rsn_ie_len; - if (rtw_parse_wpa2_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, &akm, &mfp_opt) == _SUCCESS) { + if (rtw_parse_wpa2_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, &gmcs, &akm, &mfp_opt, &spp_opt) == _SUCCESS) { sta->dot8021xalg = 1;/* psk, todo:802.1x */ sta->wpa_psk |= BIT(1); @@ -5181,16 +5253,30 @@ u16 rtw_ap_parse_sta_security_ie(_adapter *adapter, struct sta_info *sta, struct sta->wpa2_pairwise_cipher = pairwise_cipher & sec->wpa2_pairwise_cipher; sta->akm_suite_type = akm; - if (MLME_IS_AP(adapter) && (CHECK_BIT(WLAN_AKM_TYPE_SAE, akm)) && (MFP_NO == mfp_opt)) + if (MLME_IS_AP(adapter) && (CHECK_BIT(WLAN_AKM_TYPE_SAE, akm)) && (MFP_NO == mfp_opt)) { status = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION; + goto exit; + } - if (!sta->wpa2_group_cipher) + if (MLME_IS_AP(adapter) && (!CHECK_BIT(sec->akmp, akm))) { + status = WLAN_STATUS_AKMP_NOT_VALID; + goto exit; + } + + if (!sta->wpa2_group_cipher) { status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; + goto exit; + } - if (!sta->wpa2_pairwise_cipher) + if (!sta->wpa2_pairwise_cipher) { status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; - } else + goto exit; + } + + } else { status = WLAN_STATUS_INVALID_IE; + goto exit; + } } else if ((sec->wpa_psk & BIT(0)) && elems->wpa_ie) { @@ -5204,18 +5290,36 @@ u16 rtw_ap_parse_sta_security_ie(_adapter *adapter, struct sta_info *sta, struct sta->wpa_group_cipher = group_cipher & sec->wpa_group_cipher; sta->wpa_pairwise_cipher = pairwise_cipher & sec->wpa_pairwise_cipher; - if (!sta->wpa_group_cipher) + if (!sta->wpa_group_cipher) { status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; + goto exit; + } - if (!sta->wpa_pairwise_cipher) + if (!sta->wpa_pairwise_cipher) { status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; - } else + goto exit; + } + } else { status = WLAN_STATUS_INVALID_IE; + goto exit; + } } else { wpa_ie = NULL; wpa_ie_len = 0; } + if (sec->dot11PrivacyAlgrthm != _NO_PRIVACY_) { + /*check if amsdu is allowed */ + if (rtw_check_amsdu_disable(adapter->registrypriv.amsdu_mode, spp_opt) == _TRUE) + sta->flags |= WLAN_STA_AMSDU_DISABLE; + } + + if ((sec->mfp_opt == MFP_REQUIRED && mfp_opt < MFP_OPTIONAL) + || (mfp_opt == MFP_REQUIRED && sec->mfp_opt < MFP_OPTIONAL) + ) { + status = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION; + goto exit; + } #ifdef CONFIG_RTW_MESH if (MLME_IS_MESH(adapter)) { @@ -5224,28 +5328,34 @@ u16 rtw_ap_parse_sta_security_ie(_adapter *adapter, struct sta_info *sta, struct sta->flags |= WLAN_STA_MFP; } else #endif - if ((sec->mfp_opt == MFP_REQUIRED && mfp_opt == MFP_NO) || mfp_opt == MFP_INVALID) - status = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION; - else if (sec->mfp_opt >= MFP_OPTIONAL && mfp_opt >= MFP_OPTIONAL) + if (sec->mfp_opt >= MFP_OPTIONAL && mfp_opt >= MFP_OPTIONAL) sta->flags |= WLAN_STA_MFP; +#ifdef CONFIG_IEEE80211W + if ((sta->flags & WLAN_STA_MFP) + && (sec->mfp_opt >= MFP_OPTIONAL && mfp_opt >= MFP_OPTIONAL) + && security_type_bip_to_gmcs(sec->dot11wCipher) != gmcs + ) { + status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; + goto exit; + } +#endif + #ifdef CONFIG_IOCTL_CFG80211 if (MLME_IS_AP(adapter) && - (sec->auth_type == NL80211_AUTHTYPE_SAE) && + (sec->auth_type == MLME_AUTHTYPE_SAE) && (CHECK_BIT(WLAN_AKM_TYPE_SAE, sta->akm_suite_type)) && (WLAN_AUTH_OPEN == sta->authalg)) { /* WPA3-SAE, PMK caching */ if (rtw_cached_pmkid(adapter, sta->cmn.mac_addr) == -1) { RTW_INFO("SAE: No PMKSA cache entry found\n"); status = WLAN_STATUS_INVALID_PMKID; + goto exit; } else { RTW_INFO("SAE: PMKSA cache entry found\n"); } } -#endif - - if (status != _STATS_SUCCESSFUL_) - goto exit; +#endif /* CONFIG_IOCTL_CFG80211 */ if (!MLME_IS_AP(adapter)) goto exit; @@ -5439,5 +5549,450 @@ exit: return; } -#endif /* CONFIG_AP_MODE */ + +void rtw_ap_parse_sta_multi_ap_ie(_adapter *adapter, struct sta_info *sta, u8 *ies, int ies_len) +{ + sta->flags &= ~WLAN_STA_MULTI_AP; + +#ifdef CONFIG_RTW_MULTI_AP + if (adapter->multi_ap + && (rtw_get_multi_ap_ie_ext(ies, ies_len) & MULTI_AP_BACKHAUL_STA) + ) { + if (adapter->multi_ap & MULTI_AP_BACKHAUL_BSS) /* with backhaul bss, enable WDS */ + sta->flags |= WLAN_STA_MULTI_AP | WLAN_STA_WDS; + else if (adapter->multi_ap & MULTI_AP_FRONTHAUL_BSS) /* fronthaul bss only */ + sta->flags |= WLAN_STA_MULTI_AP; + } +#endif +} + +#if CONFIG_RTW_AP_DATA_BMC_TO_UC +static bool rtw_ap_data_bmc_to_uc(_adapter *adapter + , const u8 *da, const u8 *sa, const u8 *ori_ta + , u16 os_qid, _list *b2u_list) +{ + struct sta_priv *stapriv = &adapter->stapriv; + struct xmit_priv *xmitpriv = &adapter->xmitpriv; + _irqL irqL; + _list *head, *list; + struct sta_info *sta; + char b2u_sta_id[NUM_STA]; + u8 b2u_sta_num = 0; + bool bmc_need = _FALSE; + int i; + + _enter_critical_bh(&stapriv->asoc_list_lock, &irqL); + head = &stapriv->asoc_list; + list = get_next(head); + + while ((rtw_end_of_queue_search(head, list)) == _FALSE) { + int stainfo_offset; + + sta = LIST_CONTAINOR(list, struct sta_info, asoc_list); + list = get_next(list); + + stainfo_offset = rtw_stainfo_offset(stapriv, sta); + if (stainfo_offset_valid(stainfo_offset)) + b2u_sta_id[b2u_sta_num++] = stainfo_offset; + } + _exit_critical_bh(&stapriv->asoc_list_lock, &irqL); + + if (!b2u_sta_num) + goto exit; + + for (i = 0; i < b2u_sta_num; i++) { + struct xmit_frame *b2uframe; + struct pkt_attrib *attrib; + + sta = rtw_get_stainfo_by_offset(stapriv, b2u_sta_id[i]); + if (!(sta->state & WIFI_ASOC_STATE) + || _rtw_memcmp(sta->cmn.mac_addr, sa, ETH_ALEN) == _TRUE + || (ori_ta && _rtw_memcmp(sta->cmn.mac_addr, ori_ta, ETH_ALEN) == _TRUE) + || is_broadcast_mac_addr(sta->cmn.mac_addr) + || is_zero_mac_addr(sta->cmn.mac_addr)) + continue; + + b2uframe = rtw_alloc_xmitframe(xmitpriv, os_qid); + if (!b2uframe) { + bmc_need = _TRUE; + break; + } + + attrib = &b2uframe->attrib; + + _rtw_memcpy(attrib->ra, sta->cmn.mac_addr, ETH_ALEN); + _rtw_memcpy(attrib->ta, adapter_mac_addr(adapter), ETH_ALEN); + #ifdef CONFIG_RTW_WDS + if (adapter_use_wds(adapter) && (sta->flags & WLAN_STA_WDS)) { + _rtw_memcpy(attrib->dst, da, ETH_ALEN); + attrib->wds = 1; + } else + #endif + _rtw_memcpy(attrib->dst, attrib->ra, ETH_ALEN); + _rtw_memcpy(attrib->src, sa, ETH_ALEN); + + rtw_list_insert_tail(&b2uframe->list, b2u_list); + } + +exit: + return bmc_need; +} + +void dump_ap_b2u_flags(void *sel, _adapter *adapter) +{ + RTW_PRINT_SEL(sel, "%4s %4s\n", "src", "fwd"); + RTW_PRINT_SEL(sel, "0x%02x 0x%02x\n", adapter->b2u_flags_ap_src, adapter->b2u_flags_ap_fwd); +} +#endif /* CONFIG_RTW_AP_DATA_BMC_TO_UC */ + +static int rtw_ap_nexthop_resolve(_adapter *adapter, struct xmit_frame *xframe) +{ + struct pkt_attrib *attrib = &xframe->attrib; + int ret = _SUCCESS; + +#ifdef CONFIG_RTW_WDS + if (adapter_use_wds(adapter) + && rtw_wds_nexthop_lookup(adapter, attrib->dst, attrib->ra) == 0 + ) { + if (_rtw_memcmp(attrib->dst, attrib->ra, ETH_ALEN) == _FALSE) + attrib->wds = 1; + } else +#endif + _rtw_memcpy(attrib->ra, attrib->dst, ETH_ALEN); + + return ret; +} + +int rtw_ap_addr_resolve(_adapter *adapter, u16 os_qid, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list) +{ + struct pkt_file pktfile; + struct ethhdr etherhdr; + struct pkt_attrib *attrib; + struct rtw_mesh_path *mpath = NULL, *mppath = NULL; + u8 is_da_mcast; + u8 addr4_need; +#if CONFIG_RTW_AP_DATA_BMC_TO_UC + bool bmc_need = _TRUE; +#endif + int res = _SUCCESS; + + _rtw_open_pktfile(pkt, &pktfile); + if (_rtw_pktfile_read(&pktfile, (u8 *)ðerhdr, ETH_HLEN) != ETH_HLEN) { + res = _FAIL; + goto exit; + } + + xframe->pkt = pkt; +#if CONFIG_RTW_AP_DATA_BMC_TO_UC + _rtw_init_listhead(b2u_list); +#endif + + is_da_mcast = IS_MCAST(etherhdr.h_dest); + if (is_da_mcast) { + #if CONFIG_RTW_AP_DATA_BMC_TO_UC + if (rtw_ap_src_b2u_policy_chk(adapter->b2u_flags_ap_src, etherhdr.h_dest) + && adapter->registrypriv.wifi_spec == 0 + && adapter->xmitpriv.free_xmitframe_cnt > (NR_XMITFRAME / 4) + ) { + bmc_need = rtw_ap_data_bmc_to_uc(adapter + , etherhdr.h_dest, etherhdr.h_source, NULL, os_qid, b2u_list); + if (bmc_need == _FALSE) { + res = RTW_BMC_NO_NEED; + goto exit; + } + } + #endif + } + + attrib = &xframe->attrib; + + _rtw_memcpy(attrib->dst, etherhdr.h_dest, ETH_ALEN); + _rtw_memcpy(attrib->src, etherhdr.h_source, ETH_ALEN); + _rtw_memcpy(attrib->ta, adapter_mac_addr(adapter), ETH_ALEN); + + if (is_da_mcast) + _rtw_memcpy(attrib->ra, attrib->dst, ETH_ALEN); + else + res = rtw_ap_nexthop_resolve(adapter, xframe); + +exit: + return res; +} + +int rtw_ap_rx_data_validate_hdr(_adapter *adapter, union recv_frame *rframe, struct sta_info **sta) +{ + struct sta_priv *stapriv = &adapter->stapriv; + struct rx_pkt_attrib *rattrib = &rframe->u.hdr.attrib; + u8 *whdr = get_recvframe_data(rframe); + u8 is_ra_bmc = 0; + sint ret = _FAIL; + + if (!(MLME_STATE(adapter) & WIFI_ASOC_STATE)) + goto exit; + + switch (rattrib->to_fr_ds) { + case 1: + if (IS_MCAST(GetAddr1Ptr(whdr))) + goto exit; + _rtw_memcpy(rattrib->ra, GetAddr1Ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->ta, get_addr2_ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->dst, GetAddr3Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */ + _rtw_memcpy(rattrib->src, get_addr2_ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->bssid, GetAddr1Ptr(whdr), ETH_ALEN); + break; + case 3: + is_ra_bmc = IS_MCAST(GetAddr1Ptr(whdr)) ? 1 : 0; + _rtw_memcpy(rattrib->ra, GetAddr1Ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->ta, get_addr2_ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->dst, GetAddr3Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */ + _rtw_memcpy(rattrib->src, GetAddr4Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */ + if (!is_ra_bmc) + _rtw_memcpy(rattrib->bssid, GetAddr1Ptr(whdr), ETH_ALEN); + break; + default: + ret = RTW_RX_HANDLED; /* don't count for drop */ + goto exit; + } + + *sta = rtw_get_stainfo(stapriv, rattrib->ta); + if (*sta == NULL) { + if (!is_ra_bmc && !IS_RADAR_DETECTED(adapter_to_rfctl(adapter))) { + #ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL + RTW_INFO(FUNC_ADPT_FMT" issue_deauth to "MAC_FMT" with reason(7), unknown TA\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(rattrib->ta)); + issue_deauth(adapter, rattrib->ta, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); + #endif + } + ret = RTW_RX_HANDLED; + goto exit; + } + +#ifdef CONFIG_RTW_WDS_AUTO_EN + if (rattrib->to_fr_ds == 3 && !(sta->flags & WLAN_STA_WDS)) + sta->flags |= WLAN_STA_WDS; +#endif + + process_pwrbit_data(adapter, rframe, *sta); + + if ((get_frame_sub_type(whdr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) + process_wmmps_data(adapter, rframe, *sta); + + if (get_frame_sub_type(whdr) & BIT(6)) { + /* No data, will not indicate to upper layer, temporily count it here */ + count_rx_stats(adapter, rframe, *sta); + ret = RTW_RX_HANDLED; + goto exit; + } + + ret = _SUCCESS; + +exit: + return ret; +} + +int rtw_ap_rx_msdu_act_check(union recv_frame *rframe + , const u8 *da, const u8 *sa + , u8 *msdu, enum rtw_rx_llc_hdl llc_hdl + , struct xmit_frame **fwd_frame, _list *b2u_list) +{ + _adapter *adapter = rframe->u.hdr.adapter; + struct rx_pkt_attrib *rattrib = &rframe->u.hdr.attrib; + struct rtw_wds_path *wpath; + u8 is_da_bmc = IS_MCAST(da); + u8 is_da_self = !is_da_bmc && _rtw_memcmp(da, adapter_mac_addr(adapter), ETH_ALEN); + u8 is_da_peer = 0; + int in_wds_tbl = 0; + u16 os_qid; + struct xmit_frame *xframe; + struct pkt_attrib *xattrib; + u8 fwd_ra[ETH_ALEN] = {0}; + int act = 0; +#if CONFIG_RTW_AP_DATA_BMC_TO_UC + bool bmc_need = _TRUE; +#endif + +#ifdef CONFIG_RTW_WDS + /* update/create wds info for SA, RA */ + if (adapter_use_wds(adapter) + && (rframe->u.hdr.psta->state & WIFI_ASOC_STATE) + && _rtw_memcmp(sa, rframe->u.hdr.psta->cmn.mac_addr, ETH_ALEN) == _FALSE + ) { + rtw_rcu_read_lock(); + wpath = rtw_wds_path_lookup(adapter, sa); + if (!wpath) + rtw_wds_path_add(adapter, sa, rframe->u.hdr.psta); + else { + rtw_wds_path_assign_nexthop(wpath, rframe->u.hdr.psta); + wpath->last_update = rtw_get_current_time(); + } + rtw_rcu_read_unlock(); + } +#endif + + /* SA is self, need no further process */ + if (_rtw_memcmp(sa, adapter_mac_addr(adapter), ETH_ALEN) == _TRUE) + goto exit; + + if (is_da_bmc) { + /* DA is bmc addr */ + act |= RTW_RX_MSDU_ACT_INDICATE; + if (adapter->mlmepriv.ap_isolate) + goto exit; + goto fwd_chk; + + } + + if (is_da_self) { + /* DA is self, indicate */ + act |= RTW_RX_MSDU_ACT_INDICATE; + goto exit; + } + + /* DA is not self */ +#ifdef CONFIG_RTW_WDS + if (adapter_use_wds(adapter)) + in_wds_tbl = rtw_wds_nexthop_lookup(adapter, da, fwd_ra) == 0; +#endif + if (!in_wds_tbl) + is_da_peer = rtw_get_stainfo(&adapter->stapriv, da) ? 1 : 0; + + if (in_wds_tbl || is_da_peer) { + /* DA is known (peer or can be forwarded by peer) */ + if (adapter->mlmepriv.ap_isolate) { + #if defined(DBG_RX_DROP_FRAME) + RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" DA("MAC_FMT") through peer, ap_isolate\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(da)); + #endif + goto exit; + } + goto fwd_chk; + } + + /* DA is unknown*/ + act |= RTW_RX_MSDU_ACT_INDICATE; + goto exit; + +fwd_chk: + + if (adapter->stapriv.asoc_list_cnt <= 1) + goto exit; + + os_qid = rtw_os_recv_select_queue(msdu, llc_hdl); + +#if CONFIG_RTW_AP_DATA_BMC_TO_UC + _rtw_init_listhead(b2u_list); + + if (is_da_bmc + && rtw_ap_fwd_b2u_policy_chk(adapter->b2u_flags_ap_fwd, da, rattrib->to_fr_ds == 3 && !IS_MCAST(rattrib->ra)) + && adapter->registrypriv.wifi_spec == 0 + && adapter->xmitpriv.free_xmitframe_cnt > (NR_XMITFRAME / 4) + ) { + bmc_need = rtw_ap_data_bmc_to_uc(adapter + , da, sa, rframe->u.hdr.psta->cmn.mac_addr + , os_qid, b2u_list); + } + + if (bmc_need == _TRUE) +#endif + { + xframe = rtw_alloc_xmitframe(&adapter->xmitpriv, os_qid); + if (!xframe) { + #ifdef DBG_TX_DROP_FRAME + RTW_INFO("DBG_TX_DROP_FRAME "FUNC_ADPT_FMT" rtw_alloc_xmitframe fail\n" + , FUNC_ADPT_ARG(adapter)); + #endif + goto exit; + } + + xattrib = &xframe->attrib; + + _rtw_memcpy(xattrib->dst, da, ETH_ALEN); + _rtw_memcpy(xattrib->src, sa, ETH_ALEN); + _rtw_memcpy(xattrib->ta, adapter_mac_addr(adapter), ETH_ALEN); + + #ifdef CONFIG_RTW_WDS + if (in_wds_tbl && _rtw_memcmp(da, fwd_ra, ETH_ALEN) == _FALSE) { + _rtw_memcpy(xattrib->ra, fwd_ra, ETH_ALEN); + xattrib->wds = 1; + } else + #endif + _rtw_memcpy(xattrib->ra, da, ETH_ALEN); + + *fwd_frame = xframe; + } + + act |= RTW_RX_MSDU_ACT_FORWARD; + +exit: + return act; +} + +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT +void rtw_issue_action_token_req(_adapter *padapter, struct sta_info *pstat) +{ + /* Token Request Format + Category code : 1 Byte + Action code : 1 Byte + Element field: 4 Bytes, the duration of data transmission requested for the station. + */ + + u8 val = 0x0; + u8 category = RTW_WLAN_CATEGORY_TBTX; + u32 tbtx_duration = TBTX_TX_DURATION*1000; + u8 *pframe; + unsigned short *fctrl; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct rtw_ieee80211_hdr *pwlanhdr; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network); + + + if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter))) + return; + + RTW_DBG("%s: %6ph\n", __FUNCTION__, pstat->cmn.mac_addr); + pmgntframe = alloc_mgtxmitframe(pxmitpriv); + if (pmgntframe == NULL) + return; + + /* update attribute */ + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + pattrib->rate = MGN_24M; /* issue action request using OFDM rate? 20190716 Bruce add */ + + _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); + + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + _rtw_memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->cmn.mac_addr, ETH_ALEN); + _rtw_memcpy((void *)get_addr2_ptr(pwlanhdr), adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + set_frame_sub_type(pframe, WIFI_ACTION); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(val), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&(tbtx_duration), &(pattrib->pktlen)); + + pattrib->last_txcmdsz = pattrib->pktlen; + padapter->stapriv.last_token_holder = pstat; + dump_mgntframe(padapter, pmgntframe); + +} +#endif /* CONFIG_RTW_TOKEN_BASED_XMIT */ +#endif /* CONFIG_AP_MODE */ diff --git a/core/rtw_beamforming.c b/core/rtw_beamforming.c index 205da38..8eda985 100644 --- a/core/rtw_beamforming.c +++ b/core/rtw_beamforming.c @@ -94,11 +94,13 @@ static void _get_sta_beamform_cap(PADAPTER adapter, struct sta_info *sta, u8 *sta_bf_cap, u8 *sounding_dim, u8 *comp_steering) { struct beamforming_info *info; + struct mlme_priv *mlme; struct ht_priv *ht; + u16 ht_bf_cap; #ifdef CONFIG_80211AC_VHT struct vht_priv *vht; + u16 vht_bf_cap; #endif /* CONFIG_80211AC_VHT */ - u16 bf_cap; *sta_bf_cap = 0; @@ -110,56 +112,123 @@ static void _get_sta_beamform_cap(PADAPTER adapter, struct sta_info *sta, #ifdef CONFIG_80211AC_VHT vht = &adapter->mlmepriv.vhtpriv; #endif /* CONFIG_80211AC_VHT */ + mlme = &adapter->mlmepriv; - if (is_supported_ht(sta->wireless_mode) == _TRUE) { - /* HT */ - bf_cap = ht->beamform_cap; + if (is_supported_ht(sta->wireless_mode) == _FALSE) + return; - if (TEST_FLAG(bf_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE)) { - info->beamforming_cap |= BEAMFORMEE_CAP_HT_EXPLICIT; - *sta_bf_cap |= BEAMFORMER_CAP_HT_EXPLICIT; - *sounding_dim = (bf_cap & BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP) >> 6; - } - if (TEST_FLAG(bf_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE)) { + /* HT */ + if (check_fwstate(mlme, WIFI_AP_STATE)) { + /* Get peer clinet's BF cap: the cap. is intersected with associated AP.*/ + ht_bf_cap = sta->htpriv.beamform_cap; + RTW_INFO("At AP state, peer sta's ht_bf_cap=0x%x\n", ht_bf_cap); + + if (TEST_FLAG(ht_bf_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE)) { info->beamforming_cap |= BEAMFORMER_CAP_HT_EXPLICIT; *sta_bf_cap |= BEAMFORMEE_CAP_HT_EXPLICIT; - *comp_steering = (bf_cap & BEAMFORMING_HT_BEAMFORMER_STEER_NUM) >> 4; + *comp_steering = (ht_bf_cap & BEAMFORMING_HT_BEAMFORMER_STEER_NUM) >> 4; + RTW_INFO("%s: we support BEAMFORMER_CAP_HT_EXPLICIT\n", __func__); + } + if (TEST_FLAG(ht_bf_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE)) { + info->beamforming_cap |= BEAMFORMEE_CAP_HT_EXPLICIT; + *sta_bf_cap |= BEAMFORMER_CAP_HT_EXPLICIT; + *sounding_dim = (ht_bf_cap & BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP) >> 6; + RTW_INFO("%s: we support BEAMFORMEE_CAP_HT_EXPLICIT\n", __func__); + } + } else { + /* Get adapter's BF Cap: the cap. is intersected with associated AP.*/ + ht_bf_cap = ht->beamform_cap; + RTW_INFO("At non-AP state, adapter's ht_bf_cap=0x%x\n", ht_bf_cap); + + if (TEST_FLAG(ht_bf_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE)) { + info->beamforming_cap |= BEAMFORMEE_CAP_HT_EXPLICIT; + *sta_bf_cap |= BEAMFORMER_CAP_HT_EXPLICIT; + *sounding_dim = (ht_bf_cap & BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP) >> 6; + RTW_INFO("%s: we support BEAMFORMEE_CAP_HT_EXPLICIT\n", __func__); + } + if (TEST_FLAG(ht_bf_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE)) { + info->beamforming_cap |= BEAMFORMER_CAP_HT_EXPLICIT; + *sta_bf_cap |= BEAMFORMEE_CAP_HT_EXPLICIT; + *comp_steering = (ht_bf_cap & BEAMFORMING_HT_BEAMFORMER_STEER_NUM) >> 4; + RTW_INFO("%s: we support BEAMFORMER_CAP_HT_EXPLICIT\n", __func__); } } #ifdef CONFIG_80211AC_VHT - if (is_supported_vht(sta->wireless_mode) == _TRUE) { - /* VHT */ - bf_cap = vht->beamform_cap; - /* We are SU Beamformee because the STA is SU Beamformer */ - if (TEST_FLAG(bf_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE)) { - info->beamforming_cap |= BEAMFORMEE_CAP_VHT_SU; - *sta_bf_cap |= BEAMFORMER_CAP_VHT_SU; + if (is_supported_vht(sta->wireless_mode) == _FALSE) + return; - /* We are MU Beamformee because the STA is MU Beamformer */ - if (TEST_FLAG(bf_cap, BEAMFORMING_VHT_MU_MIMO_STA_ENABLE)) { - info->beamforming_cap |= BEAMFORMEE_CAP_VHT_MU; - *sta_bf_cap |= BEAMFORMER_CAP_VHT_MU; - } + /* VHT */ + if (check_fwstate(mlme, WIFI_AP_STATE)) { + /* Get peer clinet's BF cap: the cap. is intersected with associated AP.*/ + vht_bf_cap = sta->vhtpriv.beamform_cap; + RTW_INFO("At AP state, peer sta's vht_bf_cap=0x%x\n", vht_bf_cap); - *sounding_dim = (bf_cap & BEAMFORMING_VHT_BEAMFORMEE_SOUND_DIM) >> 12; - } /* We are SU Beamformer because the STA is SU Beamformee */ - if (TEST_FLAG(bf_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE)) { + if (TEST_FLAG(vht_bf_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE)) { info->beamforming_cap |= BEAMFORMER_CAP_VHT_SU; *sta_bf_cap |= BEAMFORMEE_CAP_VHT_SU; + RTW_INFO("%s: we support BEAMFORMER_CAP_VHT_SU\n", __func__); /* We are MU Beamformer because the STA is MU Beamformee */ - if (TEST_FLAG(bf_cap, BEAMFORMING_VHT_MU_MIMO_AP_ENABLE)) { + if (TEST_FLAG(vht_bf_cap, BEAMFORMING_VHT_MU_MIMO_STA_ENABLE)) { info->beamforming_cap |= BEAMFORMER_CAP_VHT_MU; *sta_bf_cap |= BEAMFORMEE_CAP_VHT_MU; + RTW_INFO("%s: we support BEAMFORMER_CAP_VHT_MU\n", __func__); } - *comp_steering = (bf_cap & BEAMFORMING_VHT_BEAMFORMER_STS_CAP) >> 8; + *comp_steering = (vht_bf_cap & BEAMFORMING_VHT_BEAMFORMER_STS_CAP) >> 8; + } + /* We are SU Beamformee because the STA is SU Beamformer */ + if (TEST_FLAG(vht_bf_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE)) { + info->beamforming_cap |= BEAMFORMEE_CAP_VHT_SU; + *sta_bf_cap |= BEAMFORMER_CAP_VHT_SU; + RTW_INFO("%s: we support BEAMFORMEE_CAP_VHT_SU\n", __func__); + + /* The STA is MU Beamformer, but we(AP) should not be MU Beamformee */ + if (TEST_FLAG(vht_bf_cap, BEAMFORMING_VHT_MU_MIMO_AP_ENABLE)) { + RTW_WARN("%s: Associated STA should not be a MU BFer.\n", __func__); + } + + *sounding_dim = (vht_bf_cap & BEAMFORMING_VHT_BEAMFORMEE_SOUND_DIM) >> 12; + } + } else { + /* Get adapter's BF Cap: the cap. is intersected with associated AP.*/ + vht_bf_cap = vht->beamform_cap; + RTW_INFO("At non-AP state, adapter's vht_bf_cap=0x%x\n", vht_bf_cap); + + /* We are SU Beamformee */ + if (TEST_FLAG(vht_bf_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE)) { + info->beamforming_cap |= BEAMFORMEE_CAP_VHT_SU; + *sta_bf_cap |= BEAMFORMER_CAP_VHT_SU; + RTW_INFO("%s: we support BEAMFORMEE_CAP_VHT_SU\n", __func__); + + /* We are MU Beamformee */ + if (TEST_FLAG(vht_bf_cap, BEAMFORMING_VHT_MU_MIMO_STA_ENABLE)) { + info->beamforming_cap |= BEAMFORMEE_CAP_VHT_MU; + *sta_bf_cap |= BEAMFORMER_CAP_VHT_MU; + RTW_INFO("%s: we support BEAMFORMEE_CAP_VHT_MU\n", __func__); + } + + *sounding_dim = (vht_bf_cap & BEAMFORMING_VHT_BEAMFORMEE_SOUND_DIM) >> 12; + } + /* We are SU Beamformer */ + if (TEST_FLAG(vht_bf_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE)) { + info->beamforming_cap |= BEAMFORMER_CAP_VHT_SU; + *sta_bf_cap |= BEAMFORMEE_CAP_VHT_SU; + RTW_INFO("%s: we support BEAMFORMER_CAP_VHT_SU\n", __func__); + + /* We are MU Beamformer, but client should not be a MU Beamformer */ + if (TEST_FLAG(vht_bf_cap, BEAMFORMING_VHT_MU_MIMO_AP_ENABLE)) { + RTW_WARN("%s: non-AP state should not support MU BFer.\n", __func__); + } + + *comp_steering = (vht_bf_cap & BEAMFORMING_VHT_BEAMFORMER_STS_CAP) >> 8; } } #endif /* CONFIG_80211AC_VHT */ + } static u8 _send_ht_ndpa_packet(PADAPTER adapter, u8 *ra, enum channel_width bw) @@ -770,7 +839,7 @@ static void _sounding_handler(PADAPTER adapter) wait_cnt = 0; - if (check_fwstate(&adapter->mlmepriv, WIFI_SITE_MONITOR) == _TRUE) { + if (check_fwstate(&adapter->mlmepriv, WIFI_UNDER_SURVEY) == _TRUE) { RTW_INFO("%s: Sounding abort! scanning APs...\n", __FUNCTION__); info->sounding_running--; return; @@ -1386,6 +1455,10 @@ static void _beamforming_enter(PADAPTER adapter, void *p) __FUNCTION__, MAC_ARG(sta_copy->cmn.mac_addr)); return; } + + RTW_INFO("%s: find STA info for " MAC_FMT "\n", + __FUNCTION__, MAC_ARG(sta_copy->cmn.mac_addr)); + if (sta != sta_copy) { RTW_WARN("%s: Origin sta(fake)=%p realsta=%p for " MAC_FMT "\n", __FUNCTION__, sta_copy, sta, MAC_ARG(sta_copy->cmn.mac_addr)); @@ -1890,7 +1963,7 @@ u8 rtw_bf_cmd(PADAPTER adapter, s32 type, u8 *pbuf, s32 size, u8 enqueue) pdrvextra_cmd_parm->size = size; pdrvextra_cmd_parm->pbuf = wk_buf; - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, ph2c); @@ -2097,7 +2170,7 @@ u8 beamforming_wk_cmd(_adapter *padapter, s32 type, u8 *pbuf, s32 size, u8 enque pdrvextra_cmd_parm->size = size; pdrvextra_cmd_parm->pbuf = wk_buf; - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, ph2c); } else diff --git a/core/rtw_br_ext.c b/core/rtw_br_ext.c index b837aa7..9a0effd 100644 --- a/core/rtw_br_ext.c +++ b/core/rtw_br_ext.c @@ -17,6 +17,8 @@ #ifdef __KERNEL__ #include #include + #include + #include #include #include #endif @@ -167,6 +169,39 @@ static __inline__ void __nat25_generate_ipv4_network_addr(unsigned char *network } +static __inline__ void __nat25_generate_ipx_network_addr_with_node(unsigned char *networkAddr, + unsigned int *ipxNetAddr, unsigned char *ipxNodeAddr) +{ + memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + + networkAddr[0] = NAT25_IPX; + memcpy(networkAddr + 1, (unsigned char *)ipxNetAddr, 4); + memcpy(networkAddr + 5, ipxNodeAddr, 6); +} + + +static __inline__ void __nat25_generate_ipx_network_addr_with_socket(unsigned char *networkAddr, + unsigned int *ipxNetAddr, unsigned short *ipxSocketAddr) +{ + memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + + networkAddr[0] = NAT25_IPX; + memcpy(networkAddr + 1, (unsigned char *)ipxNetAddr, 4); + memcpy(networkAddr + 5, (unsigned char *)ipxSocketAddr, 2); +} + + +static __inline__ void __nat25_generate_apple_network_addr(unsigned char *networkAddr, + unsigned short *network, unsigned char *node) +{ + memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + + networkAddr[0] = NAT25_APPLE; + memcpy(networkAddr + 1, (unsigned char *)network, 2); + networkAddr[3] = *node; +} + + static __inline__ void __nat25_generate_pppoe_network_addr(unsigned char *networkAddr, unsigned char *ac_mac, unsigned short *sid) { @@ -294,6 +329,19 @@ static __inline__ int __nat25_network_hash(unsigned char *networkAddr) x = networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10]; + return x & (NAT25_HASH_SIZE - 1); + } else if (networkAddr[0] == NAT25_IPX) { + unsigned long x; + + x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ + networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10]; + + return x & (NAT25_HASH_SIZE - 1); + } else if (networkAddr[0] == NAT25_APPLE) { + unsigned long x; + + x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3]; + return x & (NAT25_HASH_SIZE - 1); } else if (networkAddr[0] == NAT25_PPPOE) { unsigned long x; @@ -841,6 +889,227 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) } } + /*---------------------------------------------------*/ + /* Handle IPX and Apple Talk frame */ + /*---------------------------------------------------*/ + else if ((protocol == __constant_htons(ETH_P_IPX)) || + (protocol == __constant_htons(ETH_P_ATALK)) || + (protocol == __constant_htons(ETH_P_AARP))) { + unsigned char ipx_header[2] = {0xFF, 0xFF}; + struct ipxhdr *ipx = NULL; + struct elapaarp *ea = NULL; + struct ddpehdr *ddp = NULL; + unsigned char *framePtr = skb->data + ETH_HLEN; + + if (protocol == __constant_htons(ETH_P_IPX)) { + RTW_INFO("NAT25: Protocol=IPX (Ethernet II)\n"); + ipx = (struct ipxhdr *)framePtr; + } else { /* if(protocol <= __constant_htons(ETH_FRAME_LEN)) */ + if (!memcmp(ipx_header, framePtr, 2)) { + RTW_INFO("NAT25: Protocol=IPX (Ethernet 802.3)\n"); + ipx = (struct ipxhdr *)framePtr; + } else { + unsigned char ipx_8022_type = 0xE0; + unsigned char snap_8022_type = 0xAA; + + if (*framePtr == snap_8022_type) { + unsigned char ipx_snap_id[5] = {0x0, 0x0, 0x0, 0x81, 0x37}; /* IPX SNAP ID */ + unsigned char aarp_snap_id[5] = {0x00, 0x00, 0x00, 0x80, 0xF3}; /* Apple Talk AARP SNAP ID */ + unsigned char ddp_snap_id[5] = {0x08, 0x00, 0x07, 0x80, 0x9B}; /* Apple Talk DDP SNAP ID */ + + framePtr += 3; /* eliminate the 802.2 header */ + + if (!memcmp(ipx_snap_id, framePtr, 5)) { + framePtr += 5; /* eliminate the SNAP header */ + + RTW_INFO("NAT25: Protocol=IPX (Ethernet SNAP)\n"); + ipx = (struct ipxhdr *)framePtr; + } else if (!memcmp(aarp_snap_id, framePtr, 5)) { + framePtr += 5; /* eliminate the SNAP header */ + + ea = (struct elapaarp *)framePtr; + } else if (!memcmp(ddp_snap_id, framePtr, 5)) { + framePtr += 5; /* eliminate the SNAP header */ + + ddp = (struct ddpehdr *)framePtr; + } else { + DEBUG_WARN("NAT25: Protocol=Ethernet SNAP %02x%02x%02x%02x%02x\n", framePtr[0], + framePtr[1], framePtr[2], framePtr[3], framePtr[4]); + return -1; + } + } else if (*framePtr == ipx_8022_type) { + framePtr += 3; /* eliminate the 802.2 header */ + + if (!memcmp(ipx_header, framePtr, 2)) { + RTW_INFO("NAT25: Protocol=IPX (Ethernet 802.2)\n"); + ipx = (struct ipxhdr *)framePtr; + } else + return -1; + } + } + } + + /* IPX */ + if (ipx != NULL) { + switch (method) { + case NAT25_CHECK: + if (!memcmp(skb->data + ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) { + RTW_INFO("NAT25: Check IPX skb_copy\n"); + return 0; + } + return -1; + + case NAT25_INSERT: { + RTW_INFO("NAT25: Insert IPX, Dest=%08x,%02x%02x%02x%02x%02x%02x,%04x Source=%08x,%02x%02x%02x%02x%02x%02x,%04x\n", + ipx->ipx_dest.net, + ipx->ipx_dest.node[0], + ipx->ipx_dest.node[1], + ipx->ipx_dest.node[2], + ipx->ipx_dest.node[3], + ipx->ipx_dest.node[4], + ipx->ipx_dest.node[5], + ipx->ipx_dest.sock, + ipx->ipx_source.net, + ipx->ipx_source.node[0], + ipx->ipx_source.node[1], + ipx->ipx_source.node[2], + ipx->ipx_source.node[3], + ipx->ipx_source.node[4], + ipx->ipx_source.node[5], + ipx->ipx_source.sock); + + if (!memcmp(skb->data + ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) { + RTW_INFO("NAT25: Use IPX Net, and Socket as network addr\n"); + + __nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_source.net, &ipx->ipx_source.sock); + + /* change IPX source node addr to wlan STA address */ + memcpy(ipx->ipx_source.node, GET_MY_HWADDR(priv), ETH_ALEN); + } else + __nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_source.net, ipx->ipx_source.node); + + __nat25_db_network_insert(priv, skb->data + ETH_ALEN, networkAddr); + + __nat25_db_print(priv); + } + return 0; + + case NAT25_LOOKUP: { + if (!memcmp(GET_MY_HWADDR(priv), ipx->ipx_dest.node, ETH_ALEN)) { + RTW_INFO("NAT25: Lookup IPX, Modify Destination IPX Node addr\n"); + + __nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_dest.net, &ipx->ipx_dest.sock); + + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + + /* replace IPX destination node addr with Lookup destination MAC addr */ + memcpy(ipx->ipx_dest.node, skb->data, ETH_ALEN); + } else { + __nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_dest.net, ipx->ipx_dest.node); + + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + } + } + return 0; + + default: + return -1; + } + } + + /* AARP */ + else if (ea != NULL) { + /* Sanity check fields. */ + if (ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN) { + DEBUG_WARN("NAT25: Appletalk AARP Sanity check fail!\n"); + return -1; + } + + switch (method) { + case NAT25_CHECK: + return 0; + + case NAT25_INSERT: { + /* change to AARP source mac address to wlan STA address */ + memcpy(ea->hw_src, GET_MY_HWADDR(priv), ETH_ALEN); + + RTW_INFO("NAT25: Insert AARP, Source=%d,%d Destination=%d,%d\n", + ea->pa_src_net, + ea->pa_src_node, + ea->pa_dst_net, + ea->pa_dst_node); + + __nat25_generate_apple_network_addr(networkAddr, &ea->pa_src_net, &ea->pa_src_node); + + __nat25_db_network_insert(priv, skb->data + ETH_ALEN, networkAddr); + + __nat25_db_print(priv); + } + return 0; + + case NAT25_LOOKUP: { + RTW_INFO("NAT25: Lookup AARP, Source=%d,%d Destination=%d,%d\n", + ea->pa_src_net, + ea->pa_src_node, + ea->pa_dst_net, + ea->pa_dst_node); + + __nat25_generate_apple_network_addr(networkAddr, &ea->pa_dst_net, &ea->pa_dst_node); + + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + + /* change to AARP destination mac address to Lookup result */ + memcpy(ea->hw_dst, skb->data, ETH_ALEN); + } + return 0; + + default: + return -1; + } + } + + /* DDP */ + else if (ddp != NULL) { + switch (method) { + case NAT25_CHECK: + return -1; + + case NAT25_INSERT: { + RTW_INFO("NAT25: Insert DDP, Source=%d,%d Destination=%d,%d\n", + ddp->deh_snet, + ddp->deh_snode, + ddp->deh_dnet, + ddp->deh_dnode); + + __nat25_generate_apple_network_addr(networkAddr, &ddp->deh_snet, &ddp->deh_snode); + + __nat25_db_network_insert(priv, skb->data + ETH_ALEN, networkAddr); + + __nat25_db_print(priv); + } + return 0; + + case NAT25_LOOKUP: { + RTW_INFO("NAT25: Lookup DDP, Source=%d,%d Destination=%d,%d\n", + ddp->deh_snet, + ddp->deh_snode, + ddp->deh_dnet, + ddp->deh_dnode); + + __nat25_generate_apple_network_addr(networkAddr, &ddp->deh_dnet, &ddp->deh_dnode); + + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + } + return 0; + + default: + return -1; + } + } + + return -1; + } + /*---------------------------------------------------*/ /* Handle PPPoE frame */ /*---------------------------------------------------*/ diff --git a/core/rtw_btcoex.c b/core/rtw_btcoex.c index f459c46..5081cdd 100644 --- a/core/rtw_btcoex.c +++ b/core/rtw_btcoex.c @@ -83,7 +83,7 @@ void rtw_btcoex_ScanNotify(PADAPTER padapter, u8 type) if (_FALSE == type) { #ifdef CONFIG_CONCURRENT_MODE - if (rtw_mi_buddy_check_fwstate(padapter, WIFI_SITE_MONITOR)) + if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_SURVEY)) return; #endif @@ -178,6 +178,17 @@ void rtw_btcoex_IQKNotify(PADAPTER padapter, u8 state) hal_btcoex_IQKNotify(padapter, state); } +void rtw_btcoex_WLRFKNotify(PADAPTER padapter, u8 path, u8 type, u8 state) +{ + PHAL_DATA_TYPE pHalData; + + pHalData = GET_HAL_DATA(padapter); + if (_FALSE == pHalData->EEPROMBluetoothCoexist) + return; + + hal_btcoex_WLRFKNotify(padapter, path, type, state); +} + void rtw_btcoex_BtInfoNotify(PADAPTER padapter, u8 length, u8 *tmpBuf) { PHAL_DATA_TYPE pHalData; @@ -315,6 +326,11 @@ void rtw_btcoex_SetManualControl(PADAPTER padapter, u8 manual) hal_btcoex_SetManualControl(padapter, _FALSE); } +void rtw_btcoex_set_policy_control(PADAPTER padapter, u8 btc_policy) +{ + hal_btcoex_set_policy_control(padapter, btc_policy); +} + u8 rtw_btcoex_1Ant(PADAPTER padapter) { return hal_btcoex_1Ant(padapter); @@ -577,7 +593,7 @@ u8 rtw_btcoex_btinfo_cmd(_adapter *adapter, u8 *buf, u16 len) _rtw_memcpy(btinfo, buf, len); - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, ph2c); @@ -1468,9 +1484,7 @@ u8 rtw_btcoex_sendmsgbysocket(_adapter *padapter, u8 *msg, u8 msg_size, bool for { u8 error; struct msghdr udpmsg; - #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) mm_segment_t oldfs; - #endif struct iovec iov; struct bt_coex_info *pcoex_info = &padapter->coex_info; @@ -1500,19 +1514,15 @@ u8 rtw_btcoex_sendmsgbysocket(_adapter *padapter, u8 *msg, u8 msg_size, bool for udpmsg.msg_control = NULL; udpmsg.msg_controllen = 0; udpmsg.msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL; - #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) oldfs = get_fs(); set_fs(KERNEL_DS); - #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) error = sock_sendmsg(pcoex_info->udpsock, &udpmsg); #else error = sock_sendmsg(pcoex_info->udpsock, &udpmsg, msg_size); #endif - #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) set_fs(oldfs); - #endif if (error < 0) { RTW_INFO("Error when sendimg msg, error:%d\n", error); return _FAIL; diff --git a/core/rtw_chplan.c b/core/rtw_chplan.c index 5d7754f..82b3671 100644 --- a/core/rtw_chplan.c +++ b/core/rtw_chplan.c @@ -16,105 +16,9 @@ #include -#define RTW_DOMAIN_MAP_VER "46" -#define RTW_DOMAIN_MAP_M_VER "f" -#define RTW_COUNTRY_MAP_VER "25" - -enum rtw_rd_2g { - RTW_RD_2G_WORLD = 0, /* Worldwide 13 */ - RTW_RD_2G_ETSI1 = 1, /* Europe */ - RTW_RD_2G_FCC1 = 2, /* US */ - RTW_RD_2G_MKK1 = 3, /* Japan */ - RTW_RD_2G_ETSI2 = 4, /* France */ - RTW_RD_2G_GLOBAL = 5, /* 2G Global (include Ch14) */ - RTW_RD_2G_MKK2 = 6, /* Japan */ - RTW_RD_2G_FCC2 = 7, /* US */ - RTW_RD_2G_NULL = 8, - RTW_RD_2G_IC1 = 9, /* Canada */ - RTW_RD_2G_WORLD1 = 10, /* Worldwide 11 */ - RTW_RD_2G_KCC1 = 11, /* Korea */ - RTW_RD_2G_IC2 = 12, /* Canada */ - - RTW_RD_2G_MAX, -}; - -enum rtw_rd_5g { - RTW_RD_5G_NULL = 0, /* */ - RTW_RD_5G_ETSI1 = 1, /* Europe */ - RTW_RD_5G_ETSI2 = 2, /* Australia, New Zealand */ - RTW_RD_5G_ETSI3 = 3, /* Russia */ - RTW_RD_5G_FCC1 = 4, /* US */ - RTW_RD_5G_FCC2 = 5, /* FCC w/o DFS Channels */ - RTW_RD_5G_FCC3 = 6, /* Bolivia, Chile, El Salvador, Venezuela */ - RTW_RD_5G_FCC4 = 7, /* Venezuela */ - RTW_RD_5G_FCC5 = 8, /* China */ - RTW_RD_5G_FCC6 = 9, /* */ - RTW_RD_5G_FCC7 = 10, /* US(w/o Weather radar) */ - RTW_RD_5G_IC1 = 11, /* Canada(w/o Weather radar) */ - RTW_RD_5G_KCC1 = 12, /* Korea */ - RTW_RD_5G_MKK1 = 13, /* Japan */ - RTW_RD_5G_MKK2 = 14, /* Japan (W52, W53) */ - RTW_RD_5G_MKK3 = 15, /* Japan (W56) */ - RTW_RD_5G_NCC1 = 16, /* Taiwan, (w/o Weather radar) */ - RTW_RD_5G_NCC2 = 17, /* Taiwan, Band2, Band4 */ - RTW_RD_5G_NCC3 = 18, /* Taiwan w/o DFS, Band4 only */ - RTW_RD_5G_ETSI4 = 19, /* Europe w/o DFS, Band1 only */ - RTW_RD_5G_ETSI5 = 20, /* Australia, New Zealand(w/o Weather radar) */ - RTW_RD_5G_FCC8 = 21, /* Latin America */ - RTW_RD_5G_ETSI6 = 22, /* Israel, Bahrain, Egypt, India, China, Malaysia */ - RTW_RD_5G_ETSI7 = 23, /* China */ - RTW_RD_5G_ETSI8 = 24, /* Jordan */ - RTW_RD_5G_ETSI9 = 25, /* Lebanon */ - RTW_RD_5G_ETSI10 = 26, /* Qatar */ - RTW_RD_5G_ETSI11 = 27, /* Russia */ - RTW_RD_5G_NCC4 = 28, /* Taiwan, (w/o Weather radar) */ - RTW_RD_5G_ETSI12 = 29, /* Indonesia */ - RTW_RD_5G_FCC9 = 30, /* (w/o Weather radar) */ - RTW_RD_5G_ETSI13 = 31, /* (w/o Weather radar) */ - RTW_RD_5G_FCC10 = 32, /* Argentina(w/o Weather radar) */ - RTW_RD_5G_MKK4 = 33, /* Japan (W52) */ - RTW_RD_5G_ETSI14 = 34, /* Russia */ - RTW_RD_5G_FCC11 = 35, /* US(include CH144) */ - RTW_RD_5G_ETSI15 = 36, /* Malaysia */ - RTW_RD_5G_MKK5 = 37, /* Japan */ - RTW_RD_5G_ETSI16 = 38, /* Europe */ - RTW_RD_5G_ETSI17 = 39, /* Europe */ - RTW_RD_5G_FCC12 = 40, /* FCC */ - RTW_RD_5G_FCC13 = 41, /* FCC */ - RTW_RD_5G_FCC14 = 42, /* FCC w/o Weather radar(w/o 5600~5650MHz) */ - RTW_RD_5G_FCC15 = 43, /* FCC w/o Band3 */ - RTW_RD_5G_FCC16 = 44, /* FCC w/o Band3 */ - RTW_RD_5G_ETSI18 = 45, /* ETSI w/o DFS Band2&3 */ - RTW_RD_5G_ETSI19 = 46, /* Europe */ - RTW_RD_5G_FCC17 = 47, /* FCC w/o Weather radar(w/o 5600~5650MHz) */ - RTW_RD_5G_ETSI20 = 48, /* Europe */ - RTW_RD_5G_IC2 = 49, /* Canada(w/o Weather radar), include ch144 */ - RTW_RD_5G_ETSI21 = 50, /* Australia, New Zealand(w/o Weather radar) */ - RTW_RD_5G_FCC18 = 51, /* */ - RTW_RD_5G_WORLD = 52, /* Worldwide */ - RTW_RD_5G_CHILE1 = 53, /* Chile */ - RTW_RD_5G_ACMA1 = 54, /* Australia, New Zealand (w/o Weather radar) (w/o Ch120~Ch128) */ - RTW_RD_5G_WORLD1 = 55, /* 5G Worldwide Band1&2 */ - RTW_RD_5G_CHILE2 = 56, /* Chile (Band2,Band3) */ - RTW_RD_5G_KCC2 = 57, /* Korea (New standard) */ - RTW_RD_5G_KCC3 = 58, /* Korea (2018 Dec 05 New standard, include ch144) */ - RTW_RD_5G_MKK6 = 59, /* Japan */ - RTW_RD_5G_MKK7 = 60, /* Japan */ - RTW_RD_5G_MKK8 = 61, /* Japan */ - RTW_RD_5G_MEX1 = 62, /* Mexico */ - RTW_RD_5G_ETSI22 = 63, /* Europe */ - RTW_RD_5G_MKK9 = 64, /* Japan */ - RTW_RD_5G_FCC19 = 65, /* FCC */ - RTW_RD_5G_FCC20 = 66, /* FCC w/o Band3 */ - RTW_RD_5G_FCC21 = 67, /* FCC */ - RTW_RD_5G_ETSI23 = 68, /* Indonesia */ - RTW_RD_5G_ETSI24 = 69, /* Indonesia */ - RTW_RD_5G_ETSI25 = 70, /* China */ - RTW_RD_5G_MKK10 = 71, /* Japan */ - RTW_RD_5G_ETSI26 = 72, /* Singapore */ - - RTW_RD_5G_MAX, -}; +#define RTW_DOMAIN_MAP_VER "54" +#define RTW_DOMAIN_MAP_M_VER "g" +#define RTW_COUNTRY_MAP_VER "27" struct ch_list_t { u8 *len_ch_attr; @@ -137,122 +41,167 @@ struct ch_list_t { #define CH_LIST_CH(_ch_list, _i) (_ch_list.len_ch_attr[_i + 1]) #define CH_LIST_ATTRIB(_ch_list) (_ch_list.len_ch_attr[CH_LIST_LEN(_ch_list) + 1]) -struct chplan_ent_t { - u8 rd_2g; -#if CONFIG_IEEE80211_BAND_5GHZ - u8 rd_5g; -#endif - u8 regd; /* value of REGULATION_TXPWR_LMT */ +enum rtw_chd_2g { + RTW_CHD_2G_00 = 0, + RTW_CHD_2G_01 = 1, + RTW_CHD_2G_02 = 2, + RTW_CHD_2G_03 = 3, + RTW_CHD_2G_04 = 4, + RTW_CHD_2G_05 = 5, + RTW_CHD_2G_06 = 6, + + RTW_CHD_2G_MAX, + RTW_CHD_2G_NULL = RTW_CHD_2G_00, +}; + +enum rtw_chd_5g { + RTW_CHD_5G_00 = 0, + RTW_CHD_5G_01 = 1, + RTW_CHD_5G_02 = 2, + RTW_CHD_5G_03 = 3, + RTW_CHD_5G_04 = 4, + RTW_CHD_5G_05 = 5, + RTW_CHD_5G_06 = 6, + RTW_CHD_5G_07 = 7, + RTW_CHD_5G_08 = 8, + RTW_CHD_5G_09 = 9, + RTW_CHD_5G_10 = 10, + RTW_CHD_5G_11 = 11, + RTW_CHD_5G_12 = 12, + RTW_CHD_5G_13 = 13, + RTW_CHD_5G_14 = 14, + RTW_CHD_5G_15 = 15, + RTW_CHD_5G_16 = 16, + RTW_CHD_5G_17 = 17, + RTW_CHD_5G_18 = 18, + RTW_CHD_5G_19 = 19, + RTW_CHD_5G_20 = 20, + RTW_CHD_5G_21 = 21, + RTW_CHD_5G_22 = 22, + RTW_CHD_5G_23 = 23, + RTW_CHD_5G_24 = 24, + RTW_CHD_5G_25 = 25, + RTW_CHD_5G_26 = 26, + RTW_CHD_5G_27 = 27, + RTW_CHD_5G_28 = 28, + RTW_CHD_5G_29 = 29, + RTW_CHD_5G_30 = 30, + RTW_CHD_5G_31 = 31, + RTW_CHD_5G_32 = 32, + RTW_CHD_5G_33 = 33, + RTW_CHD_5G_34 = 34, + RTW_CHD_5G_35 = 35, + RTW_CHD_5G_36 = 36, + RTW_CHD_5G_37 = 37, + RTW_CHD_5G_38 = 38, + RTW_CHD_5G_39 = 39, + RTW_CHD_5G_40 = 40, + RTW_CHD_5G_41 = 41, + RTW_CHD_5G_42 = 42, + RTW_CHD_5G_43 = 43, + RTW_CHD_5G_44 = 44, + RTW_CHD_5G_45 = 45, + RTW_CHD_5G_46 = 46, + RTW_CHD_5G_47 = 47, + RTW_CHD_5G_48 = 48, + RTW_CHD_5G_49 = 49, + RTW_CHD_5G_50 = 50, + RTW_CHD_5G_51 = 51, + + RTW_CHD_5G_MAX, + RTW_CHD_5G_NULL = RTW_CHD_5G_00, +}; + +static const struct ch_list_t rtw_channel_def_2g[] = { + /* 0, RTW_CHD_2G_00 */ CH_LIST_ENT(0, 0), + /* 1, RTW_CHD_2G_01 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, CLA_2G_12_14_PASSIVE), + /* 2, RTW_CHD_2G_02 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0), + /* 3, RTW_CHD_2G_03 */ CH_LIST_ENT(11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0), + /* 4, RTW_CHD_2G_04 */ CH_LIST_ENT(14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0), + /* 5, RTW_CHD_2G_05 */ CH_LIST_ENT(4, 10, 11, 12, 13, 0), + /* 6, RTW_CHD_2G_06 */ CH_LIST_ENT(14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, CLA_2G_12_14_PASSIVE), }; #if CONFIG_IEEE80211_BAND_5GHZ -#define CHPLAN_ENT(i2g, i5g, regd) {i2g, i5g, regd} -#else -#define CHPLAN_ENT(i2g, i5g, regd) {i2g, regd} -#endif - -#define CHPLAN_ENT_NOT_DEFINED CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW) - -static const struct ch_list_t RTW_ChannelPlan2G[] = { - /* 0, RTW_RD_2G_WORLD */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, CLA_2G_12_14_PASSIVE), - /* 1, RTW_RD_2G_ETSI1 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0), - /* 2, RTW_RD_2G_FCC1 */ CH_LIST_ENT(11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0), - /* 3, RTW_RD_2G_MKK1 */ CH_LIST_ENT(14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0), - /* 4, RTW_RD_2G_ETSI2 */ CH_LIST_ENT(4, 10, 11, 12, 13, 0), - /* 5, RTW_RD_2G_GLOBAL */ CH_LIST_ENT(14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, CLA_2G_12_14_PASSIVE), - /* 6, RTW_RD_2G_MKK2 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0), - /* 7, RTW_RD_2G_FCC2 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0), - /* 8, RTW_RD_2G_NULL */ CH_LIST_ENT(0, 0), - /* 9, RTW_RD_2G_IC1 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0), - /* 10, RTW_RD_2G_WORLD1 */ CH_LIST_ENT(11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0), - /* 11, RTW_RD_2G_KCC1 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0), - /* 12, RTW_RD_2G_IC2 */ CH_LIST_ENT(11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0), -}; - -#if CONFIG_IEEE80211_BAND_5GHZ -static const struct ch_list_t RTW_ChannelPlan5G[] = { - /* 0, RTW_RD_5G_NULL */ CH_LIST_ENT(0, 0), - /* 1, RTW_RD_5G_ETSI1 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 2, RTW_RD_5G_ETSI2 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 3, RTW_RD_5G_ETSI3 */ CH_LIST_ENT(22, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 4, RTW_RD_5G_FCC1 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 5, RTW_RD_5G_FCC2 */ CH_LIST_ENT(9, 36, 40, 44, 48, 149, 153, 157, 161, 165, 0), - /* 6, RTW_RD_5G_FCC3 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B2_DFS), - /* 7, RTW_RD_5G_FCC4 */ CH_LIST_ENT(12, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, CLA_5G_B2_DFS), - /* 8, RTW_RD_5G_FCC5 */ CH_LIST_ENT(5, 149, 153, 157, 161, 165, 0), - /* 9, RTW_RD_5G_FCC6 */ CH_LIST_ENT(8, 36, 40, 44, 48, 52, 56, 60, 64, CLA_5G_B2_DFS), - /* 10, RTW_RD_5G_FCC7 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 11, RTW_RD_5G_IC1 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 12, RTW_RD_5G_KCC1 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 13, RTW_RD_5G_MKK1 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 14, RTW_RD_5G_MKK2 */ CH_LIST_ENT(8, 36, 40, 44, 48, 52, 56, 60, 64, CLA_5G_B2_DFS), - /* 15, RTW_RD_5G_MKK3 */ CH_LIST_ENT(11, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, CLA_5G_B3_DFS), - /* 16, RTW_RD_5G_NCC1 */ CH_LIST_ENT(16, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 17, RTW_RD_5G_NCC2 */ CH_LIST_ENT(8, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B2_DFS), - /* 18, RTW_RD_5G_NCC3 */ CH_LIST_ENT(5, 149, 153, 157, 161, 165, 0), - /* 19, RTW_RD_5G_ETSI4 */ CH_LIST_ENT(4, 36, 40, 44, 48, 0), - /* 20, RTW_RD_5G_ETSI5 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 21, RTW_RD_5G_FCC8 */ CH_LIST_ENT(4, 149, 153, 157, 161, 0), - /* 22, RTW_RD_5G_ETSI6 */ CH_LIST_ENT(8, 36, 40, 44, 48, 52, 56, 60, 64, CLA_5G_B2_DFS), - /* 23, RTW_RD_5G_ETSI7 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B2_DFS), - /* 24, RTW_RD_5G_ETSI8 */ CH_LIST_ENT(9, 36, 40, 44, 48, 149, 153, 157, 161, 165, 0), - /* 25, RTW_RD_5G_ETSI9 */ CH_LIST_ENT(11, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 0), - /* 26, RTW_RD_5G_ETSI10 */ CH_LIST_ENT(5, 149, 153, 157, 161, 165, 0), - /* 27, RTW_RD_5G_ETSI11 */ CH_LIST_ENT(16, 36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 28, RTW_RD_5G_NCC4 */ CH_LIST_ENT(17, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 29, RTW_RD_5G_ETSI12 */ CH_LIST_ENT(4, 149, 153, 157, 161, 0), - /* 30, RTW_RD_5G_FCC9 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 31, RTW_RD_5G_ETSI13 */ CH_LIST_ENT(16, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 32, RTW_RD_5G_FCC10 */ CH_LIST_ENT(20, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 33, RTW_RD_5G_MKK4 */ CH_LIST_ENT(4, 36, 40, 44, 48, 0), - /* 34, RTW_RD_5G_ETSI14 */ CH_LIST_ENT(11, 36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 35, RTW_RD_5G_FCC11 */ CH_LIST_ENT(25, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 36, RTW_RD_5G_ETSI15 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 37, RTW_RD_5G_MKK5 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE | CLA_5G_B4_PASSIVE), - /* 38, RTW_RD_5G_ETSI16 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE | CLA_5G_B4_PASSIVE), - /* 39, RTW_RD_5G_ETSI17 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE), - /* 40, RTW_RD_5G_FCC12 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE), - /* 41, RTW_RD_5G_FCC13 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE), - /* 42, RTW_RD_5G_FCC14 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE), - /* 43, RTW_RD_5G_FCC15 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B2_PASSIVE), - /* 44, RTW_RD_5G_FCC16 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE), - /* 45, RTW_RD_5G_ETSI18 */ CH_LIST_ENT(9, 36, 40, 44, 48, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B4_PASSIVE), - /* 46, RTW_RD_5G_ETSI19 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE | CLA_5G_B4_PASSIVE), - /* 47, RTW_RD_5G_FCC17 */ CH_LIST_ENT(16, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 48, RTW_RD_5G_ETSI20 */ CH_LIST_ENT(9, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B2_DFS), - /* 49, RTW_RD_5G_IC2 */ CH_LIST_ENT(22, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 144, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 50, RTW_RD_5G_ETSI21 */ CH_LIST_ENT(13, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B3_DFS), - /* 51, RTW_RD_5G_FCC18 */ CH_LIST_ENT(8, 100, 104, 108, 112, 116, 132, 136, 140, CLA_5G_B3_DFS), - /* 52, RTW_RD_5G_WORLD */ CH_LIST_ENT(25, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE | CLA_5G_B4_PASSIVE), - /* 53, RTW_RD_5G_CHILE1 */ CH_LIST_ENT(25, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 54, RTW_RD_5G_ACMA1 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 55, RTW_RD_5G_WORLD1 */ CH_LIST_ENT(8, 36, 40, 44, 48, 52, 56, 60, 64, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE), - /* 56, RTW_RD_5G_CHILE2 */ CH_LIST_ENT(16, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 57, RTW_RD_5G_KCC2 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 58, RTW_RD_5G_KCC3 */ CH_LIST_ENT(25, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 59, RTW_RD_5G_MKK6 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_DFS | CLA_5G_B3_DFS | CLA_5G_B4_DFS), - /* 60, RTW_RD_5G_MKK7 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 61, RTW_RD_5G_MKK8 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 62, RTW_RD_5G_MEX1 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), - /* 63, RTW_RD_5G_ETSI22 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_DFS | CLA_5G_B3_DFS | CLA_5G_B4_PASSIVE), - /* 64, RTW_RD_5G_MKK9 */ CH_LIST_ENT(23, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE | CLA_5G_B4_PASSIVE), - /* 65, RTW_RD_5G_FCC19 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE | CLA_5G_B4_PASSIVE), - /* 66, RTW_RD_5G_FCC20 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B4_PASSIVE), - /* 67, RTW_RD_5G_FCC21 */ CH_LIST_ENT(23, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE | CLA_5G_B4_PASSIVE), - /* 68, RTW_RD_5G_ETSI23 */ CH_LIST_ENT(12, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, CLA_5G_B2_DFS), - /* 69, RTW_RD_5G_ETSI24 */ CH_LIST_ENT(12, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, CLA_5G_B2_PASSIVE), - /* 70, RTW_RD_5G_ETSI25 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B2_PASSIVE), - /* 71, RTW_RD_5G_MKK10 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE), - /* 72, RTW_RD_5G_ETSI26 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE), +static const struct ch_list_t rtw_channel_def_5g[] = { + /* 0, RTW_CHD_5G_00 */ CH_LIST_ENT(0, 0), + /* 1, RTW_CHD_5G_01 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 2, RTW_CHD_5G_02 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 3, RTW_CHD_5G_03 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 4, RTW_CHD_5G_04 */ CH_LIST_ENT(22, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 5, RTW_CHD_5G_05 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 6, RTW_CHD_5G_06 */ CH_LIST_ENT(9, 36, 40, 44, 48, 149, 153, 157, 161, 165, 0), + /* 7, RTW_CHD_5G_07 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B2_DFS), + /* 8, RTW_CHD_5G_08 */ CH_LIST_ENT(12, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, CLA_5G_B2_DFS), + /* 9, RTW_CHD_5G_09 */ CH_LIST_ENT(5, 149, 153, 157, 161, 165, 0), + /* 10, RTW_CHD_5G_10 */ CH_LIST_ENT(8, 36, 40, 44, 48, 52, 56, 60, 64, CLA_5G_B2_DFS), + /* 11, RTW_CHD_5G_11 */ CH_LIST_ENT(11, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, CLA_5G_B3_DFS), + /* 12, RTW_CHD_5G_12 */ CH_LIST_ENT(16, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 13, RTW_CHD_5G_13 */ CH_LIST_ENT(8, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B2_DFS), + /* 14, RTW_CHD_5G_14 */ CH_LIST_ENT(4, 36, 40, 44, 48, 0), + /* 15, RTW_CHD_5G_15 */ CH_LIST_ENT(4, 149, 153, 157, 161, 0), + /* 16, RTW_CHD_5G_16 */ CH_LIST_ENT(11, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 0), + /* 17, RTW_CHD_5G_17 */ CH_LIST_ENT(16, 36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 18, RTW_CHD_5G_18 */ CH_LIST_ENT(17, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 19, RTW_CHD_5G_19 */ CH_LIST_ENT(16, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 20, RTW_CHD_5G_20 */ CH_LIST_ENT(20, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 21, RTW_CHD_5G_21 */ CH_LIST_ENT(11, 36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 22, RTW_CHD_5G_22 */ CH_LIST_ENT(25, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 23, RTW_CHD_5G_23 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 24, RTW_CHD_5G_24 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE | CLA_5G_B4_PASSIVE), + /* 25, RTW_CHD_5G_25 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE), + /* 26, RTW_CHD_5G_26 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE), + /* 27, RTW_CHD_5G_27 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE), + /* 28, RTW_CHD_5G_28 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B2_PASSIVE), + /* 29, RTW_CHD_5G_29 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE), + /* 30, RTW_CHD_5G_30 */ CH_LIST_ENT(9, 36, 40, 44, 48, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B4_PASSIVE), + /* 31, RTW_CHD_5G_31 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE | CLA_5G_B4_PASSIVE), + /* 32, RTW_CHD_5G_32 */ CH_LIST_ENT(9, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B2_DFS), + /* 33, RTW_CHD_5G_33 */ CH_LIST_ENT(22, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 144, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 34, RTW_CHD_5G_34 */ CH_LIST_ENT(13, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B3_DFS), + /* 35, RTW_CHD_5G_35 */ CH_LIST_ENT(8, 100, 104, 108, 112, 116, 132, 136, 140, CLA_5G_B3_DFS), + /* 36, RTW_CHD_5G_36 */ CH_LIST_ENT(25, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B2_DFS | CLA_5G_B3_PASSIVE | CLA_5G_B3_DFS | CLA_5G_B4_PASSIVE), + /* 37, RTW_CHD_5G_37 */ CH_LIST_ENT(8, 36, 40, 44, 48, 52, 56, 60, 64, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE), + /* 38, RTW_CHD_5G_38 */ CH_LIST_ENT(16, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 39, RTW_CHD_5G_39 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_DFS | CLA_5G_B3_DFS | CLA_5G_B4_DFS), + /* 40, RTW_CHD_5G_40 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 41, RTW_CHD_5G_41 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS | CLA_5G_B4_PASSIVE), + /* 42, RTW_CHD_5G_42 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_DFS | CLA_5G_B3_DFS | CLA_5G_B4_PASSIVE), + /* 43, RTW_CHD_5G_43 */ CH_LIST_ENT(23, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE | CLA_5G_B4_PASSIVE), + /* 44, RTW_CHD_5G_44 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE | CLA_5G_B4_PASSIVE), + /* 45, RTW_CHD_5G_45 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B4_PASSIVE), + /* 46, RTW_CHD_5G_46 */ CH_LIST_ENT(12, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, CLA_5G_B2_PASSIVE), + /* 47, RTW_CHD_5G_47 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE), + /* 48, RTW_CHD_5G_48 */ CH_LIST_ENT(20, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 49, RTW_CHD_5G_49 */ CH_LIST_ENT(17, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 50, RTW_CHD_5G_50 */ CH_LIST_ENT(17, 36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140, 144, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 51, RTW_CHD_5G_51 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, CLA_5G_B2_DFS | CLA_5G_B3_DFS), }; #endif /* CONFIG_IEEE80211_BAND_5GHZ */ +struct chplan_ent_t { + u8 regd_2g; /* value of REGULATION_TXPWR_LMT */ + u8 chd_2g; +#if CONFIG_IEEE80211_BAND_5GHZ + u8 regd_5g; /* value of REGULATION_TXPWR_LMT */ + u8 chd_5g; +#endif +}; + +#if CONFIG_IEEE80211_BAND_5GHZ +#define CHPLAN_ENT(_regd_2g, _chd_2g, _regd_5g, _chd_5g) {.regd_2g = _regd_2g, .chd_2g = _chd_2g, .regd_5g = _regd_5g, .chd_5g = _chd_5g} +#else +#define CHPLAN_ENT(_regd_2g, _chd_2g, _regd_5g, _chd_5g) {.regd_2g = _regd_2g, .chd_2g = _chd_2g} +#endif + +#define CHPLAN_ENT_NOT_DEFINED CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_NULL, TXPWR_LMT_NONE, RTW_CHD_5G_NULL) + static const struct chplan_ent_t RTW_ChannelPlanMap[] = { - /* 0x00 */ CHPLAN_ENT_NOT_DEFINED, - /* 0x01 */ CHPLAN_ENT_NOT_DEFINED, - /* 0x02 */ CHPLAN_ENT_NOT_DEFINED, - /* 0x03 */ CHPLAN_ENT_NOT_DEFINED, - /* 0x04 */ CHPLAN_ENT_NOT_DEFINED, + /* 0x00 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_49), + /* 0x01 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_50), + /* 0x02 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_03, TXPWR_LMT_ETSI, RTW_CHD_5G_07), + /* 0x03 */ CHPLAN_ENT(TXPWR_LMT_ACMA, RTW_CHD_2G_02, TXPWR_LMT_ACMA, RTW_CHD_5G_33), + /* 0x04 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_51), /* 0x05 */ CHPLAN_ENT_NOT_DEFINED, /* 0x06 */ CHPLAN_ENT_NOT_DEFINED, /* 0x07 */ CHPLAN_ENT_NOT_DEFINED, @@ -280,118 +229,140 @@ static const struct chplan_ent_t RTW_ChannelPlanMap[] = { /* 0x1D */ CHPLAN_ENT_NOT_DEFINED, /* 0x1E */ CHPLAN_ENT_NOT_DEFINED, /* 0x1F */ CHPLAN_ENT_NOT_DEFINED, - /* 0x20 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_NULL, TXPWR_LMT_WW), - /* 0x21 */ CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_NULL, TXPWR_LMT_ETSI), - /* 0x22 */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NULL, TXPWR_LMT_FCC), - /* 0x23 */ CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_MKK), - /* 0x24 */ CHPLAN_ENT(RTW_RD_2G_ETSI2, RTW_RD_5G_NULL, TXPWR_LMT_ETSI), - /* 0x25 */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC1, TXPWR_LMT_FCC), - /* 0x26 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI1, TXPWR_LMT_ETSI), - /* 0x27 */ CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_MKK1, TXPWR_LMT_MKK), - /* 0x28 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_KCC1, TXPWR_LMT_KCC), - /* 0x29 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC2, TXPWR_LMT_FCC), - /* 0x2A */ CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_NULL, TXPWR_LMT_FCC), - /* 0x2B */ CHPLAN_ENT(RTW_RD_2G_IC1, RTW_RD_5G_IC2, TXPWR_LMT_IC), - /* 0x2C */ CHPLAN_ENT(RTW_RD_2G_MKK2, RTW_RD_5G_NULL, TXPWR_LMT_MKK), - /* 0x2D */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_CHILE1, TXPWR_LMT_CHILE), - /* 0x2E */ CHPLAN_ENT(RTW_RD_2G_WORLD1, RTW_RD_5G_WORLD1, TXPWR_LMT_WW), - /* 0x2F */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_CHILE2, TXPWR_LMT_CHILE), - /* 0x30 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC3, TXPWR_LMT_FCC), - /* 0x31 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC4, TXPWR_LMT_FCC), - /* 0x32 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC5, TXPWR_LMT_FCC), - /* 0x33 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC6, TXPWR_LMT_FCC), - /* 0x34 */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC7, TXPWR_LMT_FCC), - /* 0x35 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI2, TXPWR_LMT_ETSI), - /* 0x36 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI3, TXPWR_LMT_ETSI), - /* 0x37 */ CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_MKK2, TXPWR_LMT_MKK), - /* 0x38 */ CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_MKK3, TXPWR_LMT_MKK), - /* 0x39 */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NCC1, TXPWR_LMT_FCC), - /* 0x3A */ CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI1, TXPWR_LMT_ETSI), - /* 0x3B */ CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ACMA1, TXPWR_LMT_ACMA), - /* 0x3C */ CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI6, TXPWR_LMT_ETSI), - /* 0x3D */ CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI12, TXPWR_LMT_ETSI), - /* 0x3E */ CHPLAN_ENT(RTW_RD_2G_KCC1, RTW_RD_5G_KCC2, TXPWR_LMT_KCC), - /* 0x3F */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC11, TXPWR_LMT_FCC), - /* 0x40 */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NCC2, TXPWR_LMT_FCC), - /* 0x41 */ CHPLAN_ENT(RTW_RD_2G_GLOBAL, RTW_RD_5G_NULL, TXPWR_LMT_WW), - /* 0x42 */ CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI4, TXPWR_LMT_ETSI), - /* 0x43 */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC2, TXPWR_LMT_FCC), - /* 0x44 */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NCC3, TXPWR_LMT_FCC), - /* 0x45 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ACMA1, TXPWR_LMT_ACMA), - /* 0x46 */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC8, TXPWR_LMT_FCC), - /* 0x47 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI6, TXPWR_LMT_ETSI), - /* 0x48 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI7, TXPWR_LMT_ETSI), - /* 0x49 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI8, TXPWR_LMT_ETSI), - /* 0x4A */ CHPLAN_ENT(RTW_RD_2G_IC2, RTW_RD_5G_IC2, TXPWR_LMT_IC), - /* 0x4B */ CHPLAN_ENT(RTW_RD_2G_KCC1, RTW_RD_5G_KCC3, TXPWR_LMT_KCC), - /* 0x4C */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC15, TXPWR_LMT_FCC), - /* 0x4D */ CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_MEX1, TXPWR_LMT_MEXICO), - /* 0x4E */ CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI22, TXPWR_LMT_ETSI), - /* 0x4F */ CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_MKK9, TXPWR_LMT_MKK), - /* 0x50 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI9, TXPWR_LMT_ETSI), - /* 0x51 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI10, TXPWR_LMT_ETSI), - /* 0x52 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI11, TXPWR_LMT_ETSI), - /* 0x53 */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NCC4, TXPWR_LMT_FCC), - /* 0x54 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI12, TXPWR_LMT_ETSI), - /* 0x55 */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC9, TXPWR_LMT_FCC), - /* 0x56 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI13, TXPWR_LMT_ETSI), - /* 0x57 */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC10, TXPWR_LMT_FCC), - /* 0x58 */ CHPLAN_ENT(RTW_RD_2G_MKK2, RTW_RD_5G_MKK4, TXPWR_LMT_MKK), - /* 0x59 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI14, TXPWR_LMT_ETSI), - /* 0x5A */ CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_FCC19, TXPWR_LMT_FCC), - /* 0x5B */ CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_FCC20, TXPWR_LMT_FCC), - /* 0x5C */ CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_FCC21, TXPWR_LMT_FCC), - /* 0x5D */ CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI23, TXPWR_LMT_ETSI), - /* 0x5E */ CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI2, TXPWR_LMT_ETSI), - /* 0x5F */ CHPLAN_ENT(RTW_RD_2G_MKK2, RTW_RD_5G_MKK10, TXPWR_LMT_MKK), - /* 0x60 */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC5, TXPWR_LMT_FCC), - /* 0x61 */ CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_FCC7, TXPWR_LMT_FCC), - /* 0x62 */ CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_FCC1, TXPWR_LMT_FCC), - /* 0x63 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI15, TXPWR_LMT_ETSI), - /* 0x64 */ CHPLAN_ENT(RTW_RD_2G_MKK2, RTW_RD_5G_MKK5, TXPWR_LMT_MKK), - /* 0x65 */ CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI16, TXPWR_LMT_ETSI), - /* 0x66 */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC14, TXPWR_LMT_FCC), - /* 0x67 */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC12, TXPWR_LMT_FCC), - /* 0x68 */ CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_FCC14, TXPWR_LMT_FCC), - /* 0x69 */ CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_FCC12, TXPWR_LMT_FCC), - /* 0x6A */ CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI17, TXPWR_LMT_ETSI), - /* 0x6B */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC16, TXPWR_LMT_FCC), - /* 0x6C */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC13, TXPWR_LMT_FCC), - /* 0x6D */ CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_FCC15, TXPWR_LMT_FCC), - /* 0x6E */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC12, TXPWR_LMT_FCC), - /* 0x6F */ CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_ETSI8, TXPWR_LMT_ETSI), - /* 0x70 */ CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_ETSI18, TXPWR_LMT_ETSI), - /* 0x71 */ CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_ETSI17, TXPWR_LMT_ETSI), - /* 0x72 */ CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_ETSI19, TXPWR_LMT_ETSI), - /* 0x73 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC7, TXPWR_LMT_FCC), - /* 0x74 */ CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_FCC17, TXPWR_LMT_FCC), - /* 0x75 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI20, TXPWR_LMT_ETSI), - /* 0x76 */ CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_FCC11, TXPWR_LMT_FCC), - /* 0x77 */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI21, TXPWR_LMT_ETSI), - /* 0x78 */ CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC18, TXPWR_LMT_FCC), - /* 0x79 */ CHPLAN_ENT(RTW_RD_2G_MKK2, RTW_RD_5G_MKK1, TXPWR_LMT_MKK), - /* 0x7A */ CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI25, TXPWR_LMT_ETSI), - /* 0x7B */ CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI24, TXPWR_LMT_ETSI), - /* 0x7C */ CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI26, TXPWR_LMT_ETSI), - /* 0x7D */ CHPLAN_ENT_NOT_DEFINED, - /* 0x7E */ CHPLAN_ENT_NOT_DEFINED, - /* 0x7F */ CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC1, TXPWR_LMT_FCC), /* Realtek Define */ + /* 0x20 */ CHPLAN_ENT(TXPWR_LMT_WW, RTW_CHD_2G_01, TXPWR_LMT_NONE, RTW_CHD_5G_00), + /* 0x21 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_NONE, RTW_CHD_5G_00), + /* 0x22 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_NONE, RTW_CHD_5G_00), + /* 0x23 */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_04, TXPWR_LMT_NONE, RTW_CHD_5G_00), + /* 0x24 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_05, TXPWR_LMT_NONE, RTW_CHD_5G_00), + /* 0x25 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_03), + /* 0x26 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_02), + /* 0x27 */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_04, TXPWR_LMT_MKK, RTW_CHD_5G_02), + /* 0x28 */ CHPLAN_ENT(TXPWR_LMT_KCC, RTW_CHD_2G_01, TXPWR_LMT_KCC, RTW_CHD_5G_05), + /* 0x29 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_06), + /* 0x2A */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_02, TXPWR_LMT_NONE, RTW_CHD_5G_00), + /* 0x2B */ CHPLAN_ENT(TXPWR_LMT_IC, RTW_CHD_2G_02, TXPWR_LMT_IC, RTW_CHD_5G_33), + /* 0x2C */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_02, TXPWR_LMT_NONE, RTW_CHD_5G_00), + /* 0x2D */ CHPLAN_ENT(TXPWR_LMT_CHILE, RTW_CHD_2G_01, TXPWR_LMT_CHILE, RTW_CHD_5G_22), + /* 0x2E */ CHPLAN_ENT(TXPWR_LMT_WW, RTW_CHD_2G_03, TXPWR_LMT_WW, RTW_CHD_5G_37), + /* 0x2F */ CHPLAN_ENT(TXPWR_LMT_CHILE, RTW_CHD_2G_01, TXPWR_LMT_CHILE, RTW_CHD_5G_38), + /* 0x30 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_07), + /* 0x31 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_08), + /* 0x32 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_09), + /* 0x33 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_10), + /* 0x34 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_01), + /* 0x35 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_03), + /* 0x36 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_04), + /* 0x37 */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_04, TXPWR_LMT_MKK, RTW_CHD_5G_10), + /* 0x38 */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_04, TXPWR_LMT_MKK, RTW_CHD_5G_11), + /* 0x39 */ CHPLAN_ENT(TXPWR_LMT_NCC, RTW_CHD_2G_03, TXPWR_LMT_NCC, RTW_CHD_5G_12), + /* 0x3A */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_02), + /* 0x3B */ CHPLAN_ENT(TXPWR_LMT_ACMA, RTW_CHD_2G_02, TXPWR_LMT_ACMA, RTW_CHD_5G_01), + /* 0x3C */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_10), + /* 0x3D */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_15), + /* 0x3E */ CHPLAN_ENT(TXPWR_LMT_KCC, RTW_CHD_2G_02, TXPWR_LMT_KCC, RTW_CHD_5G_03), + /* 0x3F */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_22), + /* 0x40 */ CHPLAN_ENT(TXPWR_LMT_NCC, RTW_CHD_2G_03, TXPWR_LMT_NCC, RTW_CHD_5G_13), + /* 0x41 */ CHPLAN_ENT(TXPWR_LMT_WW, RTW_CHD_2G_06, TXPWR_LMT_NONE, RTW_CHD_5G_00), + /* 0x42 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_14), + /* 0x43 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_06), + /* 0x44 */ CHPLAN_ENT(TXPWR_LMT_NCC, RTW_CHD_2G_03, TXPWR_LMT_NCC, RTW_CHD_5G_09), + /* 0x45 */ CHPLAN_ENT(TXPWR_LMT_ACMA, RTW_CHD_2G_01, TXPWR_LMT_ACMA, RTW_CHD_5G_01), + /* 0x46 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_15), + /* 0x47 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_10), + /* 0x48 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_07), + /* 0x49 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_06), + /* 0x4A */ CHPLAN_ENT(TXPWR_LMT_IC, RTW_CHD_2G_03, TXPWR_LMT_IC, RTW_CHD_5G_33), + /* 0x4B */ CHPLAN_ENT(TXPWR_LMT_KCC, RTW_CHD_2G_02, TXPWR_LMT_KCC, RTW_CHD_5G_22), + /* 0x4C */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_28), + /* 0x4D */ CHPLAN_ENT(TXPWR_LMT_MEXICO, RTW_CHD_2G_02, TXPWR_LMT_MEXICO, RTW_CHD_5G_01), + /* 0x4E */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_42), + /* 0x4F */ CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_00, TXPWR_LMT_MKK, RTW_CHD_5G_43), + /* 0x50 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_16), + /* 0x51 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_09), + /* 0x52 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_17), + /* 0x53 */ CHPLAN_ENT(TXPWR_LMT_NCC, RTW_CHD_2G_03, TXPWR_LMT_NCC, RTW_CHD_5G_18), + /* 0x54 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_15), + /* 0x55 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_01), + /* 0x56 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_19), + /* 0x57 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_20), + /* 0x58 */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_02, TXPWR_LMT_MKK, RTW_CHD_5G_14), + /* 0x59 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_21), + /* 0x5A */ CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_00, TXPWR_LMT_FCC, RTW_CHD_5G_44), + /* 0x5B */ CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_00, TXPWR_LMT_FCC, RTW_CHD_5G_45), + /* 0x5C */ CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_00, TXPWR_LMT_FCC, RTW_CHD_5G_43), + /* 0x5D */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_08), + /* 0x5E */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_03), + /* 0x5F */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_02, TXPWR_LMT_MKK, RTW_CHD_5G_47), + /* 0x60 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_09), + /* 0x61 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_02, TXPWR_LMT_FCC, RTW_CHD_5G_01), + /* 0x62 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_02, TXPWR_LMT_FCC, RTW_CHD_5G_03), + /* 0x63 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_23), + /* 0x64 */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_02, TXPWR_LMT_MKK, RTW_CHD_5G_24), + /* 0x65 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_24), + /* 0x66 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_27), + /* 0x67 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_25), + /* 0x68 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_02, TXPWR_LMT_FCC, RTW_CHD_5G_27), + /* 0x69 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_02, TXPWR_LMT_FCC, RTW_CHD_5G_25), + /* 0x6A */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_25), + /* 0x6B */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_29), + /* 0x6C */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_26), + /* 0x6D */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_02, TXPWR_LMT_FCC, RTW_CHD_5G_28), + /* 0x6E */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_25), + /* 0x6F */ CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_00, TXPWR_LMT_ETSI, RTW_CHD_5G_06), + /* 0x70 */ CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_00, TXPWR_LMT_ETSI, RTW_CHD_5G_30), + /* 0x71 */ CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_00, TXPWR_LMT_ETSI, RTW_CHD_5G_25), + /* 0x72 */ CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_00, TXPWR_LMT_ETSI, RTW_CHD_5G_31), + /* 0x73 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_01), + /* 0x74 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_02, TXPWR_LMT_FCC, RTW_CHD_5G_19), + /* 0x75 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_32), + /* 0x76 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_02, TXPWR_LMT_FCC, RTW_CHD_5G_22), + /* 0x77 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_34), + /* 0x78 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_35), + /* 0x79 */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_02, TXPWR_LMT_MKK, RTW_CHD_5G_02), + /* 0x7A */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_28), + /* 0x7B */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_46), + /* 0x7C */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_47), + /* 0x7D */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_04, TXPWR_LMT_MKK, RTW_CHD_5G_48), + /* 0x7E */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_02, TXPWR_LMT_MKK, RTW_CHD_5G_48), + /* 0x7F */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_03), }; const int RTW_ChannelPlanMap_size = sizeof(RTW_ChannelPlanMap) / sizeof(RTW_ChannelPlanMap[0]); +u8 rtw_chplan_get_default_regd_2g(u8 id) +{ + return RTW_ChannelPlanMap[id].regd_2g; +} + +u8 rtw_chplan_get_default_regd_5g(u8 id) +{ +#if CONFIG_IEEE80211_BAND_5GHZ + return RTW_ChannelPlanMap[id].regd_5g; +#else + return TXPWR_LMT_NONE; +#endif +} + u8 rtw_chplan_get_default_regd(u8 id) { - return RTW_ChannelPlanMap[id].regd; + u8 regd_2g = rtw_chplan_get_default_regd_2g(id); + u8 regd_5g = rtw_chplan_get_default_regd_5g(id); + + if (regd_2g != TXPWR_LMT_NONE && regd_5g != TXPWR_LMT_NONE) { + if (regd_2g != regd_5g) + RTW_WARN("channel_plan:0x%02x, regd_2g:%u, regd_5g:%u not the same\n", id, regd_2g, regd_5g); + return regd_5g; + } + return regd_2g != TXPWR_LMT_NONE ? regd_2g : regd_5g; } bool rtw_chplan_is_empty(u8 id) { const struct chplan_ent_t *chplan_map = &RTW_ChannelPlanMap[id]; - if (chplan_map->rd_2g == RTW_RD_2G_NULL + if (chplan_map->chd_2g == RTW_CHD_2G_NULL #if CONFIG_IEEE80211_BAND_5GHZ - && chplan_map->rd_5g == RTW_RD_5G_NULL + && chplan_map->chd_5g == RTW_CHD_5G_NULL #endif ) return _TRUE; @@ -417,13 +388,19 @@ bool rtw_regsty_is_excl_chs(struct registry_priv *regsty, u8 ch) return _FALSE; } -u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set) +const char *_regd_src_str[] = { + [REGD_SRC_RTK_PRIV] = "RTK_PRIV", + [REGD_SRC_OS] = "OS", + [REGD_SRC_NUM] = "UNKNOWN", +}; + +static u8 init_channel_set_from_rtk_priv(_adapter *padapter, RT_CHANNEL_INFO *channel_set) { struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); struct registry_priv *regsty = adapter_to_regsty(padapter); + u8 ChannelPlan = rfctl->ChannelPlan; u8 index, chanset_size = 0; u8 b5GBand = _FALSE, b2_4GBand = _FALSE; - u8 rd_2g = 0, rd_5g = 0; u8 ch, attrib; #ifdef CONFIG_DFS_MASTER int i; @@ -448,11 +425,12 @@ u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel } if (b2_4GBand) { - rd_2g = RTW_ChannelPlanMap[ChannelPlan].rd_2g; - attrib = CH_LIST_ATTRIB(RTW_ChannelPlan2G[rd_2g]); + u8 chd_2g = RTW_ChannelPlanMap[ChannelPlan].chd_2g; - for (index = 0; index < CH_LIST_LEN(RTW_ChannelPlan2G[rd_2g]); index++) { - ch = CH_LIST_CH(RTW_ChannelPlan2G[rd_2g], index); + attrib = CH_LIST_ATTRIB(rtw_channel_def_2g[chd_2g]); + + for (index = 0; index < CH_LIST_LEN(rtw_channel_def_2g[chd_2g]); index++) { + ch = CH_LIST_CH(rtw_channel_def_2g[chd_2g], index); if (rtw_regsty_is_excl_chs(regsty, ch) == _TRUE) continue; @@ -464,11 +442,9 @@ u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel channel_set[chanset_size].ChannelNum = ch; if (ch >= 12 && ch <= 14 && (attrib & CLA_2G_12_14_PASSIVE)) - channel_set[chanset_size].ScanType = SCAN_PASSIVE; - else - channel_set[chanset_size].ScanType = SCAN_ACTIVE; + channel_set[chanset_size].flags |= RTW_CHF_NO_IR; - if (channel_set[chanset_size].ScanType == SCAN_PASSIVE) { + if (channel_set[chanset_size].flags & RTW_CHF_NO_IR) { if (rfctl->country_ent || ch <= 11) RTW_INFO("ch%u is PASSIVE\n", ch); } @@ -480,12 +456,12 @@ u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel #if CONFIG_IEEE80211_BAND_5GHZ if (b5GBand) { bool dfs; + u8 chd_5g = RTW_ChannelPlanMap[ChannelPlan].chd_5g; - rd_5g = RTW_ChannelPlanMap[ChannelPlan].rd_5g; - attrib = CH_LIST_ATTRIB(RTW_ChannelPlan5G[rd_5g]); + attrib = CH_LIST_ATTRIB(rtw_channel_def_5g[chd_5g]); - for (index = 0; index < CH_LIST_LEN(RTW_ChannelPlan5G[rd_5g]); index++) { - ch = CH_LIST_CH(RTW_ChannelPlan5G[rd_5g], index); + for (index = 0; index < CH_LIST_LEN(rtw_channel_def_5g[chd_5g]); index++) { + ch = CH_LIST_CH(rtw_channel_def_5g[chd_5g], index); if (rtw_regsty_is_excl_chs(regsty, ch) == _TRUE) continue; dfs = (rtw_is_5g_band2(ch) && (attrib & CLA_5G_B2_DFS)) @@ -508,14 +484,13 @@ u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel || (rtw_is_5g_band3(ch) && (attrib & CLA_5G_B3_PASSIVE)) /* band3 passive */ || (rtw_is_5g_band4(ch) && (attrib & CLA_5G_B4_PASSIVE)) /* band4 passive */ ) - channel_set[chanset_size].ScanType = SCAN_PASSIVE; - else - channel_set[chanset_size].ScanType = SCAN_ACTIVE; + channel_set[chanset_size].flags |= RTW_CHF_NO_IR; - channel_set[chanset_size].dfs = dfs; + if (dfs) + channel_set[chanset_size].flags |= RTW_CHF_DFS; - if (channel_set[chanset_size].ScanType == SCAN_PASSIVE) { - if (rfctl->country_ent || channel_set[chanset_size].dfs) + if (channel_set[chanset_size].flags & RTW_CHF_NO_IR) { + if (rfctl->country_ent || (channel_set[chanset_size].flags & RTW_CHF_DFS)) RTW_INFO("ch%u is PASSIVE%s\n", ch, dfs ? " DFS" : ""); } @@ -539,6 +514,22 @@ u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel return chanset_size; } +u8 init_channel_set(_adapter *adapter) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + if (rfctl->regd_src == REGD_SRC_RTK_PRIV) + return init_channel_set_from_rtk_priv(adapter, rfctl->channel_set); +#ifdef CONFIG_REGD_SRC_FROM_OS + else if (rfctl->regd_src == REGD_SRC_OS) + return rtw_os_init_channel_set(adapter, rfctl->channel_set); +#endif + else + rtw_warn_on(1); + + return 0; +} + bool rtw_chset_is_dfs_range(struct _RT_CHANNEL_INFO *chset, u32 hi, u32 lo) { u8 hi_ch = rtw_freq2ch(hi); @@ -546,7 +537,7 @@ bool rtw_chset_is_dfs_range(struct _RT_CHANNEL_INFO *chset, u32 hi, u32 lo) int i; for (i = 0; i < MAX_CHANNEL_NUM && chset[i].ChannelNum != 0; i++){ - if (!chset[i].dfs) + if (!(chset[i].flags & RTW_CHF_DFS)) continue; if (hi_ch > chset[i].ChannelNum && lo_ch < chset[i].ChannelNum) return 1; @@ -561,7 +552,7 @@ bool rtw_chset_is_dfs_ch(struct _RT_CHANNEL_INFO *chset, u8 ch) for (i = 0; i < MAX_CHANNEL_NUM && chset[i].ChannelNum != 0; i++){ if (chset[i].ChannelNum == ch) - return chset[i].dfs; + return chset[i].flags & RTW_CHF_DFS ? 1 : 0; } return 0; @@ -577,7 +568,7 @@ bool rtw_chset_is_dfs_chbw(struct _RT_CHANNEL_INFO *chset, u8 ch, u8 bw, u8 offs return rtw_chset_is_dfs_range(chset, hi, lo); } -void rtw_process_beacon_hint(_adapter *adapter, WLAN_BSSID_EX *bss) +u8 rtw_process_beacon_hint(_adapter *adapter, WLAN_BSSID_EX *bss) { #ifndef RTW_CHPLAN_BEACON_HINT_NON_WORLD_WIDE #define RTW_CHPLAN_BEACON_HINT_NON_WORLD_WIDE 0 @@ -595,37 +586,41 @@ void rtw_process_beacon_hint(_adapter *adapter, WLAN_BSSID_EX *bss) RT_CHANNEL_INFO *chset = rfctl->channel_set; u8 ch = bss->Configuration.DSConfig; int chset_idx = rtw_chset_search_ch(chset, ch); + u8 act_cnt = 0; if (chset_idx < 0) - return; + goto exit; - if (chset[chset_idx].ScanType == SCAN_PASSIVE - && (RTW_CHPLAN_BEACON_HINT_NON_WORLD_WIDE || !rfctl->country_ent) + if ((chset[chset_idx].flags & RTW_CHF_NO_IR) + && (RTW_CHPLAN_BEACON_HINT_NON_WORLD_WIDE || !rfctl->country_ent || IS_ALPHA2_WORLDWIDE(rfctl->country_ent->alpha2)) && (RTW_CHPLAN_BEACON_HINT_ON_2G_CH_1_11 || !(ch <= 11)) - && (RTW_CHPLAN_BEACON_HINT_ON_DFS_CH || !chset[chset_idx].dfs) + && (RTW_CHPLAN_BEACON_HINT_ON_DFS_CH || !(chset[chset_idx].flags & RTW_CHF_DFS)) ) { RTW_INFO("%s: change ch:%d to active\n", __func__, ch); - chset[chset_idx].ScanType = SCAN_ACTIVE; + chset[chset_idx].flags &= ~RTW_CHF_NO_IR; + act_cnt++; } + +exit: + return act_cnt; } +const char *_rtw_dfs_regd_str[] = { + [RTW_DFS_REGD_NONE] = "NONE", + [RTW_DFS_REGD_FCC] = "FCC", + [RTW_DFS_REGD_MKK] = "MKK", + [RTW_DFS_REGD_ETSI] = "ETSI", +}; + #ifdef CONFIG_80211AC_VHT #define COUNTRY_CHPLAN_ASSIGN_EN_11AC(_val) , .en_11ac = (_val) #else #define COUNTRY_CHPLAN_ASSIGN_EN_11AC(_val) #endif -#if RTW_DEF_MODULE_REGULATORY_CERT -#define COUNTRY_CHPLAN_ASSIGN_DEF_MODULE_FLAGS(_val) , .def_module_flags = (_val) -#else -#define COUNTRY_CHPLAN_ASSIGN_DEF_MODULE_FLAGS(_val) -#endif - -/* has def_module_flags specified, used by common map and HAL dfference map */ -#define COUNTRY_CHPLAN_ENT(_alpha2, _chplan, _en_11ac, _def_module_flags) \ +#define COUNTRY_CHPLAN_ENT(_alpha2, _chplan, _en_11ac) \ {.alpha2 = (_alpha2), .chplan = (_chplan) \ COUNTRY_CHPLAN_ASSIGN_EN_11AC(_en_11ac) \ - COUNTRY_CHPLAN_ASSIGN_DEF_MODULE_FLAGS(_def_module_flags) \ } #ifdef CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP @@ -634,488 +629,1739 @@ void rtw_process_beacon_hint(_adapter *adapter, WLAN_BSSID_EX *bss) #elif RTW_DEF_MODULE_REGULATORY_CERT -/* leave def_module_flags empty, def_module_flags check is done on country_chplan_map */ #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8821AE_HMC_M2) /* 2013 certify */ -static const struct country_chplan RTL8821AE_HMC_M2_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("CA", 0x34, 1, 0), /* Canada */ - COUNTRY_CHPLAN_ENT("CL", 0x30, 1, 0), /* Chile */ - COUNTRY_CHPLAN_ENT("CN", 0x51, 1, 0), /* China */ - COUNTRY_CHPLAN_ENT("CO", 0x34, 1, 0), /* Colombia */ - COUNTRY_CHPLAN_ENT("CR", 0x34, 1, 0), /* Costa Rica */ - COUNTRY_CHPLAN_ENT("DO", 0x34, 1, 0), /* Dominican Republic */ - COUNTRY_CHPLAN_ENT("EC", 0x34, 1, 0), /* Ecuador */ - COUNTRY_CHPLAN_ENT("GT", 0x34, 1, 0), /* Guatemala */ - COUNTRY_CHPLAN_ENT("ID", 0x3D, 0, 0), /* Indonesia */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ - COUNTRY_CHPLAN_ENT("MX", 0x34, 1, 0), /* Mexico */ - COUNTRY_CHPLAN_ENT("MY", 0x47, 1, 0), /* Malaysia */ - COUNTRY_CHPLAN_ENT("NI", 0x34, 1, 0), /* Nicaragua */ - COUNTRY_CHPLAN_ENT("PA", 0x34, 1, 0), /* Panama */ - COUNTRY_CHPLAN_ENT("PE", 0x34, 1, 0), /* Peru */ - COUNTRY_CHPLAN_ENT("PR", 0x34, 1, 0), /* Puerto Rico */ - COUNTRY_CHPLAN_ENT("PY", 0x34, 1, 0), /* Paraguay */ - COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0), /* Taiwan */ - COUNTRY_CHPLAN_ENT("UA", 0x36, 0, 0), /* Ukraine */ - COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0), /* United States of America (USA) */ +static const struct country_chplan RTL8821AE_HMC_M2_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x34, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x30, 1), + COUNTRY_CHPLAN_ENT("CN", 0x51, 1), + COUNTRY_CHPLAN_ENT("CO", 0x34, 1), + COUNTRY_CHPLAN_ENT("CR", 0x34, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x34, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x34, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x34, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x3D, 0), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x34, 1), + COUNTRY_CHPLAN_ENT("MY", 0x47, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x34, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x34, 1), + COUNTRY_CHPLAN_ENT("PE", 0x34, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x34, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x34, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TT", 0x76, 1), + COUNTRY_CHPLAN_ENT("TW", 0x39, 1), + COUNTRY_CHPLAN_ENT("UA", 0x36, 0), + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), + COUNTRY_CHPLAN_ENT("US", 0x34, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8821AU) /* 2014 certify */ -static const struct country_chplan RTL8821AU_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("CA", 0x34, 1, 0), /* Canada */ - COUNTRY_CHPLAN_ENT("ID", 0x3D, 0, 0), /* Indonesia */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ - COUNTRY_CHPLAN_ENT("RU", 0x59, 0, 0), /* Russia(fac/gost), Kaliningrad */ - COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0), /* Taiwan */ - COUNTRY_CHPLAN_ENT("UA", 0x36, 0, 0), /* Ukraine */ - COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0), /* United States of America (USA) */ +static const struct country_chplan RTL8821AU_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x34, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x3D, 0), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 0), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("TW", 0x39, 1), + COUNTRY_CHPLAN_ENT("UA", 0x36, 0), + COUNTRY_CHPLAN_ENT("US", 0x34, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8812AENF_NGFF) /* 2014 certify */ -static const struct country_chplan RTL8812AENF_NGFF_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0), /* Taiwan */ - COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0), /* United States of America (USA) */ +static const struct country_chplan RTL8812AENF_NGFF_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("TW", 0x39, 1), + COUNTRY_CHPLAN_ENT("US", 0x34, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8812AEBT_HMC) /* 2013 certify */ -static const struct country_chplan RTL8812AEBT_HMC_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("CA", 0x34, 1, 0), /* Canada */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ - COUNTRY_CHPLAN_ENT("RU", 0x59, 0, 0), /* Russia(fac/gost), Kaliningrad */ - COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0), /* Taiwan */ - COUNTRY_CHPLAN_ENT("UA", 0x36, 0, 0), /* Ukraine */ - COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0), /* United States of America (USA) */ +static const struct country_chplan RTL8812AEBT_HMC_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x34, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 0), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("TW", 0x39, 1), + COUNTRY_CHPLAN_ENT("UA", 0x36, 0), + COUNTRY_CHPLAN_ENT("US", 0x34, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8188EE_HMC_M2) /* 2012 certify */ -static const struct country_chplan RTL8188EE_HMC_M2_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("AW", 0x34, 1, 0), /* Aruba */ - COUNTRY_CHPLAN_ENT("BB", 0x34, 1, 0), /* Barbados */ - COUNTRY_CHPLAN_ENT("CA", 0x20, 1, 0), /* Canada */ - COUNTRY_CHPLAN_ENT("CO", 0x34, 1, 0), /* Colombia */ - COUNTRY_CHPLAN_ENT("CR", 0x34, 1, 0), /* Costa Rica */ - COUNTRY_CHPLAN_ENT("DO", 0x34, 1, 0), /* Dominican Republic */ - COUNTRY_CHPLAN_ENT("EC", 0x34, 1, 0), /* Ecuador */ - COUNTRY_CHPLAN_ENT("GT", 0x34, 1, 0), /* Guatemala */ - COUNTRY_CHPLAN_ENT("HT", 0x34, 1, 0), /* Haiti */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ - COUNTRY_CHPLAN_ENT("MX", 0x34, 1, 0), /* Mexico */ - COUNTRY_CHPLAN_ENT("NI", 0x34, 1, 0), /* Nicaragua */ - COUNTRY_CHPLAN_ENT("PA", 0x34, 1, 0), /* Panama */ - COUNTRY_CHPLAN_ENT("PE", 0x34, 1, 0), /* Peru */ - COUNTRY_CHPLAN_ENT("PR", 0x34, 1, 0), /* Puerto Rico */ - COUNTRY_CHPLAN_ENT("PY", 0x34, 1, 0), /* Paraguay */ - COUNTRY_CHPLAN_ENT("SC", 0x34, 1, 0), /* Seychelles */ - COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0), /* Taiwan */ - COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0), /* United States of America (USA) */ - COUNTRY_CHPLAN_ENT("VC", 0x34, 1, 0), /* Saint Vincent and the Grenadines */ +static const struct country_chplan RTL8188EE_HMC_M2_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AM", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AW", 0x34, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BB", 0x34, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BF", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BI", 0x26, 1), + COUNTRY_CHPLAN_ENT("BJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BN", 0x47, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x20, 1), + COUNTRY_CHPLAN_ENT("CD", 0x26, 1), + COUNTRY_CHPLAN_ENT("CF", 0x26, 1), + COUNTRY_CHPLAN_ENT("CG", 0x26, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), + COUNTRY_CHPLAN_ENT("CM", 0x26, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CO", 0x34, 1), + COUNTRY_CHPLAN_ENT("CR", 0x34, 1), + COUNTRY_CHPLAN_ENT("CV", 0x26, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x34, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x34, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("ET", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GA", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GD", 0x76, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GM", 0x26, 1), + COUNTRY_CHPLAN_ENT("GN", 0x26, 1), + COUNTRY_CHPLAN_ENT("GQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x34, 1), + COUNTRY_CHPLAN_ENT("GW", 0x26, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HT", 0x34, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x5D, 1), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LR", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("ML", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MU", 0x26, 1), + COUNTRY_CHPLAN_ENT("MW", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x34, 1), + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NE", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x34, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NP", 0x48, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x34, 1), + COUNTRY_CHPLAN_ENT("PE", 0x34, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x34, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x34, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("RW", 0x26, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SC", 0x34, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SL", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("TD", 0x26, 1), + COUNTRY_CHPLAN_ENT("TG", 0x26, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TT", 0x76, 1), + COUNTRY_CHPLAN_ENT("TW", 0x39, 1), + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), + COUNTRY_CHPLAN_ENT("US", 0x34, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1), + COUNTRY_CHPLAN_ENT("VC", 0x34, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZM", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8723BE_HMC_M2) /* 2013 certify */ -static const struct country_chplan RTL8723BE_HMC_M2_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("AW", 0x34, 1, 0), /* Aruba */ - COUNTRY_CHPLAN_ENT("BS", 0x34, 1, 0), /* Bahamas */ - COUNTRY_CHPLAN_ENT("CA", 0x20, 1, 0), /* Canada */ - COUNTRY_CHPLAN_ENT("CO", 0x34, 1, 0), /* Colombia */ - COUNTRY_CHPLAN_ENT("CR", 0x34, 1, 0), /* Costa Rica */ - COUNTRY_CHPLAN_ENT("DO", 0x34, 1, 0), /* Dominican Republic */ - COUNTRY_CHPLAN_ENT("EC", 0x34, 1, 0), /* Ecuador */ - COUNTRY_CHPLAN_ENT("GT", 0x34, 1, 0), /* Guatemala */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ - COUNTRY_CHPLAN_ENT("MX", 0x34, 1, 0), /* Mexico */ - COUNTRY_CHPLAN_ENT("NI", 0x34, 1, 0), /* Nicaragua */ - COUNTRY_CHPLAN_ENT("PA", 0x34, 1, 0), /* Panama */ - COUNTRY_CHPLAN_ENT("PE", 0x34, 1, 0), /* Peru */ - COUNTRY_CHPLAN_ENT("PR", 0x34, 1, 0), /* Puerto Rico */ - COUNTRY_CHPLAN_ENT("PY", 0x34, 1, 0), /* Paraguay */ - COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0), /* Taiwan */ - COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0), /* United States of America (USA) */ +static const struct country_chplan RTL8723BE_HMC_M2_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AM", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AO", 0x47, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AW", 0x34, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BF", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BI", 0x26, 1), + COUNTRY_CHPLAN_ENT("BJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BS", 0x34, 1), + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x20, 1), + COUNTRY_CHPLAN_ENT("CD", 0x26, 1), + COUNTRY_CHPLAN_ENT("CF", 0x26, 1), + COUNTRY_CHPLAN_ENT("CG", 0x26, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), + COUNTRY_CHPLAN_ENT("CM", 0x26, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CO", 0x34, 1), + COUNTRY_CHPLAN_ENT("CR", 0x34, 1), + COUNTRY_CHPLAN_ENT("CV", 0x26, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x34, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x34, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("ET", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GA", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GD", 0x76, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GM", 0x26, 1), + COUNTRY_CHPLAN_ENT("GQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x34, 1), + COUNTRY_CHPLAN_ENT("GW", 0x26, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x5D, 1), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LR", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MG", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("ML", 0x26, 1), + COUNTRY_CHPLAN_ENT("MR", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MU", 0x26, 1), + COUNTRY_CHPLAN_ENT("MW", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x34, 1), + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NE", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x34, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NP", 0x48, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x34, 1), + COUNTRY_CHPLAN_ENT("PE", 0x34, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x34, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x34, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("RW", 0x26, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SL", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("SZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("TD", 0x26, 1), + COUNTRY_CHPLAN_ENT("TG", 0x26, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TT", 0x76, 1), + COUNTRY_CHPLAN_ENT("TW", 0x39, 1), + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), + COUNTRY_CHPLAN_ENT("US", 0x34, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZM", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8723BS_NGFF1216) /* 2014 certify */ -static const struct country_chplan RTL8723BS_NGFF1216_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("BB", 0x34, 1, 0), /* Barbados */ - COUNTRY_CHPLAN_ENT("CA", 0x20, 1, 0), /* Canada */ - COUNTRY_CHPLAN_ENT("CO", 0x34, 1, 0), /* Colombia */ - COUNTRY_CHPLAN_ENT("CR", 0x34, 1, 0), /* Costa Rica */ - COUNTRY_CHPLAN_ENT("DO", 0x34, 1, 0), /* Dominican Republic */ - COUNTRY_CHPLAN_ENT("EC", 0x34, 1, 0), /* Ecuador */ - COUNTRY_CHPLAN_ENT("GT", 0x34, 1, 0), /* Guatemala */ - COUNTRY_CHPLAN_ENT("HT", 0x34, 1, 0), /* Haiti */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ - COUNTRY_CHPLAN_ENT("MX", 0x34, 1, 0), /* Mexico */ - COUNTRY_CHPLAN_ENT("NI", 0x34, 1, 0), /* Nicaragua */ - COUNTRY_CHPLAN_ENT("PA", 0x34, 1, 0), /* Panama */ - COUNTRY_CHPLAN_ENT("PE", 0x34, 1, 0), /* Peru */ - COUNTRY_CHPLAN_ENT("PR", 0x34, 1, 0), /* Puerto Rico */ - COUNTRY_CHPLAN_ENT("PY", 0x34, 1, 0), /* Paraguay */ - COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0), /* Taiwan */ - COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0), /* United States of America (USA) */ +static const struct country_chplan RTL8723BS_NGFF1216_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AO", 0x47, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BB", 0x34, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x20, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CO", 0x34, 1), + COUNTRY_CHPLAN_ENT("CR", 0x34, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x34, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x34, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x34, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HT", 0x34, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x5D, 1), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("MQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x34, 1), + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x34, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NP", 0x48, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x34, 1), + COUNTRY_CHPLAN_ENT("PE", 0x34, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x34, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x34, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TT", 0x76, 1), + COUNTRY_CHPLAN_ENT("TW", 0x39, 1), + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), + COUNTRY_CHPLAN_ENT("US", 0x34, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("YE", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8192EEBT_HMC_M2) /* 2013 certify */ -static const struct country_chplan RTL8192EEBT_HMC_M2_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("AW", 0x34, 1, 0), /* Aruba */ - COUNTRY_CHPLAN_ENT("CA", 0x20, 1, 0), /* Canada */ - COUNTRY_CHPLAN_ENT("CO", 0x34, 1, 0), /* Colombia */ - COUNTRY_CHPLAN_ENT("CR", 0x34, 1, 0), /* Costa Rica */ - COUNTRY_CHPLAN_ENT("DO", 0x34, 1, 0), /* Dominican Republic */ - COUNTRY_CHPLAN_ENT("EC", 0x34, 1, 0), /* Ecuador */ - COUNTRY_CHPLAN_ENT("GT", 0x34, 1, 0), /* Guatemala */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ - COUNTRY_CHPLAN_ENT("MX", 0x34, 1, 0), /* Mexico */ - COUNTRY_CHPLAN_ENT("NI", 0x34, 1, 0), /* Nicaragua */ - COUNTRY_CHPLAN_ENT("PA", 0x34, 1, 0), /* Panama */ - COUNTRY_CHPLAN_ENT("PE", 0x34, 1, 0), /* Peru */ - COUNTRY_CHPLAN_ENT("PR", 0x34, 1, 0), /* Puerto Rico */ - COUNTRY_CHPLAN_ENT("PY", 0x34, 1, 0), /* Paraguay */ - COUNTRY_CHPLAN_ENT("SC", 0x34, 1, 0), /* Seychelles */ - COUNTRY_CHPLAN_ENT("ST", 0x34, 1, 0), /* Sao Tome and Principe */ - COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0), /* Taiwan */ - COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0), /* United States of America (USA) */ +static const struct country_chplan RTL8192EEBT_HMC_M2_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AM", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AO", 0x47, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AW", 0x34, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BF", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BI", 0x26, 1), + COUNTRY_CHPLAN_ENT("BJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x20, 1), + COUNTRY_CHPLAN_ENT("CD", 0x26, 1), + COUNTRY_CHPLAN_ENT("CF", 0x26, 1), + COUNTRY_CHPLAN_ENT("CG", 0x26, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), + COUNTRY_CHPLAN_ENT("CM", 0x26, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CO", 0x34, 1), + COUNTRY_CHPLAN_ENT("CR", 0x34, 1), + COUNTRY_CHPLAN_ENT("CV", 0x26, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x34, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x34, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("EH", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("ET", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GA", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GD", 0x76, 1), + COUNTRY_CHPLAN_ENT("GF", 0x26, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GM", 0x26, 1), + COUNTRY_CHPLAN_ENT("GQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x34, 1), + COUNTRY_CHPLAN_ENT("GW", 0x26, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x5D, 1), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LR", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("ML", 0x26, 1), + COUNTRY_CHPLAN_ENT("MR", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MU", 0x26, 1), + COUNTRY_CHPLAN_ENT("MW", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x34, 1), + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NE", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x34, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NP", 0x48, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x34, 1), + COUNTRY_CHPLAN_ENT("PE", 0x34, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x34, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x34, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("RW", 0x26, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SC", 0x34, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SL", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("ST", 0x34, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("TD", 0x26, 1), + COUNTRY_CHPLAN_ENT("TF", 0x26, 1), + COUNTRY_CHPLAN_ENT("TG", 0x26, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TT", 0x76, 1), + COUNTRY_CHPLAN_ENT("TW", 0x39, 1), + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), + COUNTRY_CHPLAN_ENT("US", 0x34, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("YT", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZM", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8723DE_NGFF1630) /* 2016 certify */ -static const struct country_chplan RTL8723DE_NGFF1630_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("CA", 0x2A, 1, 0), /* Canada */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ - COUNTRY_CHPLAN_ENT("MX", 0x34, 1, 0), /* Mexico */ +static const struct country_chplan RTL8723DE_NGFF1630_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x2A, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CO", 0x76, 1), + COUNTRY_CHPLAN_ENT("CR", 0x76, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x76, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x76, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x61, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x5D, 1), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("KZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x34, 1), + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NA", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x76, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x76, 1), + COUNTRY_CHPLAN_ENT("PE", 0x76, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x76, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x76, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TT", 0x76, 1), + COUNTRY_CHPLAN_ENT("TW", 0x76, 1), + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), + COUNTRY_CHPLAN_ENT("US", 0x76, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8822BE) /* 2016 certify */ -static const struct country_chplan RTL8822BE_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("ID", 0x3D, 0, 0), /* Indonesia */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ +static const struct country_chplan RTL8822BE_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AM", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AO", 0x47, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BB", 0x76, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BF", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BI", 0x26, 1), + COUNTRY_CHPLAN_ENT("BJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BM", 0x76, 1), + COUNTRY_CHPLAN_ENT("BN", 0x47, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BS", 0x76, 1), + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x2B, 1), + COUNTRY_CHPLAN_ENT("CD", 0x26, 1), + COUNTRY_CHPLAN_ENT("CF", 0x26, 1), + COUNTRY_CHPLAN_ENT("CG", 0x26, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), + COUNTRY_CHPLAN_ENT("CM", 0x26, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CO", 0x76, 1), + COUNTRY_CHPLAN_ENT("CR", 0x76, 1), + COUNTRY_CHPLAN_ENT("CV", 0x26, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x76, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x76, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("EH", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FJ", 0x76, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GA", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GE", 0x26, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GI", 0x26, 1), + COUNTRY_CHPLAN_ENT("GL", 0x26, 1), + COUNTRY_CHPLAN_ENT("GM", 0x26, 1), + COUNTRY_CHPLAN_ENT("GN", 0x26, 1), + COUNTRY_CHPLAN_ENT("GP", 0x26, 1), + COUNTRY_CHPLAN_ENT("GQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x61, 1), + COUNTRY_CHPLAN_ENT("GU", 0x76, 1), + COUNTRY_CHPLAN_ENT("GW", 0x26, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HT", 0x76, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x3D, 0), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("KZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LR", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MG", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("ML", 0x26, 1), + COUNTRY_CHPLAN_ENT("MO", 0x35, 1), + COUNTRY_CHPLAN_ENT("MQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("MR", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MU", 0x26, 1), + COUNTRY_CHPLAN_ENT("MW", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x4D, 1), + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NA", 0x26, 1), + COUNTRY_CHPLAN_ENT("NE", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x76, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NP", 0x48, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x76, 1), + COUNTRY_CHPLAN_ENT("PE", 0x76, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x76, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x76, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SC", 0x76, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SL", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("ST", 0x76, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("TD", 0x26, 1), + COUNTRY_CHPLAN_ENT("TF", 0x26, 1), + COUNTRY_CHPLAN_ENT("TG", 0x26, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TT", 0x76, 1), + COUNTRY_CHPLAN_ENT("TW", 0x76, 1), + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), + COUNTRY_CHPLAN_ENT("US", 0x76, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("YT", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZM", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8821CE) /* 2016 certify */ -static const struct country_chplan RTL8821CE_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("ID", 0x3D, 0, 0), /* Indonesia */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ +static const struct country_chplan RTL8821CE_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AM", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AO", 0x47, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BB", 0x76, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BF", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BI", 0x26, 1), + COUNTRY_CHPLAN_ENT("BJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BM", 0x76, 1), + COUNTRY_CHPLAN_ENT("BN", 0x47, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BS", 0x76, 1), + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x2B, 1), + COUNTRY_CHPLAN_ENT("CD", 0x26, 1), + COUNTRY_CHPLAN_ENT("CF", 0x26, 1), + COUNTRY_CHPLAN_ENT("CG", 0x26, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), + COUNTRY_CHPLAN_ENT("CM", 0x26, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CO", 0x76, 1), + COUNTRY_CHPLAN_ENT("CR", 0x76, 1), + COUNTRY_CHPLAN_ENT("CV", 0x26, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x76, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x76, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("EH", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("ET", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FJ", 0x76, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GA", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GE", 0x26, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GI", 0x26, 1), + COUNTRY_CHPLAN_ENT("GL", 0x26, 1), + COUNTRY_CHPLAN_ENT("GM", 0x26, 1), + COUNTRY_CHPLAN_ENT("GN", 0x26, 1), + COUNTRY_CHPLAN_ENT("GP", 0x26, 1), + COUNTRY_CHPLAN_ENT("GQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x61, 1), + COUNTRY_CHPLAN_ENT("GU", 0x76, 1), + COUNTRY_CHPLAN_ENT("GW", 0x26, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HT", 0x76, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x3D, 0), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("KZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LR", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MG", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("ML", 0x26, 1), + COUNTRY_CHPLAN_ENT("MO", 0x35, 1), + COUNTRY_CHPLAN_ENT("MQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("MR", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MU", 0x26, 1), + COUNTRY_CHPLAN_ENT("MW", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x4D, 1), + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NA", 0x26, 1), + COUNTRY_CHPLAN_ENT("NE", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x76, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NP", 0x48, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x76, 1), + COUNTRY_CHPLAN_ENT("PE", 0x76, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x76, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x76, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SC", 0x76, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SL", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("ST", 0x76, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("TD", 0x26, 1), + COUNTRY_CHPLAN_ENT("TF", 0x26, 1), + COUNTRY_CHPLAN_ENT("TG", 0x26, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TW", 0x76, 1), + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), + COUNTRY_CHPLAN_ENT("US", 0x76, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("YT", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZM", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8822CE) /* 2018 certify */ -static const struct country_chplan RTL8822CE_country_chplan_exc_map[] = { +static const struct country_chplan RTL8822CE_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AM", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AO", 0x47, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AW", 0x76, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BB", 0x76, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BF", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BI", 0x26, 1), + COUNTRY_CHPLAN_ENT("BJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BM", 0x76, 1), + COUNTRY_CHPLAN_ENT("BN", 0x47, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BS", 0x76, 1), + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x2B, 1), + COUNTRY_CHPLAN_ENT("CD", 0x26, 1), + COUNTRY_CHPLAN_ENT("CF", 0x26, 1), + COUNTRY_CHPLAN_ENT("CG", 0x26, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), + COUNTRY_CHPLAN_ENT("CM", 0x26, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CO", 0x76, 1), + COUNTRY_CHPLAN_ENT("CR", 0x76, 1), + COUNTRY_CHPLAN_ENT("CV", 0x26, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x76, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x76, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("EH", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("ET", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FJ", 0x76, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GA", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GE", 0x26, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GI", 0x26, 1), + COUNTRY_CHPLAN_ENT("GL", 0x26, 1), + COUNTRY_CHPLAN_ENT("GM", 0x26, 1), + COUNTRY_CHPLAN_ENT("GN", 0x26, 1), + COUNTRY_CHPLAN_ENT("GP", 0x26, 1), + COUNTRY_CHPLAN_ENT("GQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x61, 1), + COUNTRY_CHPLAN_ENT("GU", 0x76, 1), + COUNTRY_CHPLAN_ENT("GW", 0x26, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HT", 0x76, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KM", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x4B, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("KZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LR", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MG", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("ML", 0x26, 1), + COUNTRY_CHPLAN_ENT("MO", 0x35, 1), + COUNTRY_CHPLAN_ENT("MQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("MR", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MU", 0x26, 1), + COUNTRY_CHPLAN_ENT("MW", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x4D, 1), + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NA", 0x26, 1), + COUNTRY_CHPLAN_ENT("NE", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x76, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NP", 0x48, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x76, 1), + COUNTRY_CHPLAN_ENT("PE", 0x76, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x76, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x76, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SC", 0x76, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SL", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("ST", 0x76, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("SZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("TD", 0x26, 1), + COUNTRY_CHPLAN_ENT("TF", 0x26, 1), + COUNTRY_CHPLAN_ENT("TG", 0x26, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TW", 0x76, 1), + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), + COUNTRY_CHPLAN_ENT("US", 0x76, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("YT", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZM", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif /** - * rtw_def_module_get_chplan_from_country - - * @country_code: string of country code - * @return: - * Return NULL for case referring to common map + * rtw_def_module_country_chplan_map - + * @hal_map: returned map + * @return: size of map */ -static const struct country_chplan *rtw_def_module_get_chplan_from_country(const char *country_code) +static u16 rtw_def_module_country_chplan_map(const struct country_chplan **hal_map) { - const struct country_chplan *ent = NULL; - const struct country_chplan *hal_map = NULL; u16 hal_map_sz = 0; - int i; /* TODO: runtime selection for multi driver */ #if (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8821AE_HMC_M2) - hal_map = RTL8821AE_HMC_M2_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8821AE_HMC_M2_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8821AE_HMC_M2_country_chplan_map; + hal_map_sz = sizeof(RTL8821AE_HMC_M2_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8821AU) - hal_map = RTL8821AU_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8821AU_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8821AU_country_chplan_map; + hal_map_sz = sizeof(RTL8821AU_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8812AENF_NGFF) - hal_map = RTL8812AENF_NGFF_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8812AENF_NGFF_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8812AENF_NGFF_country_chplan_map; + hal_map_sz = sizeof(RTL8812AENF_NGFF_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8812AEBT_HMC) - hal_map = RTL8812AEBT_HMC_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8812AEBT_HMC_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8812AEBT_HMC_country_chplan_map; + hal_map_sz = sizeof(RTL8812AEBT_HMC_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8188EE_HMC_M2) - hal_map = RTL8188EE_HMC_M2_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8188EE_HMC_M2_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8188EE_HMC_M2_country_chplan_map; + hal_map_sz = sizeof(RTL8188EE_HMC_M2_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8723BE_HMC_M2) - hal_map = RTL8723BE_HMC_M2_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8723BE_HMC_M2_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8723BE_HMC_M2_country_chplan_map; + hal_map_sz = sizeof(RTL8723BE_HMC_M2_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8723BS_NGFF1216) - hal_map = RTL8723BS_NGFF1216_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8723BS_NGFF1216_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8723BS_NGFF1216_country_chplan_map; + hal_map_sz = sizeof(RTL8723BS_NGFF1216_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8192EEBT_HMC_M2) - hal_map = RTL8192EEBT_HMC_M2_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8192EEBT_HMC_M2_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8192EEBT_HMC_M2_country_chplan_map; + hal_map_sz = sizeof(RTL8192EEBT_HMC_M2_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8723DE_NGFF1630) - hal_map = RTL8723DE_NGFF1630_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8723DE_NGFF1630_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8723DE_NGFF1630_country_chplan_map; + hal_map_sz = sizeof(RTL8723DE_NGFF1630_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8822BE) - hal_map = RTL8822BE_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8822BE_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8822BE_country_chplan_map; + hal_map_sz = sizeof(RTL8822BE_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8821CE) - hal_map = RTL8821CE_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8821CE_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8821CE_country_chplan_map; + hal_map_sz = sizeof(RTL8821CE_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8822CE) - hal_map = RTL8822CE_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8822CE_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8822CE_country_chplan_map; + hal_map_sz = sizeof(RTL8822CE_country_chplan_map) / sizeof(struct country_chplan); #endif - if (hal_map == NULL || hal_map_sz == 0) - goto exit; - - for (i = 0; i < hal_map_sz; i++) { - if (strncmp(country_code, hal_map[i].alpha2, 2) == 0) { - ent = &hal_map[i]; - break; - } - } - -exit: - return ent; + return hal_map_sz; } -#endif /* CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP or RTW_DEF_MODULE_REGULATORY_CERT */ +#else static const struct country_chplan country_chplan_map[] = { - COUNTRY_CHPLAN_ENT("00", 0x7F, 1, 0x000), /* Unspecified */ - COUNTRY_CHPLAN_ENT("AD", 0x26, 1, 0x000), /* Andorra */ - COUNTRY_CHPLAN_ENT("AE", 0x35, 1, 0xFFB), /* United Arab Emirates */ - COUNTRY_CHPLAN_ENT("AF", 0x42, 1, 0x000), /* Afghanistan */ - COUNTRY_CHPLAN_ENT("AG", 0x76, 1, 0x000), /* Antigua & Barbuda */ - COUNTRY_CHPLAN_ENT("AI", 0x26, 1, 0x000), /* Anguilla(UK) */ - COUNTRY_CHPLAN_ENT("AL", 0x26, 1, 0xFF1), /* Albania */ - COUNTRY_CHPLAN_ENT("AM", 0x26, 1, 0xEB0), /* Armenia */ - COUNTRY_CHPLAN_ENT("AN", 0x76, 1, 0xFF1), /* Netherlands Antilles */ - COUNTRY_CHPLAN_ENT("AO", 0x47, 1, 0xEE0), /* Angola */ - COUNTRY_CHPLAN_ENT("AQ", 0x26, 1, 0x000), /* Antarctica */ - COUNTRY_CHPLAN_ENT("AR", 0x61, 1, 0xFF3), /* Argentina */ - COUNTRY_CHPLAN_ENT("AS", 0x76, 1, 0x000), /* American Samoa */ - COUNTRY_CHPLAN_ENT("AT", 0x26, 1, 0xFFB), /* Austria */ - COUNTRY_CHPLAN_ENT("AU", 0x45, 1, 0xFFB), /* Australia */ - COUNTRY_CHPLAN_ENT("AW", 0x76, 1, 0x8B0), /* Aruba */ - COUNTRY_CHPLAN_ENT("AZ", 0x26, 1, 0xFF1), /* Azerbaijan */ - COUNTRY_CHPLAN_ENT("BA", 0x26, 1, 0xFF1), /* Bosnia & Herzegovina */ - COUNTRY_CHPLAN_ENT("BB", 0x76, 1, 0xE50), /* Barbados */ - COUNTRY_CHPLAN_ENT("BD", 0x26, 1, 0xFF1), /* Bangladesh */ - COUNTRY_CHPLAN_ENT("BE", 0x26, 1, 0xFFB), /* Belgium */ - COUNTRY_CHPLAN_ENT("BF", 0x26, 1, 0xEB0), /* Burkina Faso */ - COUNTRY_CHPLAN_ENT("BG", 0x26, 1, 0xFF1), /* Bulgaria */ - COUNTRY_CHPLAN_ENT("BH", 0x48, 1, 0xFF1), /* Bahrain */ - COUNTRY_CHPLAN_ENT("BI", 0x26, 1, 0xEB0), /* Burundi */ - COUNTRY_CHPLAN_ENT("BJ", 0x26, 1, 0xEB0), /* Benin */ - COUNTRY_CHPLAN_ENT("BM", 0x76, 1, 0xE00), /* Bermuda (UK) */ - COUNTRY_CHPLAN_ENT("BN", 0x47, 1, 0xE10), /* Brunei */ - COUNTRY_CHPLAN_ENT("BO", 0x73, 1, 0xFF1), /* Bolivia */ - COUNTRY_CHPLAN_ENT("BR", 0x62, 1, 0xFF1), /* Brazil */ - COUNTRY_CHPLAN_ENT("BS", 0x76, 1, 0xE20), /* Bahamas */ - COUNTRY_CHPLAN_ENT("BT", 0x26, 1, 0x000), /* Bhutan */ - COUNTRY_CHPLAN_ENT("BV", 0x26, 1, 0x000), /* Bouvet Island (Norway) */ - COUNTRY_CHPLAN_ENT("BW", 0x35, 1, 0xEF1), /* Botswana */ - COUNTRY_CHPLAN_ENT("BY", 0x26, 1, 0xFF1), /* Belarus */ - COUNTRY_CHPLAN_ENT("BZ", 0x76, 1, 0x000), /* Belize */ - COUNTRY_CHPLAN_ENT("CA", 0x2B, 1, 0xFFB), /* Canada */ - COUNTRY_CHPLAN_ENT("CC", 0x26, 1, 0x000), /* Cocos (Keeling) Islands (Australia) */ - COUNTRY_CHPLAN_ENT("CD", 0x26, 1, 0xEB0), /* Congo, Republic of the */ - COUNTRY_CHPLAN_ENT("CF", 0x26, 1, 0xEB0), /* Central African Republic */ - COUNTRY_CHPLAN_ENT("CG", 0x26, 1, 0xEB0), /* Congo, Democratic Republic of the. Zaire */ - COUNTRY_CHPLAN_ENT("CH", 0x26, 1, 0xFFB), /* Switzerland */ - COUNTRY_CHPLAN_ENT("CI", 0x42, 1, 0xFF1), /* Cote d'Ivoire */ - COUNTRY_CHPLAN_ENT("CK", 0x26, 1, 0x000), /* Cook Islands */ - COUNTRY_CHPLAN_ENT("CL", 0x2D, 1, 0xFF1), /* Chile */ - COUNTRY_CHPLAN_ENT("CM", 0x26, 1, 0xEB0), /* Cameroon */ - COUNTRY_CHPLAN_ENT("CN", 0x48, 1, 0xFFB), /* China */ - COUNTRY_CHPLAN_ENT("CO", 0x76, 1, 0xFF1), /* Colombia */ - COUNTRY_CHPLAN_ENT("CR", 0x76, 1, 0xFF1), /* Costa Rica */ - COUNTRY_CHPLAN_ENT("CV", 0x26, 1, 0xEB0), /* Cape Verde */ - COUNTRY_CHPLAN_ENT("CX", 0x45, 1, 0x000), /* Christmas Island (Australia) */ - COUNTRY_CHPLAN_ENT("CY", 0x26, 1, 0xFFB), /* Cyprus */ - COUNTRY_CHPLAN_ENT("CZ", 0x26, 1, 0xFFB), /* Czech Republic */ - COUNTRY_CHPLAN_ENT("DE", 0x26, 1, 0xFFB), /* Germany */ - COUNTRY_CHPLAN_ENT("DJ", 0x26, 1, 0xE80), /* Djibouti */ - COUNTRY_CHPLAN_ENT("DK", 0x26, 1, 0xFFB), /* Denmark */ - COUNTRY_CHPLAN_ENT("DM", 0x76, 1, 0x000), /* Dominica */ - COUNTRY_CHPLAN_ENT("DO", 0x76, 1, 0xFF1), /* Dominican Republic */ - COUNTRY_CHPLAN_ENT("DZ", 0x26, 1, 0xFF1), /* Algeria */ - COUNTRY_CHPLAN_ENT("EC", 0x76, 1, 0xFF1), /* Ecuador */ - COUNTRY_CHPLAN_ENT("EE", 0x26, 1, 0xFFB), /* Estonia */ - COUNTRY_CHPLAN_ENT("EG", 0x47, 1, 0xFF1), /* Egypt */ - COUNTRY_CHPLAN_ENT("EH", 0x47, 1, 0xE80), /* Western Sahara */ - COUNTRY_CHPLAN_ENT("ER", 0x26, 1, 0x000), /* Eritrea */ - COUNTRY_CHPLAN_ENT("ES", 0x26, 1, 0xFFB), /* Spain, Canary Islands, Ceuta, Melilla */ - COUNTRY_CHPLAN_ENT("ET", 0x26, 1, 0xCB0), /* Ethiopia */ - COUNTRY_CHPLAN_ENT("FI", 0x26, 1, 0xFFB), /* Finland */ - COUNTRY_CHPLAN_ENT("FJ", 0x76, 1, 0xE00), /* Fiji */ - COUNTRY_CHPLAN_ENT("FK", 0x26, 1, 0x000), /* Falkland Islands (Islas Malvinas) (UK) */ - COUNTRY_CHPLAN_ENT("FM", 0x76, 1, 0x000), /* Micronesia, Federated States of (USA) */ - COUNTRY_CHPLAN_ENT("FO", 0x26, 1, 0x000), /* Faroe Islands (Denmark) */ - COUNTRY_CHPLAN_ENT("FR", 0x26, 1, 0xFFB), /* France */ - COUNTRY_CHPLAN_ENT("GA", 0x26, 1, 0xEB0), /* Gabon */ - COUNTRY_CHPLAN_ENT("GB", 0x26, 1, 0xFFB), /* Great Britain (United Kingdom; England) */ - COUNTRY_CHPLAN_ENT("GD", 0x76, 1, 0x0B0), /* Grenada */ - COUNTRY_CHPLAN_ENT("GE", 0x26, 1, 0xE00), /* Georgia */ - COUNTRY_CHPLAN_ENT("GF", 0x26, 1, 0x080), /* French Guiana */ - COUNTRY_CHPLAN_ENT("GG", 0x26, 1, 0x000), /* Guernsey (UK) */ - COUNTRY_CHPLAN_ENT("GH", 0x26, 1, 0xFF1), /* Ghana */ - COUNTRY_CHPLAN_ENT("GI", 0x26, 1, 0xE00), /* Gibraltar (UK) */ - COUNTRY_CHPLAN_ENT("GL", 0x26, 1, 0xE00), /* Greenland (Denmark) */ - COUNTRY_CHPLAN_ENT("GM", 0x26, 1, 0xEB0), /* Gambia */ - COUNTRY_CHPLAN_ENT("GN", 0x26, 1, 0xE10), /* Guinea */ - COUNTRY_CHPLAN_ENT("GP", 0x26, 1, 0xE00), /* Guadeloupe (France) */ - COUNTRY_CHPLAN_ENT("GQ", 0x26, 1, 0xEB0), /* Equatorial Guinea */ - COUNTRY_CHPLAN_ENT("GR", 0x26, 1, 0xFFB), /* Greece */ - COUNTRY_CHPLAN_ENT("GS", 0x26, 1, 0x000), /* South Georgia and the Sandwich Islands (UK) */ - COUNTRY_CHPLAN_ENT("GT", 0x61, 1, 0xFF1), /* Guatemala */ - COUNTRY_CHPLAN_ENT("GU", 0x76, 1, 0xE00), /* Guam (USA) */ - COUNTRY_CHPLAN_ENT("GW", 0x26, 1, 0xEB0), /* Guinea-Bissau */ - COUNTRY_CHPLAN_ENT("GY", 0x44, 1, 0x000), /* Guyana */ - COUNTRY_CHPLAN_ENT("HK", 0x35, 1, 0xFFB), /* Hong Kong */ - COUNTRY_CHPLAN_ENT("HM", 0x45, 1, 0x000), /* Heard and McDonald Islands (Australia) */ - COUNTRY_CHPLAN_ENT("HN", 0x32, 1, 0xFF1), /* Honduras */ - COUNTRY_CHPLAN_ENT("HR", 0x26, 1, 0xFF9), /* Croatia */ - COUNTRY_CHPLAN_ENT("HT", 0x76, 1, 0xE50), /* Haiti */ - COUNTRY_CHPLAN_ENT("HU", 0x26, 1, 0xFFB), /* Hungary */ - COUNTRY_CHPLAN_ENT("ID", 0x5D, 1, 0x7F3), /* Indonesia */ - COUNTRY_CHPLAN_ENT("IE", 0x26, 1, 0xFFB), /* Ireland */ - COUNTRY_CHPLAN_ENT("IL", 0x47, 1, 0xFF1), /* Israel */ - COUNTRY_CHPLAN_ENT("IM", 0x26, 1, 0x000), /* Isle of Man (UK) */ - COUNTRY_CHPLAN_ENT("IN", 0x48, 1, 0xFF1), /* India */ - COUNTRY_CHPLAN_ENT("IO", 0x26, 1, 0x000), /* British Indian Ocean Territory (UK) */ - COUNTRY_CHPLAN_ENT("IQ", 0x26, 1, 0x000), /* Iraq */ - COUNTRY_CHPLAN_ENT("IR", 0x26, 0, 0x000), /* Iran */ - COUNTRY_CHPLAN_ENT("IS", 0x26, 1, 0xFFB), /* Iceland */ - COUNTRY_CHPLAN_ENT("IT", 0x26, 1, 0xFFB), /* Italy */ - COUNTRY_CHPLAN_ENT("JE", 0x26, 1, 0x000), /* Jersey (UK) */ - COUNTRY_CHPLAN_ENT("JM", 0x32, 1, 0xFF1), /* Jamaica */ - COUNTRY_CHPLAN_ENT("JO", 0x49, 1, 0xFFB), /* Jordan */ - COUNTRY_CHPLAN_ENT("JP", 0x27, 1, 0xFFF), /* Japan- Telec */ - COUNTRY_CHPLAN_ENT("KE", 0x47, 1, 0xFF9), /* Kenya */ - COUNTRY_CHPLAN_ENT("KG", 0x26, 1, 0xFF1), /* Kyrgyzstan */ - COUNTRY_CHPLAN_ENT("KH", 0x26, 1, 0xFF1), /* Cambodia */ - COUNTRY_CHPLAN_ENT("KI", 0x26, 1, 0x000), /* Kiribati */ - COUNTRY_CHPLAN_ENT("KM", 0x26, 1, 0x800), /* Comoros */ - COUNTRY_CHPLAN_ENT("KN", 0x76, 1, 0x000), /* Saint Kitts and Nevis */ - COUNTRY_CHPLAN_ENT("KR", 0x4B, 1, 0xFFB), /* South Korea */ - COUNTRY_CHPLAN_ENT("KW", 0x47, 1, 0xFFB), /* Kuwait */ - COUNTRY_CHPLAN_ENT("KY", 0x76, 1, 0x000), /* Cayman Islands (UK) */ - COUNTRY_CHPLAN_ENT("KZ", 0x26, 1, 0xF00), /* Kazakhstan */ - COUNTRY_CHPLAN_ENT("LA", 0x26, 1, 0x000), /* Laos */ - COUNTRY_CHPLAN_ENT("LB", 0x26, 1, 0xFF1), /* Lebanon */ - COUNTRY_CHPLAN_ENT("LC", 0x76, 1, 0x000), /* Saint Lucia */ - COUNTRY_CHPLAN_ENT("LI", 0x26, 1, 0xFFB), /* Liechtenstein */ - COUNTRY_CHPLAN_ENT("LK", 0x26, 1, 0xFF1), /* Sri Lanka */ - COUNTRY_CHPLAN_ENT("LR", 0x26, 1, 0xEB0), /* Liberia */ - COUNTRY_CHPLAN_ENT("LS", 0x26, 1, 0xFF1), /* Lesotho */ - COUNTRY_CHPLAN_ENT("LT", 0x26, 1, 0xFFB), /* Lithuania */ - COUNTRY_CHPLAN_ENT("LU", 0x26, 1, 0xFFB), /* Luxembourg */ - COUNTRY_CHPLAN_ENT("LV", 0x26, 1, 0xFFB), /* Latvia */ - COUNTRY_CHPLAN_ENT("LY", 0x26, 1, 0x000), /* Libya */ - COUNTRY_CHPLAN_ENT("MA", 0x47, 1, 0xFF1), /* Morocco */ - COUNTRY_CHPLAN_ENT("MC", 0x26, 1, 0xFFB), /* Monaco */ - COUNTRY_CHPLAN_ENT("MD", 0x26, 1, 0xFF1), /* Moldova */ - COUNTRY_CHPLAN_ENT("ME", 0x26, 1, 0xFF1), /* Montenegro */ - COUNTRY_CHPLAN_ENT("MF", 0x76, 1, 0x000), /* Saint Martin */ - COUNTRY_CHPLAN_ENT("MG", 0x26, 1, 0xE20), /* Madagascar */ - COUNTRY_CHPLAN_ENT("MH", 0x76, 1, 0x000), /* Marshall Islands (USA) */ - COUNTRY_CHPLAN_ENT("MK", 0x26, 1, 0xFF1), /* Republic of Macedonia (FYROM) */ - COUNTRY_CHPLAN_ENT("ML", 0x26, 1, 0xEB0), /* Mali */ - COUNTRY_CHPLAN_ENT("MM", 0x26, 1, 0x000), /* Burma (Myanmar) */ - COUNTRY_CHPLAN_ENT("MN", 0x26, 1, 0x000), /* Mongolia */ - COUNTRY_CHPLAN_ENT("MO", 0x35, 1, 0xE00), /* Macau */ - COUNTRY_CHPLAN_ENT("MP", 0x76, 1, 0x000), /* Northern Mariana Islands (USA) */ - COUNTRY_CHPLAN_ENT("MQ", 0x26, 1, 0xE40), /* Martinique (France) */ - COUNTRY_CHPLAN_ENT("MR", 0x26, 1, 0xEA0), /* Mauritania */ - COUNTRY_CHPLAN_ENT("MS", 0x26, 1, 0x000), /* Montserrat (UK) */ - COUNTRY_CHPLAN_ENT("MT", 0x26, 1, 0xFFB), /* Malta */ - COUNTRY_CHPLAN_ENT("MU", 0x26, 1, 0xEB0), /* Mauritius */ - COUNTRY_CHPLAN_ENT("MV", 0x47, 1, 0x000), /* Maldives */ - COUNTRY_CHPLAN_ENT("MW", 0x26, 1, 0xEB0), /* Malawi */ - COUNTRY_CHPLAN_ENT("MX", 0x4D, 1, 0xFF1), /* Mexico */ - COUNTRY_CHPLAN_ENT("MY", 0x63, 1, 0xFF1), /* Malaysia */ - COUNTRY_CHPLAN_ENT("MZ", 0x26, 1, 0xFF1), /* Mozambique */ - COUNTRY_CHPLAN_ENT("NA", 0x26, 1, 0xF00), /* Namibia */ - COUNTRY_CHPLAN_ENT("NC", 0x26, 1, 0x000), /* New Caledonia */ - COUNTRY_CHPLAN_ENT("NE", 0x26, 1, 0xEB0), /* Niger */ - COUNTRY_CHPLAN_ENT("NF", 0x45, 1, 0x000), /* Norfolk Island (Australia) */ - COUNTRY_CHPLAN_ENT("NG", 0x75, 1, 0xFF9), /* Nigeria */ - COUNTRY_CHPLAN_ENT("NI", 0x76, 1, 0xFF1), /* Nicaragua */ - COUNTRY_CHPLAN_ENT("NL", 0x26, 1, 0xFFB), /* Netherlands */ - COUNTRY_CHPLAN_ENT("NO", 0x26, 1, 0xFFB), /* Norway */ - COUNTRY_CHPLAN_ENT("NP", 0x48, 1, 0xEF0), /* Nepal */ - COUNTRY_CHPLAN_ENT("NR", 0x26, 1, 0x000), /* Nauru */ - COUNTRY_CHPLAN_ENT("NU", 0x45, 1, 0x000), /* Niue */ - COUNTRY_CHPLAN_ENT("NZ", 0x45, 1, 0xFFB), /* New Zealand */ - COUNTRY_CHPLAN_ENT("OM", 0x26, 1, 0xFF9), /* Oman */ - COUNTRY_CHPLAN_ENT("PA", 0x76, 1, 0xFF1), /* Panama */ - COUNTRY_CHPLAN_ENT("PE", 0x76, 1, 0xFF1), /* Peru */ - COUNTRY_CHPLAN_ENT("PF", 0x26, 1, 0x000), /* French Polynesia (France) */ - COUNTRY_CHPLAN_ENT("PG", 0x35, 1, 0xFF1), /* Papua New Guinea */ - COUNTRY_CHPLAN_ENT("PH", 0x35, 1, 0xFF1), /* Philippines */ - COUNTRY_CHPLAN_ENT("PK", 0x51, 1, 0xFF1), /* Pakistan */ - COUNTRY_CHPLAN_ENT("PL", 0x26, 1, 0xFFB), /* Poland */ - COUNTRY_CHPLAN_ENT("PM", 0x26, 1, 0x000), /* Saint Pierre and Miquelon (France) */ - COUNTRY_CHPLAN_ENT("PR", 0x76, 1, 0xFF1), /* Puerto Rico */ - COUNTRY_CHPLAN_ENT("PT", 0x26, 1, 0xFFB), /* Portugal */ - COUNTRY_CHPLAN_ENT("PW", 0x76, 1, 0x000), /* Palau */ - COUNTRY_CHPLAN_ENT("PY", 0x76, 1, 0xFF1), /* Paraguay */ - COUNTRY_CHPLAN_ENT("QA", 0x35, 1, 0xFF9), /* Qatar */ - COUNTRY_CHPLAN_ENT("RE", 0x26, 1, 0x000), /* Reunion (France) */ - COUNTRY_CHPLAN_ENT("RO", 0x26, 1, 0xFF1), /* Romania */ - COUNTRY_CHPLAN_ENT("RS", 0x26, 1, 0xFF1), /* Serbia, Kosovo */ - COUNTRY_CHPLAN_ENT("RU", 0x59, 1, 0xFFB), /* Russia(fac/gost), Kaliningrad */ - COUNTRY_CHPLAN_ENT("RW", 0x26, 1, 0x0B0), /* Rwanda */ - COUNTRY_CHPLAN_ENT("SA", 0x35, 1, 0xFFB), /* Saudi Arabia */ - COUNTRY_CHPLAN_ENT("SB", 0x26, 1, 0x000), /* Solomon Islands */ - COUNTRY_CHPLAN_ENT("SC", 0x76, 1, 0xE90), /* Seychelles */ - COUNTRY_CHPLAN_ENT("SE", 0x26, 1, 0xFFB), /* Sweden */ - COUNTRY_CHPLAN_ENT("SG", 0x35, 1, 0xFFB), /* Singapore */ - COUNTRY_CHPLAN_ENT("SH", 0x26, 1, 0x000), /* Saint Helena (UK) */ - COUNTRY_CHPLAN_ENT("SI", 0x26, 1, 0xFFB), /* Slovenia */ - COUNTRY_CHPLAN_ENT("SJ", 0x26, 1, 0x000), /* Svalbard (Norway) */ - COUNTRY_CHPLAN_ENT("SK", 0x26, 1, 0xFFB), /* Slovakia */ - COUNTRY_CHPLAN_ENT("SL", 0x26, 1, 0xEB0), /* Sierra Leone */ - COUNTRY_CHPLAN_ENT("SM", 0x26, 1, 0x000), /* San Marino */ - COUNTRY_CHPLAN_ENT("SN", 0x26, 1, 0xFF1), /* Senegal */ - COUNTRY_CHPLAN_ENT("SO", 0x26, 1, 0x000), /* Somalia */ - COUNTRY_CHPLAN_ENT("SR", 0x74, 1, 0x000), /* Suriname */ - COUNTRY_CHPLAN_ENT("ST", 0x76, 1, 0xE80), /* Sao Tome and Principe */ - COUNTRY_CHPLAN_ENT("SV", 0x30, 1, 0xFF1), /* El Salvador */ - COUNTRY_CHPLAN_ENT("SX", 0x76, 1, 0x000), /* Sint Marteen */ - COUNTRY_CHPLAN_ENT("SZ", 0x26, 1, 0x820), /* Swaziland */ - COUNTRY_CHPLAN_ENT("TC", 0x26, 1, 0x000), /* Turks and Caicos Islands (UK) */ - COUNTRY_CHPLAN_ENT("TD", 0x26, 1, 0xEB0), /* Chad */ - COUNTRY_CHPLAN_ENT("TF", 0x26, 1, 0xE80), /* French Southern and Antarctic Lands (FR Southern Territories) */ - COUNTRY_CHPLAN_ENT("TG", 0x26, 1, 0xEB0), /* Togo */ - COUNTRY_CHPLAN_ENT("TH", 0x35, 1, 0xFF1), /* Thailand */ - COUNTRY_CHPLAN_ENT("TJ", 0x26, 1, 0xE40), /* Tajikistan */ - COUNTRY_CHPLAN_ENT("TK", 0x45, 1, 0x000), /* Tokelau */ - COUNTRY_CHPLAN_ENT("TM", 0x26, 1, 0x000), /* Turkmenistan */ - COUNTRY_CHPLAN_ENT("TN", 0x47, 1, 0xFF1), /* Tunisia */ - COUNTRY_CHPLAN_ENT("TO", 0x26, 1, 0x000), /* Tonga */ - COUNTRY_CHPLAN_ENT("TR", 0x26, 1, 0xFF1), /* Turkey, Northern Cyprus */ - COUNTRY_CHPLAN_ENT("TT", 0x76, 1, 0x3F1), /* Trinidad & Tobago */ - COUNTRY_CHPLAN_ENT("TV", 0x21, 0, 0x000), /* Tuvalu */ - COUNTRY_CHPLAN_ENT("TW", 0x76, 1, 0xFFF), /* Taiwan */ - COUNTRY_CHPLAN_ENT("TZ", 0x26, 1, 0xEF0), /* Tanzania */ - COUNTRY_CHPLAN_ENT("UA", 0x36, 1, 0xFFB), /* Ukraine */ - COUNTRY_CHPLAN_ENT("UG", 0x26, 1, 0xEF1), /* Uganda */ - COUNTRY_CHPLAN_ENT("US", 0x76, 1, 0xFFF), /* United States of America (USA) */ - COUNTRY_CHPLAN_ENT("UY", 0x30, 1, 0xFF1), /* Uruguay */ - COUNTRY_CHPLAN_ENT("UZ", 0x47, 1, 0xEF0), /* Uzbekistan */ - COUNTRY_CHPLAN_ENT("VA", 0x26, 1, 0x000), /* Holy See (Vatican City) */ - COUNTRY_CHPLAN_ENT("VC", 0x76, 1, 0x010), /* Saint Vincent and the Grenadines */ - COUNTRY_CHPLAN_ENT("VE", 0x30, 1, 0xFF1), /* Venezuela */ - COUNTRY_CHPLAN_ENT("VG", 0x76, 1, 0x000), /* British Virgin Islands (UK) */ - COUNTRY_CHPLAN_ENT("VI", 0x76, 1, 0x000), /* United States Virgin Islands (USA) */ - COUNTRY_CHPLAN_ENT("VN", 0x35, 1, 0xFF1), /* Vietnam */ - COUNTRY_CHPLAN_ENT("VU", 0x26, 1, 0x000), /* Vanuatu */ - COUNTRY_CHPLAN_ENT("WF", 0x26, 1, 0x000), /* Wallis and Futuna (France) */ - COUNTRY_CHPLAN_ENT("WS", 0x76, 1, 0x000), /* Samoa */ - COUNTRY_CHPLAN_ENT("YE", 0x26, 1, 0x040), /* Yemen */ - COUNTRY_CHPLAN_ENT("YT", 0x26, 1, 0xE80), /* Mayotte (France) */ - COUNTRY_CHPLAN_ENT("ZA", 0x35, 1, 0xFF1), /* South Africa */ - COUNTRY_CHPLAN_ENT("ZM", 0x26, 1, 0xEB0), /* Zambia */ - COUNTRY_CHPLAN_ENT("ZW", 0x26, 1, 0xFF1), /* Zimbabwe */ + COUNTRY_CHPLAN_ENT("AD", 0x26, 1), /* Andorra */ + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), /* United Arab Emirates */ + COUNTRY_CHPLAN_ENT("AF", 0x42, 1), /* Afghanistan */ + COUNTRY_CHPLAN_ENT("AG", 0x76, 1), /* Antigua & Barbuda */ + COUNTRY_CHPLAN_ENT("AI", 0x26, 1), /* Anguilla(UK) */ + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), /* Albania */ + COUNTRY_CHPLAN_ENT("AM", 0x26, 1), /* Armenia */ + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), /* Netherlands Antilles */ + COUNTRY_CHPLAN_ENT("AO", 0x47, 1), /* Angola */ + COUNTRY_CHPLAN_ENT("AQ", 0x26, 1), /* Antarctica */ + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), /* Argentina */ + COUNTRY_CHPLAN_ENT("AS", 0x76, 1), /* American Samoa */ + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), /* Austria */ + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), /* Australia */ + COUNTRY_CHPLAN_ENT("AW", 0x76, 1), /* Aruba */ + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), /* Azerbaijan */ + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), /* Bosnia & Herzegovina */ + COUNTRY_CHPLAN_ENT("BB", 0x76, 1), /* Barbados */ + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), /* Bangladesh */ + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), /* Belgium */ + COUNTRY_CHPLAN_ENT("BF", 0x26, 1), /* Burkina Faso */ + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), /* Bulgaria */ + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), /* Bahrain */ + COUNTRY_CHPLAN_ENT("BI", 0x26, 1), /* Burundi */ + COUNTRY_CHPLAN_ENT("BJ", 0x26, 1), /* Benin */ + COUNTRY_CHPLAN_ENT("BM", 0x76, 1), /* Bermuda (UK) */ + COUNTRY_CHPLAN_ENT("BN", 0x47, 1), /* Brunei */ + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), /* Bolivia */ + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), /* Brazil */ + COUNTRY_CHPLAN_ENT("BS", 0x76, 1), /* Bahamas */ + COUNTRY_CHPLAN_ENT("BT", 0x26, 1), /* Bhutan */ + COUNTRY_CHPLAN_ENT("BV", 0x26, 1), /* Bouvet Island (Norway) */ + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), /* Botswana */ + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), /* Belarus */ + COUNTRY_CHPLAN_ENT("BZ", 0x76, 1), /* Belize */ + COUNTRY_CHPLAN_ENT("CA", 0x2B, 1), /* Canada */ + COUNTRY_CHPLAN_ENT("CC", 0x26, 1), /* Cocos (Keeling) Islands (Australia) */ + COUNTRY_CHPLAN_ENT("CD", 0x26, 1), /* Congo, Republic of the */ + COUNTRY_CHPLAN_ENT("CF", 0x26, 1), /* Central African Republic */ + COUNTRY_CHPLAN_ENT("CG", 0x26, 1), /* Congo, Democratic Republic of the. Zaire */ + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), /* Switzerland */ + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), /* Cote d'Ivoire */ + COUNTRY_CHPLAN_ENT("CK", 0x26, 1), /* Cook Islands */ + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), /* Chile */ + COUNTRY_CHPLAN_ENT("CM", 0x26, 1), /* Cameroon */ + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), /* China */ + COUNTRY_CHPLAN_ENT("CO", 0x76, 1), /* Colombia */ + COUNTRY_CHPLAN_ENT("CR", 0x76, 1), /* Costa Rica */ + COUNTRY_CHPLAN_ENT("CV", 0x26, 1), /* Cape Verde */ + COUNTRY_CHPLAN_ENT("CX", 0x45, 1), /* Christmas Island (Australia) */ + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), /* Cyprus */ + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), /* Czech Republic */ + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), /* Germany */ + COUNTRY_CHPLAN_ENT("DJ", 0x26, 1), /* Djibouti */ + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), /* Denmark */ + COUNTRY_CHPLAN_ENT("DM", 0x76, 1), /* Dominica */ + COUNTRY_CHPLAN_ENT("DO", 0x76, 1), /* Dominican Republic */ + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), /* Algeria */ + COUNTRY_CHPLAN_ENT("EC", 0x76, 1), /* Ecuador */ + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), /* Estonia */ + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), /* Egypt */ + COUNTRY_CHPLAN_ENT("EH", 0x47, 1), /* Western Sahara */ + COUNTRY_CHPLAN_ENT("ER", 0x26, 1), /* Eritrea */ + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), /* Spain, Canary Islands, Ceuta, Melilla */ + COUNTRY_CHPLAN_ENT("ET", 0x26, 1), /* Ethiopia */ + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), /* Finland */ + COUNTRY_CHPLAN_ENT("FJ", 0x76, 1), /* Fiji */ + COUNTRY_CHPLAN_ENT("FK", 0x26, 1), /* Falkland Islands (Islas Malvinas) (UK) */ + COUNTRY_CHPLAN_ENT("FM", 0x76, 1), /* Micronesia, Federated States of (USA) */ + COUNTRY_CHPLAN_ENT("FO", 0x26, 1), /* Faroe Islands (Denmark) */ + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), /* France */ + COUNTRY_CHPLAN_ENT("GA", 0x26, 1), /* Gabon */ + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), /* Great Britain (United Kingdom; England) */ + COUNTRY_CHPLAN_ENT("GD", 0x76, 1), /* Grenada */ + COUNTRY_CHPLAN_ENT("GE", 0x26, 1), /* Georgia */ + COUNTRY_CHPLAN_ENT("GF", 0x26, 1), /* French Guiana */ + COUNTRY_CHPLAN_ENT("GG", 0x26, 1), /* Guernsey (UK) */ + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), /* Ghana */ + COUNTRY_CHPLAN_ENT("GI", 0x26, 1), /* Gibraltar (UK) */ + COUNTRY_CHPLAN_ENT("GL", 0x26, 1), /* Greenland (Denmark) */ + COUNTRY_CHPLAN_ENT("GM", 0x26, 1), /* Gambia */ + COUNTRY_CHPLAN_ENT("GN", 0x26, 1), /* Guinea */ + COUNTRY_CHPLAN_ENT("GP", 0x26, 1), /* Guadeloupe (France) */ + COUNTRY_CHPLAN_ENT("GQ", 0x26, 1), /* Equatorial Guinea */ + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), /* Greece */ + COUNTRY_CHPLAN_ENT("GS", 0x26, 1), /* South Georgia and the Sandwich Islands (UK) */ + COUNTRY_CHPLAN_ENT("GT", 0x61, 1), /* Guatemala */ + COUNTRY_CHPLAN_ENT("GU", 0x76, 1), /* Guam (USA) */ + COUNTRY_CHPLAN_ENT("GW", 0x26, 1), /* Guinea-Bissau */ + COUNTRY_CHPLAN_ENT("GY", 0x44, 1), /* Guyana */ + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), /* Hong Kong */ + COUNTRY_CHPLAN_ENT("HM", 0x45, 1), /* Heard and McDonald Islands (Australia) */ + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), /* Honduras */ + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), /* Croatia */ + COUNTRY_CHPLAN_ENT("HT", 0x76, 1), /* Haiti */ + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), /* Hungary */ + COUNTRY_CHPLAN_ENT("ID", 0x5D, 1), /* Indonesia */ + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), /* Ireland */ + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), /* Israel */ + COUNTRY_CHPLAN_ENT("IM", 0x26, 1), /* Isle of Man (UK) */ + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), /* India */ + COUNTRY_CHPLAN_ENT("IO", 0x26, 1), /* British Indian Ocean Territory (UK) */ + COUNTRY_CHPLAN_ENT("IQ", 0x26, 1), /* Iraq */ + COUNTRY_CHPLAN_ENT("IR", 0x26, 0), /* Iran */ + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), /* Iceland */ + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), /* Italy */ + COUNTRY_CHPLAN_ENT("JE", 0x26, 1), /* Jersey (UK) */ + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), /* Jamaica */ + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), /* Jordan */ + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), /* Japan- Telec */ + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), /* Kenya */ + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), /* Kyrgyzstan */ + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), /* Cambodia */ + COUNTRY_CHPLAN_ENT("KI", 0x26, 1), /* Kiribati */ + COUNTRY_CHPLAN_ENT("KM", 0x26, 1), /* Comoros */ + COUNTRY_CHPLAN_ENT("KN", 0x76, 1), /* Saint Kitts and Nevis */ + COUNTRY_CHPLAN_ENT("KR", 0x4B, 1), /* South Korea */ + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), /* Kuwait */ + COUNTRY_CHPLAN_ENT("KY", 0x76, 1), /* Cayman Islands (UK) */ + COUNTRY_CHPLAN_ENT("KZ", 0x26, 1), /* Kazakhstan */ + COUNTRY_CHPLAN_ENT("LA", 0x26, 1), /* Laos */ + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), /* Lebanon */ + COUNTRY_CHPLAN_ENT("LC", 0x76, 1), /* Saint Lucia */ + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), /* Liechtenstein */ + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), /* Sri Lanka */ + COUNTRY_CHPLAN_ENT("LR", 0x26, 1), /* Liberia */ + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), /* Lesotho */ + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), /* Lithuania */ + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), /* Luxembourg */ + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), /* Latvia */ + COUNTRY_CHPLAN_ENT("LY", 0x26, 1), /* Libya */ + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), /* Morocco */ + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), /* Monaco */ + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), /* Moldova */ + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), /* Montenegro */ + COUNTRY_CHPLAN_ENT("MF", 0x76, 1), /* Saint Martin */ + COUNTRY_CHPLAN_ENT("MG", 0x26, 1), /* Madagascar */ + COUNTRY_CHPLAN_ENT("MH", 0x76, 1), /* Marshall Islands (USA) */ + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), /* Republic of Macedonia (FYROM) */ + COUNTRY_CHPLAN_ENT("ML", 0x26, 1), /* Mali */ + COUNTRY_CHPLAN_ENT("MM", 0x26, 1), /* Burma (Myanmar) */ + COUNTRY_CHPLAN_ENT("MN", 0x26, 1), /* Mongolia */ + COUNTRY_CHPLAN_ENT("MO", 0x35, 1), /* Macau */ + COUNTRY_CHPLAN_ENT("MP", 0x76, 1), /* Northern Mariana Islands (USA) */ + COUNTRY_CHPLAN_ENT("MQ", 0x26, 1), /* Martinique (France) */ + COUNTRY_CHPLAN_ENT("MR", 0x26, 1), /* Mauritania */ + COUNTRY_CHPLAN_ENT("MS", 0x26, 1), /* Montserrat (UK) */ + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), /* Malta */ + COUNTRY_CHPLAN_ENT("MU", 0x26, 1), /* Mauritius */ + COUNTRY_CHPLAN_ENT("MV", 0x47, 1), /* Maldives */ + COUNTRY_CHPLAN_ENT("MW", 0x26, 1), /* Malawi */ + COUNTRY_CHPLAN_ENT("MX", 0x4D, 1), /* Mexico */ + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), /* Malaysia */ + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), /* Mozambique */ + COUNTRY_CHPLAN_ENT("NA", 0x26, 1), /* Namibia */ + COUNTRY_CHPLAN_ENT("NC", 0x26, 1), /* New Caledonia */ + COUNTRY_CHPLAN_ENT("NE", 0x26, 1), /* Niger */ + COUNTRY_CHPLAN_ENT("NF", 0x45, 1), /* Norfolk Island (Australia) */ + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), /* Nigeria */ + COUNTRY_CHPLAN_ENT("NI", 0x76, 1), /* Nicaragua */ + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), /* Netherlands */ + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), /* Norway */ + COUNTRY_CHPLAN_ENT("NP", 0x48, 1), /* Nepal */ + COUNTRY_CHPLAN_ENT("NR", 0x26, 1), /* Nauru */ + COUNTRY_CHPLAN_ENT("NU", 0x45, 1), /* Niue */ + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), /* New Zealand */ + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), /* Oman */ + COUNTRY_CHPLAN_ENT("PA", 0x76, 1), /* Panama */ + COUNTRY_CHPLAN_ENT("PE", 0x76, 1), /* Peru */ + COUNTRY_CHPLAN_ENT("PF", 0x26, 1), /* French Polynesia (France) */ + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), /* Papua New Guinea */ + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), /* Philippines */ + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), /* Pakistan */ + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), /* Poland */ + COUNTRY_CHPLAN_ENT("PM", 0x26, 1), /* Saint Pierre and Miquelon (France) */ + COUNTRY_CHPLAN_ENT("PR", 0x76, 1), /* Puerto Rico */ + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), /* Portugal */ + COUNTRY_CHPLAN_ENT("PW", 0x76, 1), /* Palau */ + COUNTRY_CHPLAN_ENT("PY", 0x76, 1), /* Paraguay */ + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), /* Qatar */ + COUNTRY_CHPLAN_ENT("RE", 0x26, 1), /* Reunion (France) */ + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), /* Romania */ + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), /* Serbia, Kosovo */ + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), /* Russia(fac/gost), Kaliningrad */ + COUNTRY_CHPLAN_ENT("RW", 0x26, 1), /* Rwanda */ + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), /* Saudi Arabia */ + COUNTRY_CHPLAN_ENT("SB", 0x26, 1), /* Solomon Islands */ + COUNTRY_CHPLAN_ENT("SC", 0x76, 1), /* Seychelles */ + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), /* Sweden */ + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), /* Singapore */ + COUNTRY_CHPLAN_ENT("SH", 0x26, 1), /* Saint Helena (UK) */ + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), /* Slovenia */ + COUNTRY_CHPLAN_ENT("SJ", 0x26, 1), /* Svalbard (Norway) */ + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), /* Slovakia */ + COUNTRY_CHPLAN_ENT("SL", 0x26, 1), /* Sierra Leone */ + COUNTRY_CHPLAN_ENT("SM", 0x26, 1), /* San Marino */ + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), /* Senegal */ + COUNTRY_CHPLAN_ENT("SO", 0x26, 1), /* Somalia */ + COUNTRY_CHPLAN_ENT("SR", 0x74, 1), /* Suriname */ + COUNTRY_CHPLAN_ENT("ST", 0x76, 1), /* Sao Tome and Principe */ + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), /* El Salvador */ + COUNTRY_CHPLAN_ENT("SX", 0x76, 1), /* Sint Marteen */ + COUNTRY_CHPLAN_ENT("SZ", 0x26, 1), /* Swaziland */ + COUNTRY_CHPLAN_ENT("TC", 0x26, 1), /* Turks and Caicos Islands (UK) */ + COUNTRY_CHPLAN_ENT("TD", 0x26, 1), /* Chad */ + COUNTRY_CHPLAN_ENT("TF", 0x26, 1), /* French Southern and Antarctic Lands (FR Southern Territories) */ + COUNTRY_CHPLAN_ENT("TG", 0x26, 1), /* Togo */ + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), /* Thailand */ + COUNTRY_CHPLAN_ENT("TJ", 0x26, 1), /* Tajikistan */ + COUNTRY_CHPLAN_ENT("TK", 0x45, 1), /* Tokelau */ + COUNTRY_CHPLAN_ENT("TM", 0x26, 1), /* Turkmenistan */ + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), /* Tunisia */ + COUNTRY_CHPLAN_ENT("TO", 0x26, 1), /* Tonga */ + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), /* Turkey, Northern Cyprus */ + COUNTRY_CHPLAN_ENT("TT", 0x76, 1), /* Trinidad & Tobago */ + COUNTRY_CHPLAN_ENT("TV", 0x21, 0), /* Tuvalu */ + COUNTRY_CHPLAN_ENT("TW", 0x76, 1), /* Taiwan */ + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1), /* Tanzania */ + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), /* Ukraine */ + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), /* Uganda */ + COUNTRY_CHPLAN_ENT("US", 0x76, 1), /* United States of America (USA) */ + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), /* Uruguay */ + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1), /* Uzbekistan */ + COUNTRY_CHPLAN_ENT("VA", 0x26, 1), /* Holy See (Vatican City) */ + COUNTRY_CHPLAN_ENT("VC", 0x76, 1), /* Saint Vincent and the Grenadines */ + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), /* Venezuela */ + COUNTRY_CHPLAN_ENT("VG", 0x76, 1), /* British Virgin Islands (UK) */ + COUNTRY_CHPLAN_ENT("VI", 0x76, 1), /* United States Virgin Islands (USA) */ + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), /* Vietnam */ + COUNTRY_CHPLAN_ENT("VU", 0x26, 1), /* Vanuatu */ + COUNTRY_CHPLAN_ENT("WF", 0x26, 1), /* Wallis and Futuna (France) */ + COUNTRY_CHPLAN_ENT("WS", 0x76, 1), /* Samoa */ + COUNTRY_CHPLAN_ENT("YE", 0x26, 1), /* Yemen */ + COUNTRY_CHPLAN_ENT("YT", 0x26, 1), /* Mayotte (France) */ + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), /* South Africa */ + COUNTRY_CHPLAN_ENT("ZM", 0x26, 1), /* Zambia */ + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), /* Zimbabwe */ }; +#endif /* CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP or RTW_DEF_MODULE_REGULATORY_CERT or newest */ /* * rtw_get_chplan_from_country - @@ -1125,9 +2371,6 @@ static const struct country_chplan country_chplan_map[] = { */ const struct country_chplan *rtw_get_chplan_from_country(const char *country_code) { -#if RTW_DEF_MODULE_REGULATORY_CERT - const struct country_chplan *exc_ent = NULL; -#endif const struct country_chplan *ent = NULL; const struct country_chplan *map = NULL; u16 map_sz = 0; @@ -1140,10 +2383,9 @@ const struct country_chplan *rtw_get_chplan_from_country(const char *country_cod #ifdef CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP map = CUSTOMIZED_country_chplan_map; map_sz = sizeof(CUSTOMIZED_country_chplan_map) / sizeof(struct country_chplan); +#elif RTW_DEF_MODULE_REGULATORY_CERT + map_sz = rtw_def_module_country_chplan_map(&map); #else - #if RTW_DEF_MODULE_REGULATORY_CERT - exc_ent = rtw_def_module_get_chplan_from_country(code); - #endif map = country_chplan_map; map_sz = sizeof(country_chplan_map) / sizeof(struct country_chplan); #endif @@ -1155,20 +2397,20 @@ const struct country_chplan *rtw_get_chplan_from_country(const char *country_cod } } - #if RTW_DEF_MODULE_REGULATORY_CERT - if (!ent || !(COUNTRY_CHPLAN_DEF_MODULE_FALGS(ent) & RTW_DEF_MODULE_REGULATORY_CERT)) - exc_ent = ent = NULL; - if (exc_ent) - ent = exc_ent; - #endif - return ent; } void dump_country_chplan(void *sel, const struct country_chplan *ent) { - RTW_PRINT_SEL(sel, "\"%c%c\", 0x%02X%s\n" - , ent->alpha2[0], ent->alpha2[1], ent->chplan + char buf[16]; + + if (ent->chplan == RTW_CHPLAN_UNSPECIFIED) + sprintf(buf, "NA"); + else + sprintf(buf, "0x%02X", ent->chplan); + + RTW_PRINT_SEL(sel, "\"%c%c\", %s%s\n" + , ent->alpha2[0], ent->alpha2[1], buf , COUNTRY_CHPLAN_EN_11AC(ent) ? " ac" : "" ); } @@ -1213,27 +2455,60 @@ void dump_chplan_id_list(void *sel) } } +#ifdef CONFIG_RTW_DEBUG void dump_chplan_test(void *sel) { int i, j; + /* check redundent */ + for (i = 0; i < RTW_CHD_2G_MAX; i++) { + for (j = 0; j < i; j++) { + if (CH_LIST_LEN(rtw_channel_def_2g[i]) == CH_LIST_LEN(rtw_channel_def_2g[j]) + && _rtw_memcmp(&CH_LIST_CH(rtw_channel_def_2g[i], 0), &CH_LIST_CH(rtw_channel_def_2g[j], 0), CH_LIST_LEN(rtw_channel_def_2g[i]) + 1) == _TRUE) + RTW_PRINT_SEL(sel, "2G chd:%u and %u is the same\n", i, j); + } + } + /* check invalid channel */ - for (i = 0; i < RTW_RD_2G_MAX; i++) { - for (j = 0; j < CH_LIST_LEN(RTW_ChannelPlan2G[i]); j++) { - if (rtw_ch2freq(CH_LIST_CH(RTW_ChannelPlan2G[i], j)) == 0) - RTW_PRINT_SEL(sel, "invalid ch:%u at (%d,%d)\n", CH_LIST_CH(RTW_ChannelPlan2G[i], j), i, j); + for (i = 0; i < RTW_CHD_2G_MAX; i++) { + for (j = 0; j < CH_LIST_LEN(rtw_channel_def_2g[i]); j++) { + if (rtw_ch2freq(CH_LIST_CH(rtw_channel_def_2g[i], j)) == 0) + RTW_PRINT_SEL(sel, "2G invalid ch:%u at (%d,%d)\n", CH_LIST_CH(rtw_channel_def_2g[i], j), i, j); } } #if CONFIG_IEEE80211_BAND_5GHZ - for (i = 0; i < RTW_RD_5G_MAX; i++) { - for (j = 0; j < CH_LIST_LEN(RTW_ChannelPlan5G[i]); j++) { - if (rtw_ch2freq(CH_LIST_CH(RTW_ChannelPlan5G[i], j)) == 0) - RTW_PRINT_SEL(sel, "invalid ch:%u at (%d,%d)\n", CH_LIST_CH(RTW_ChannelPlan5G[i], j), i, j); + /* check redundent */ + for (i = 0; i < RTW_CHD_5G_MAX; i++) { + for (j = 0; j < i; j++) { + if (CH_LIST_LEN(rtw_channel_def_5g[i]) == CH_LIST_LEN(rtw_channel_def_5g[j]) + && _rtw_memcmp(&CH_LIST_CH(rtw_channel_def_5g[i], 0), &CH_LIST_CH(rtw_channel_def_5g[j], 0), CH_LIST_LEN(rtw_channel_def_5g[i]) + 1) == _TRUE) + RTW_PRINT_SEL(sel, "5G chd:%u and %u is the same\n", i, j); + } + } + + /* check invalid channel */ + for (i = 0; i < RTW_CHD_5G_MAX; i++) { + for (j = 0; j < CH_LIST_LEN(rtw_channel_def_5g[i]); j++) { + if (rtw_ch2freq(CH_LIST_CH(rtw_channel_def_5g[i], j)) == 0) + RTW_PRINT_SEL(sel, "5G invalid ch:%u at (%d,%d)\n", CH_LIST_CH(rtw_channel_def_5g[i], j), i, j); } } #endif + + /* check redundent */ + for (i = 0; i < RTW_ChannelPlanMap_size; i++) { + if (!rtw_is_channel_plan_valid(i)) + continue; + for (j = 0; j < i; j++) { + if (!rtw_is_channel_plan_valid(j)) + continue; + if (_rtw_memcmp(&RTW_ChannelPlanMap[i], &RTW_ChannelPlanMap[j], sizeof(RTW_ChannelPlanMap[i])) == _TRUE) + RTW_PRINT_SEL(sel, "channel plan 0x%02x and 0x%02x is the same\n", i, j); + } + } } +#endif /* CONFIG_RTW_DEBUG */ void dump_chplan_ver(void *sel) { diff --git a/core/rtw_chplan.h b/core/rtw_chplan.h index b6a53f5..bfe1ab2 100644 --- a/core/rtw_chplan.h +++ b/core/rtw_chplan.h @@ -20,15 +20,28 @@ u8 rtw_chplan_get_default_regd(u8 id); bool rtw_chplan_is_empty(u8 id); bool rtw_is_channel_plan_valid(u8 id); +bool rtw_regsty_is_excl_chs(struct registry_priv *regsty, u8 ch); + +enum regd_src_t { + REGD_SRC_RTK_PRIV = 0, /* Regulatory settings from Realtek framework (Realtek defined or customized) */ + REGD_SRC_OS = 1, /* Regulatory settings from OS */ + REGD_SRC_NUM, +}; + +#define regd_src_is_valid(src) ((src) < REGD_SRC_NUM) + +extern const char *_regd_src_str[]; +#define regd_src_str(src) ((src) >= REGD_SRC_NUM ? _regd_src_str[REGD_SRC_NUM] : _regd_src_str[src]) struct _RT_CHANNEL_INFO; -u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, struct _RT_CHANNEL_INFO *channel_set); +u8 init_channel_set(_adapter *adapter); bool rtw_chset_is_dfs_range(struct _RT_CHANNEL_INFO *chset, u32 hi, u32 lo); bool rtw_chset_is_dfs_ch(struct _RT_CHANNEL_INFO *chset, u8 ch); bool rtw_chset_is_dfs_chbw(struct _RT_CHANNEL_INFO *chset, u8 ch, u8 bw, u8 offset); -void rtw_process_beacon_hint(_adapter *adapter, WLAN_BSSID_EX *bss); +u8 rtw_process_beacon_hint(_adapter *adapter, WLAN_BSSID_EX *bss); #define IS_ALPHA2_NO_SPECIFIED(_alpha2) ((*((u16 *)(_alpha2))) == 0xFFFF) +#define IS_ALPHA2_WORLDWIDE(_alpha2) (strncmp(_alpha2, "00", 2) == 0) #define RTW_MODULE_RTL8821AE_HMC_M2 BIT0 /* RTL8821AE(HMC + M.2) */ #define RTW_MODULE_RTL8821AU BIT1 /* RTL8821AU */ @@ -43,15 +56,24 @@ void rtw_process_beacon_hint(_adapter *adapter, WLAN_BSSID_EX *bss); #define RTW_MODULE_RTL8821CE BIT10 /* RTL8821CE */ #define RTW_MODULE_RTL8822CE BIT11 /* RTL8822CE */ +enum rtw_dfs_regd { + RTW_DFS_REGD_NONE = 0, + RTW_DFS_REGD_FCC = 1, + RTW_DFS_REGD_MKK = 2, + RTW_DFS_REGD_ETSI = 3, + RTW_DFS_REGD_NUM, + RTW_DFS_REGD_AUTO = 0xFF, /* follow channel plan */ +}; + +extern const char *_rtw_dfs_regd_str[]; +#define rtw_dfs_regd_str(region) (((region) >= RTW_DFS_REGD_NUM) ? _rtw_dfs_regd_str[RTW_DFS_REGD_NONE] : _rtw_dfs_regd_str[(region)]) + struct country_chplan { - char alpha2[2]; + char alpha2[2]; /* "00" means worldwide */ u8 chplan; #ifdef CONFIG_80211AC_VHT u8 en_11ac; #endif -#if RTW_DEF_MODULE_REGULATORY_CERT - u16 def_module_flags; /* RTW_MODULE_RTLXXX */ -#endif }; #ifdef CONFIG_80211AC_VHT @@ -60,18 +82,14 @@ struct country_chplan { #define COUNTRY_CHPLAN_EN_11AC(_ent) 0 #endif -#if RTW_DEF_MODULE_REGULATORY_CERT -#define COUNTRY_CHPLAN_DEF_MODULE_FALGS(_ent) ((_ent)->def_module_flags) -#else -#define COUNTRY_CHPLAN_DEF_MODULE_FALGS(_ent) 0 -#endif - const struct country_chplan *rtw_get_chplan_from_country(const char *country_code); void dump_country_chplan(void *sel, const struct country_chplan *ent); void dump_country_chplan_map(void *sel); void dump_chplan_id_list(void *sel); +#ifdef CONFIG_RTW_DEBUG void dump_chplan_test(void *sel); +#endif void dump_chplan_ver(void *sel); #endif /* __RTW_CHPLAN_H__ */ diff --git a/core/rtw_cmd.c b/core/rtw_cmd.c index 26c0fb6..7bcc6f4 100644 --- a/core/rtw_cmd.c +++ b/core/rtw_cmd.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2019 Realtek Corporation. + * Copyright(c) 2007 - 2017 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -261,17 +261,17 @@ sint _rtw_enqueue_cmd(_queue *queue, struct cmd_obj *obj, bool to_head) #ifdef DBG_CMD_QUEUE if (dump_cmd_id) { - printk("%s===> cmdcode:0x%02x\n", __FUNCTION__, obj->cmdcode); - if (obj->cmdcode == GEN_CMD_CODE(_Set_MLME_EVT)) { + RTW_INFO("%s===> cmdcode:0x%02x\n", __FUNCTION__, obj->cmdcode); + if (obj->cmdcode == CMD_SET_MLME_EVT) { if (obj->parmbuf) { - struct C2HEvent_Header *pc2h_evt_hdr = (struct C2HEvent_Header *)(obj->parmbuf); - printk("pc2h_evt_hdr->ID:0x%02x(%d)\n", pc2h_evt_hdr->ID, pc2h_evt_hdr->ID); + struct rtw_evt_header *evt_hdr = (struct rtw_evt_header *)(obj->parmbuf); + RTW_INFO("evt_hdr->id:%d\n", evt_hdr->id); } } - if (obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { + if (obj->cmdcode == CMD_SET_DRV_EXTRA) { if (obj->parmbuf) { struct drvextra_cmd_parm *pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)(obj->parmbuf); - printk("pdrvextra_cmd_parm->ec_id:0x%02x\n", pdrvextra_cmd_parm->ec_id); + RTW_INFO("pdrvextra_cmd_parm->ec_id:0x%02x\n", pdrvextra_cmd_parm->ec_id); } } } @@ -344,7 +344,7 @@ struct cmd_obj *_rtw_dequeue_cmd(_queue *queue) if (dump_cmd_id) { RTW_INFO("%s===> cmdcode:0x%02x\n", __FUNCTION__, obj->cmdcode); - if (obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { + if (obj->cmdcode == CMD_SET_DRV_EXTRA) { if (obj->parmbuf) { struct drvextra_cmd_parm *pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)(obj->parmbuf); printk("pdrvextra_cmd_parm->ec_id:0x%02x\n", pdrvextra_cmd_parm->ec_id); @@ -391,14 +391,18 @@ void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv) int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj); int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) { +#ifndef CONFIG_MAC_LOOPBACK_DRIVER u8 bAllow = _FALSE; /* set to _TRUE to allow enqueuing cmd when hw_init_completed is _FALSE */ +#else + u8 bAllow = _TRUE; /* hw_init_completed is _FALSE in the case of MAC loopback*/ +#endif #ifdef SUPPORT_HW_RFOFF_DETECTED /* To decide allow or not */ if ((adapter_to_pwrctl(pcmdpriv->padapter)->bHWPwrPindetect) && (!pcmdpriv->padapter->registrypriv.usbss_enable) ) { - if (cmd_obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { + if (cmd_obj->cmdcode == CMD_SET_DRV_EXTRA) { struct drvextra_cmd_parm *pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)cmd_obj->parmbuf; if (pdrvextra_cmd_parm->ec_id == POWER_SAVING_CTRL_WK_CID) { /* RTW_INFO("==>enqueue POWER_SAVING_CTRL_WK_CID\n"); */ @@ -408,7 +412,7 @@ int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) } #endif - if (cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan)) + if (cmd_obj->cmdcode == CMD_SET_CHANPLAN) bAllow = _TRUE; if (cmd_obj->no_io) @@ -454,7 +458,7 @@ u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) rtw_warn_on(1); } - if (cmd_obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { + if (cmd_obj->cmdcode == CMD_SET_DRV_EXTRA) { struct drvextra_cmd_parm *extra_parm = (struct drvextra_cmd_parm *)cmd_obj->parmbuf; if (extra_parm->pbuf && extra_parm->size > 0) @@ -589,13 +593,13 @@ _next: goto post_process; } - if (pcmd->cmdcode >= (sizeof(wlancmds) / sizeof(struct cmd_hdl))) { + if (pcmd->cmdcode >= (sizeof(wlancmds) / sizeof(struct rtw_cmd))) { RTW_ERR("%s undefined cmdcode:%d\n", __func__, pcmd->cmdcode); pcmd->res = H2C_PARAMETERS_ERROR; goto post_process; } - cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns; + cmd_hdl = wlancmds[pcmd->cmdcode].cmd_hdl; if (!cmd_hdl) { RTW_ERR("%s no cmd_hdl for cmdcode:%d\n", __func__, pcmd->cmdcode); pcmd->res = H2C_PARAMETERS_ERROR; @@ -604,13 +608,13 @@ _next: if (_FAIL == rtw_cmd_filter(pcmdpriv, pcmd)) { pcmd->res = H2C_DROPPED; - if (pcmd->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { + if (pcmd->cmdcode == CMD_SET_DRV_EXTRA) { extra_parm = (struct drvextra_cmd_parm *)pcmd->parmbuf; if (extra_parm && extra_parm->pbuf && extra_parm->size > 0) rtw_mfree(extra_parm->pbuf, extra_parm->size); } #if CONFIG_DFS - else if (pcmd->cmdcode == GEN_CMD_CODE(_SetChannelSwitch)) + else if (pcmd->cmdcode == CMD_SET_CHANSWITCH) adapter_to_rfctl(padapter)->csa_ch = 0; #endif goto post_process; @@ -670,16 +674,16 @@ post_process: } /* call callback function for post-processed */ - if (pcmd->cmdcode < (sizeof(rtw_cmd_callback) / sizeof(struct _cmd_callback))) { - pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback; - if (pcmd_callback == NULL) { - rtw_free_cmd_obj(pcmd); - } else { - /* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!=NULL) */ - pcmd_callback(pcmd->padapter, pcmd);/* need conider that free cmd_obj in rtw_cmd_callback */ - } - } else { + if (pcmd->cmdcode < (sizeof(wlancmds) / sizeof(struct rtw_cmd))) + pcmd_callback = wlancmds[pcmd->cmdcode].callback; + else + pcmd_callback = NULL; + + if (pcmd_callback == NULL) { rtw_free_cmd_obj(pcmd); + } else { + /* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!=NULL) */ + pcmd_callback(pcmd->padapter, pcmd);/* need conider that free cmd_obj in rtw_cmd_callback */ } flush_signals_thread(); @@ -704,13 +708,13 @@ post_process: if (0) RTW_INFO("%s: leaving... drop "CMD_FMT"\n", __func__, CMD_ARG(pcmd)); - if (pcmd->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { + if (pcmd->cmdcode == CMD_SET_DRV_EXTRA) { extra_parm = (struct drvextra_cmd_parm *)pcmd->parmbuf; if (extra_parm->pbuf && extra_parm->size > 0) rtw_mfree(extra_parm->pbuf, extra_parm->size); } #if CONFIG_DFS - else if (pcmd->cmdcode == GEN_CMD_CODE(_SetChannelSwitch)) + else if (pcmd->cmdcode == CMD_SET_CHANSWITCH) adapter_to_rfctl(padapter)->csa_ch = 0; #endif @@ -800,44 +804,6 @@ void rtw_evt_notify_isr(struct evt_priv *pevtpriv) } #endif - -/* -u8 rtw_setstandby_cmd(unsigned char *adapter) -*/ -u8 rtw_setstandby_cmd(_adapter *padapter, uint action) -{ - struct cmd_obj *ph2c; - struct usb_suspend_parm *psetusbsuspend; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - - u8 ret = _SUCCESS; - - - ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); - if (ph2c == NULL) { - ret = _FAIL; - goto exit; - } - - psetusbsuspend = (struct usb_suspend_parm *)rtw_zmalloc(sizeof(struct usb_suspend_parm)); - if (psetusbsuspend == NULL) { - rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); - ret = _FAIL; - goto exit; - } - - psetusbsuspend->action = action; - - init_h2fwcmd_w_parm_no_rsp(ph2c, psetusbsuspend, GEN_CMD_CODE(_SetUsbSuspend)); - - ret = rtw_enqueue_cmd(pcmdpriv, ph2c); - -exit: - - - return ret; -} - void rtw_init_sitesurvey_parm(_adapter *padapter, struct sitesurvey_parm *pparm) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -861,12 +827,12 @@ u8 rtw_sitesurvey_cmd(_adapter *padapter, struct sitesurvey_parm *pparm) struct mlme_priv *pmlmepriv = &padapter->mlmepriv; #ifdef CONFIG_LPS - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 0); #endif #ifdef CONFIG_P2P_PS - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) p2p_ps_wk_cmd(padapter, P2P_PS_SCAN, 1); #endif /* CONFIG_P2P_PS */ @@ -887,9 +853,9 @@ u8 rtw_sitesurvey_cmd(_adapter *padapter, struct sitesurvey_parm *pparm) rtw_free_network_queue(padapter, _FALSE); - init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey)); + init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, CMD_SITE_SURVEY); - set_fwstate(pmlmepriv, _FW_UNDER_SURVEY); + set_fwstate(pmlmepriv, WIFI_UNDER_SURVEY); res = rtw_enqueue_cmd(pcmdpriv, ph2c); @@ -902,301 +868,12 @@ u8 rtw_sitesurvey_cmd(_adapter *padapter, struct sitesurvey_parm *pparm) rtw_led_control(padapter, LED_CTL_SITE_SURVEY); } else - _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); + _clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY); return res; } -u8 rtw_setdatarate_cmd(_adapter *padapter, u8 *rateset) -{ - struct cmd_obj *ph2c; - struct setdatarate_parm *pbsetdataratepara; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - u8 res = _SUCCESS; - - - ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); - if (ph2c == NULL) { - res = _FAIL; - goto exit; - } - - pbsetdataratepara = (struct setdatarate_parm *)rtw_zmalloc(sizeof(struct setdatarate_parm)); - if (pbsetdataratepara == NULL) { - rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); - res = _FAIL; - goto exit; - } - - init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate)); -#ifdef MP_FIRMWARE_OFFLOAD - pbsetdataratepara->curr_rateidx = *(u32 *)rateset; - /* _rtw_memcpy(pbsetdataratepara, rateset, sizeof(u32)); */ -#else - pbsetdataratepara->mac_id = 5; - _rtw_memcpy(pbsetdataratepara->datarates, rateset, NumRates); -#endif - res = rtw_enqueue_cmd(pcmdpriv, ph2c); -exit: - - - return res; -} - -u8 rtw_setbasicrate_cmd(_adapter *padapter, u8 *rateset) -{ - struct cmd_obj *ph2c; - struct setbasicrate_parm *pssetbasicratepara; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - u8 res = _SUCCESS; - - - ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); - if (ph2c == NULL) { - res = _FAIL; - goto exit; - } - pssetbasicratepara = (struct setbasicrate_parm *)rtw_zmalloc(sizeof(struct setbasicrate_parm)); - - if (pssetbasicratepara == NULL) { - rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); - res = _FAIL; - goto exit; - } - - init_h2fwcmd_w_parm_no_rsp(ph2c, pssetbasicratepara, _SetBasicRate_CMD_); - - _rtw_memcpy(pssetbasicratepara->basicrates, rateset, NumRates); - - res = rtw_enqueue_cmd(pcmdpriv, ph2c); -exit: - - - return res; -} - - -/* -unsigned char rtw_setphy_cmd(unsigned char *adapter) - -1. be called only after rtw_update_registrypriv_dev_network( ~) or mp testing program -2. for AdHoc/Ap mode or mp mode? - -*/ -u8 rtw_setphy_cmd(_adapter *padapter, u8 modem, u8 ch) -{ - struct cmd_obj *ph2c; - struct setphy_parm *psetphypara; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - /* struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - * struct registry_priv* pregistry_priv = &padapter->registrypriv; */ - u8 res = _SUCCESS; - - - ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); - if (ph2c == NULL) { - res = _FAIL; - goto exit; - } - psetphypara = (struct setphy_parm *)rtw_zmalloc(sizeof(struct setphy_parm)); - - if (psetphypara == NULL) { - rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); - res = _FAIL; - goto exit; - } - - init_h2fwcmd_w_parm_no_rsp(ph2c, psetphypara, _SetPhy_CMD_); - - - psetphypara->modem = modem; - psetphypara->rfchannel = ch; - - res = rtw_enqueue_cmd(pcmdpriv, ph2c); -exit: - return res; -} - -u8 rtw_getmacreg_cmd(_adapter *padapter, u8 len, u32 addr) -{ - struct cmd_obj *ph2c; - struct readMAC_parm *preadmacparm; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - u8 res = _SUCCESS; - - ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); - if (ph2c == NULL) { - res = _FAIL; - goto exit; - } - preadmacparm = (struct readMAC_parm *)rtw_zmalloc(sizeof(struct readMAC_parm)); - - if (preadmacparm == NULL) { - rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); - res = _FAIL; - goto exit; - } - - init_h2fwcmd_w_parm_no_rsp(ph2c, preadmacparm, GEN_CMD_CODE(_GetMACReg)); - - preadmacparm->len = len; - preadmacparm->addr = addr; - - res = rtw_enqueue_cmd(pcmdpriv, ph2c); - -exit: - return res; -} - -void rtw_usb_catc_trigger_cmd(_adapter *padapter, const char *caller) -{ - RTW_INFO("%s caller:%s\n", __func__, caller); - rtw_getmacreg_cmd(padapter, 1, 0x1c4); -} - -u8 rtw_setbbreg_cmd(_adapter *padapter, u8 offset, u8 val) -{ - struct cmd_obj *ph2c; - struct writeBB_parm *pwritebbparm; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - u8 res = _SUCCESS; - ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); - if (ph2c == NULL) { - res = _FAIL; - goto exit; - } - pwritebbparm = (struct writeBB_parm *)rtw_zmalloc(sizeof(struct writeBB_parm)); - - if (pwritebbparm == NULL) { - rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); - res = _FAIL; - goto exit; - } - - init_h2fwcmd_w_parm_no_rsp(ph2c, pwritebbparm, GEN_CMD_CODE(_SetBBReg)); - - pwritebbparm->offset = offset; - pwritebbparm->value = val; - - res = rtw_enqueue_cmd(pcmdpriv, ph2c); -exit: - return res; -} - -u8 rtw_getbbreg_cmd(_adapter *padapter, u8 offset, u8 *pval) -{ - struct cmd_obj *ph2c; - struct readBB_parm *prdbbparm; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - u8 res = _SUCCESS; - - ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); - if (ph2c == NULL) { - res = _FAIL; - goto exit; - } - prdbbparm = (struct readBB_parm *)rtw_zmalloc(sizeof(struct readBB_parm)); - - if (prdbbparm == NULL) { - rtw_mfree((unsigned char *) ph2c, sizeof(struct cmd_obj)); - return _FAIL; - } - - _rtw_init_listhead(&ph2c->list); - ph2c->cmdcode = GEN_CMD_CODE(_GetBBReg); - ph2c->parmbuf = (unsigned char *)prdbbparm; - ph2c->cmdsz = sizeof(struct readBB_parm); - ph2c->rsp = pval; - ph2c->rspsz = sizeof(struct readBB_rsp); - - prdbbparm->offset = offset; - - res = rtw_enqueue_cmd(pcmdpriv, ph2c); -exit: - return res; -} - -u8 rtw_setrfreg_cmd(_adapter *padapter, u8 offset, u32 val) -{ - struct cmd_obj *ph2c; - struct writeRF_parm *pwriterfparm; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - u8 res = _SUCCESS; - ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); - if (ph2c == NULL) { - res = _FAIL; - goto exit; - } - pwriterfparm = (struct writeRF_parm *)rtw_zmalloc(sizeof(struct writeRF_parm)); - - if (pwriterfparm == NULL) { - rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); - res = _FAIL; - goto exit; - } - - init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg)); - - pwriterfparm->offset = offset; - pwriterfparm->value = val; - - res = rtw_enqueue_cmd(pcmdpriv, ph2c); -exit: - return res; -} - -u8 rtw_getrfreg_cmd(_adapter *padapter, u8 offset, u8 *pval) -{ - struct cmd_obj *ph2c; - struct readRF_parm *prdrfparm; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - u8 res = _SUCCESS; - - - ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); - if (ph2c == NULL) { - res = _FAIL; - goto exit; - } - - prdrfparm = (struct readRF_parm *)rtw_zmalloc(sizeof(struct readRF_parm)); - if (prdrfparm == NULL) { - rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); - res = _FAIL; - goto exit; - } - - _rtw_init_listhead(&ph2c->list); - ph2c->cmdcode = GEN_CMD_CODE(_GetRFReg); - ph2c->parmbuf = (unsigned char *)prdrfparm; - ph2c->cmdsz = sizeof(struct readRF_parm); - ph2c->rsp = pval; - ph2c->rspsz = sizeof(struct readRF_rsp); - - prdrfparm->offset = offset; - - res = rtw_enqueue_cmd(pcmdpriv, ph2c); - -exit: - - - return res; -} - -void rtw_getbbrfreg_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd) -{ - - /* rtw_free_cmd_obj(pcmd); */ - rtw_mfree((unsigned char *) pcmd->parmbuf, pcmd->cmdsz); - rtw_mfree((unsigned char *) pcmd, sizeof(struct cmd_obj)); - -#ifdef CONFIG_MP_INCLUDED - if (padapter->registrypriv.mp_mode == 1) - padapter->mppriv.workparam.bcompleted = _TRUE; -#endif -} - void rtw_readtssi_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd) { @@ -1210,6 +887,7 @@ void rtw_readtssi_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd) } +#ifdef CONFIG_AP_MODE static u8 rtw_createbss_cmd(_adapter *adapter, int flags, bool adhoc , u8 ifbmp, u8 excl_ifbmp, s16 req_ch, s8 req_bw, s8 req_offset) { @@ -1259,7 +937,7 @@ static u8 rtw_createbss_cmd(_adapter *adapter, int flags, bool adhoc goto exit; } - init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, GEN_CMD_CODE(_CreateBss)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_CREATE_BSS); if (flags & RTW_CMDF_WAIT_ACK) { cmdobj->sctx = &sctx; @@ -1308,42 +986,7 @@ inline u8 rtw_change_bss_chbw_cmd(_adapter *adapter, int flags , req_ch, req_bw, req_offset ); } - -#ifdef CONFIG_RTW_80211R -static void rtw_ft_validate_akm_type(_adapter *padapter, - struct wlan_network *pnetwork) -{ - struct security_priv *psecuritypriv = &(padapter->securitypriv); - struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); - u32 tmp_len; - u8 *ptmp; - - /*IEEE802.11-2012 Std. Table 8-101-AKM suite selectors*/ - if (rtw_ft_valid_akm(padapter, psecuritypriv->rsn_akm_suite_type)) { - ptmp = rtw_get_ie(&pnetwork->network.IEs[12], - _MDIE_, &tmp_len, (pnetwork->network.IELength-12)); - if (ptmp) { - pft_roam->mdid = *(u16 *)(ptmp+2); - pft_roam->ft_cap = *(ptmp+4); - - RTW_INFO("FT: target " MAC_FMT " mdid=(0x%2x), capacity=(0x%2x)\n", - MAC_ARG(pnetwork->network.MacAddress), pft_roam->mdid, pft_roam->ft_cap); - rtw_ft_set_flags(padapter, RTW_FT_PEER_EN); - - if (rtw_ft_otd_roam_en(padapter)) - rtw_ft_set_flags(padapter, RTW_FT_PEER_OTD_EN); - } else { - /* Don't use FT roaming if target AP cannot support FT */ - rtw_ft_clr_flags(padapter, (RTW_FT_PEER_EN|RTW_FT_PEER_OTD_EN)); - rtw_ft_reset_status(padapter); - } - } else { - /* It could be a non-FT connection */ - rtw_ft_clr_flags(padapter, (RTW_FT_PEER_EN|RTW_FT_PEER_OTD_EN)); - rtw_ft_reset_status(padapter); - } -} -#endif +#endif /* CONFIG_AP_MODE */ u8 rtw_joinbss_cmd(_adapter *padapter, struct wlan_network *pnetwork) { @@ -1497,28 +1140,22 @@ u8 rtw_joinbss_cmd(_adapter *padapter, struct wlan_network *pnetwork) #ifdef CONFIG_80211AC_VHT pvhtpriv->vht_option = _FALSE; - if ((psecnetwork->Configuration.DSConfig <= 14) && - (!rtw_is_vht_2g4(padapter))) { - RTW_PRINT("%s: Not support VHT rate on 2.4G (ch:%d)\n", - __FUNCTION__, - psecnetwork->Configuration.DSConfig); - goto skip_vht; - } if (phtpriv->ht_option && REGSTY_IS_11AC_ENABLE(pregistrypriv) && is_supported_vht(pregistrypriv->wireless_mode) && (!rfctl->country_ent || COUNTRY_CHPLAN_EN_11AC(rfctl->country_ent)) ) { - rtw_restructure_vht_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], - pnetwork->network.IELength, &psecnetwork->IELength); + u8 vht_enable = 0; - if ((psecnetwork->Configuration.DSConfig <= 14) && - (pvhtpriv->vht_option == _TRUE)) - RTW_INFO("%s: AP support VHT rate on 2.4G (ch:%d)\n", - __FUNCTION__, - psecnetwork->Configuration.DSConfig); + if (pnetwork->network.Configuration.DSConfig > 14) + vht_enable = 1; + else if ((REGSTY_IS_11AC_24G_ENABLE(pregistrypriv)) && (padapter->registrypriv.wifi_spec == 0)) + vht_enable = 1; + + if (vht_enable == 1) + rtw_restructure_vht_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], + pnetwork->network.IELength, &psecnetwork->IELength); } -skip_vht: #endif #endif /* CONFIG_80211N_HT */ @@ -1540,7 +1177,7 @@ skip_vht: pcmd->cmdsz = sizeof(WLAN_BSSID_EX); _rtw_init_listhead(&pcmd->list); - pcmd->cmdcode = _JoinBss_CMD_;/* GEN_CMD_CODE(_JoinBss) */ + pcmd->cmdcode = CMD_JOINBSS;/* _JoinBss_CMD_ */ pcmd->parmbuf = (unsigned char *)psecnetwork; pcmd->rsp = NULL; pcmd->rspsz = 0; @@ -1583,7 +1220,7 @@ u8 rtw_disassoc_cmd(_adapter *padapter, u32 deauth_timeout_ms, int flags) /* for rtw_mfree((u8 *)param, sizeof(*param)); goto exit; } - init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_); + init_h2fwcmd_w_parm_no_rsp(cmdobj, param, CMD_DISCONNECT); if (flags & RTW_CMDF_WAIT_ACK) { cmdobj->sctx = &sctx; rtw_sctx_init(&sctx, 2000); @@ -1604,10 +1241,9 @@ exit: return res; } - +#ifdef CONFIG_AP_MODE u8 rtw_stop_ap_cmd(_adapter *adapter, u8 flags) { -#ifdef CONFIG_AP_MODE struct cmd_obj *cmdobj; struct drvextra_cmd_parm *parm; struct cmd_priv *pcmdpriv = &adapter->cmdpriv; @@ -1637,7 +1273,7 @@ u8 rtw_stop_ap_cmd(_adapter *adapter, u8 flags) goto exit; } - init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_SET_DRV_EXTRA); if (flags & RTW_CMDF_WAIT_ACK) { cmdobj->sctx = &sctx; @@ -1654,11 +1290,45 @@ u8 rtw_stop_ap_cmd(_adapter *adapter, u8 flags) _exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL); } } - exit: return res; -#endif } +#endif /* CONFIG_AP_MODE */ + +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT +u8 rtw_tx_control_cmd(_adapter *adapter) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &adapter->cmdpriv; + + u8 res = _SUCCESS; + + ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); + if (ph2c == NULL){ + res = _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if (pdrvextra_cmd_parm == NULL) { + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res = _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = TBTX_CONTROL_TX_WK_CID; + pdrvextra_cmd_parm->type = 0; + pdrvextra_cmd_parm->size = 0; + pdrvextra_cmd_parm->pbuf = NULL; + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + return res; +} +#endif u8 rtw_setopmode_cmd(_adapter *adapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype, u8 flags) { @@ -1690,7 +1360,7 @@ u8 rtw_setopmode_cmd(_adapter *adapter, NDIS_802_11_NETWORK_INFRASTRUCTURE netw goto exit; } - init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, _SetOpMode_CMD_); + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_SET_OPMODE); if (flags & RTW_CMDF_WAIT_ACK) { cmdobj->sctx = &sctx; @@ -1721,6 +1391,7 @@ u8 rtw_setstakey_cmd(_adapter *padapter, struct sta_info *sta, u8 key_type, bool struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; + u8 key_len =16; u8 res = _SUCCESS; @@ -1737,14 +1408,17 @@ u8 rtw_setstakey_cmd(_adapter *padapter, struct sta_info *sta, u8 key_type, bool else GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, _FALSE); + if ((psetstakey_para->algorithm == _GCMP_256_) || (psetstakey_para->algorithm == _CCMP_256_)) + key_len = 32; + if (key_type == GROUP_KEY) { - _rtw_memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16); + _rtw_memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, key_len); psetstakey_para->gk = 1; } else if (key_type == UNICAST_KEY) - _rtw_memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16); + _rtw_memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, key_len); #ifdef CONFIG_TDLS else if (key_type == TDLS_KEY) { - _rtw_memcpy(&psetstakey_para->key, sta->tpk.tk, 16); + _rtw_memcpy(&psetstakey_para->key, sta->tpk.tk, key_len); psetstakey_para->algorithm = (u8)sta->dot118021XPrivacy; } #endif /* CONFIG_TDLS */ @@ -1768,7 +1442,7 @@ u8 rtw_setstakey_cmd(_adapter *padapter, struct sta_info *sta, u8 key_type, bool goto exit; } - init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); + init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, CMD_SET_STAKEY); ph2c->rsp = (u8 *) psetstakey_rsp; ph2c->rspsz = sizeof(struct set_stakey_rsp); res = rtw_enqueue_cmd(pcmdpriv, ph2c); @@ -1824,7 +1498,7 @@ u8 rtw_clearstakey_cmd(_adapter *padapter, struct sta_info *sta, u8 enqueue) goto exit; } - init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); + init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, CMD_SET_STAKEY); ph2c->rsp = (u8 *) psetstakey_rsp; ph2c->rspsz = sizeof(struct set_stakey_rsp); @@ -1842,117 +1516,6 @@ exit: return res; } -u8 rtw_setrttbl_cmd(_adapter *padapter, struct setratable_parm *prate_table) -{ - struct cmd_obj *ph2c; - struct setratable_parm *psetrttblparm; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - u8 res = _SUCCESS; - - ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); - if (ph2c == NULL) { - res = _FAIL; - goto exit; - } - psetrttblparm = (struct setratable_parm *)rtw_zmalloc(sizeof(struct setratable_parm)); - - if (psetrttblparm == NULL) { - rtw_mfree((unsigned char *) ph2c, sizeof(struct cmd_obj)); - res = _FAIL; - goto exit; - } - - init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable)); - - _rtw_memcpy(psetrttblparm, prate_table, sizeof(struct setratable_parm)); - - res = rtw_enqueue_cmd(pcmdpriv, ph2c); -exit: - return res; - -} - -u8 rtw_getrttbl_cmd(_adapter *padapter, struct getratable_rsp *pval) -{ - struct cmd_obj *ph2c; - struct getratable_parm *pgetrttblparm; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - u8 res = _SUCCESS; - - ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); - if (ph2c == NULL) { - res = _FAIL; - goto exit; - } - pgetrttblparm = (struct getratable_parm *)rtw_zmalloc(sizeof(struct getratable_parm)); - - if (pgetrttblparm == NULL) { - rtw_mfree((unsigned char *) ph2c, sizeof(struct cmd_obj)); - res = _FAIL; - goto exit; - } - - /* init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable)); */ - - _rtw_init_listhead(&ph2c->list); - ph2c->cmdcode = GEN_CMD_CODE(_GetRaTable); - ph2c->parmbuf = (unsigned char *)pgetrttblparm; - ph2c->cmdsz = sizeof(struct getratable_parm); - ph2c->rsp = (u8 *)pval; - ph2c->rspsz = sizeof(struct getratable_rsp); - - pgetrttblparm->rsvd = 0x0; - - res = rtw_enqueue_cmd(pcmdpriv, ph2c); -exit: - return res; - -} - -u8 rtw_setassocsta_cmd(_adapter *padapter, u8 *mac_addr) -{ - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct cmd_obj *ph2c; - struct set_assocsta_parm *psetassocsta_para; - struct set_stakey_rsp *psetassocsta_rsp = NULL; - - u8 res = _SUCCESS; - - - ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); - if (ph2c == NULL) { - res = _FAIL; - goto exit; - } - - psetassocsta_para = (struct set_assocsta_parm *)rtw_zmalloc(sizeof(struct set_assocsta_parm)); - if (psetassocsta_para == NULL) { - rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); - res = _FAIL; - goto exit; - } - - psetassocsta_rsp = (struct set_stakey_rsp *)rtw_zmalloc(sizeof(struct set_assocsta_rsp)); - if (psetassocsta_rsp == NULL) { - rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); - rtw_mfree((u8 *) psetassocsta_para, sizeof(struct set_assocsta_parm)); - return _FAIL; - } - - init_h2fwcmd_w_parm_no_rsp(ph2c, psetassocsta_para, _SetAssocSta_CMD_); - ph2c->rsp = (u8 *) psetassocsta_rsp; - ph2c->rspsz = sizeof(struct set_assocsta_rsp); - - _rtw_memcpy(psetassocsta_para->addr, mac_addr, ETH_ALEN); - - res = rtw_enqueue_cmd(pcmdpriv, ph2c); - -exit: - - - return res; -} - u8 rtw_addbareq_cmd(_adapter *padapter, u8 tid, u8 *addr) { struct cmd_priv *pcmdpriv = &padapter->cmdpriv; @@ -1978,7 +1541,7 @@ u8 rtw_addbareq_cmd(_adapter *padapter, u8 tid, u8 *addr) paddbareq_parm->tid = tid; _rtw_memcpy(paddbareq_parm->addr, addr, ETH_ALEN); - init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, GEN_CMD_CODE(_AddBAReq)); + init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, CMD_ADD_BAREQ); /* RTW_INFO("rtw_addbareq_cmd, tid=%d\n", tid); */ @@ -2019,7 +1582,7 @@ u8 rtw_addbarsp_cmd(_adapter *padapter, u8 *addr, u16 tid, u8 status, u8 size, u paddBaRsp_parm->size = size; paddBaRsp_parm->start_seq = start_seq; - init_h2fwcmd_w_parm_no_rsp(ph2c, paddBaRsp_parm, GEN_CMD_CODE(_AddBARsp)); + init_h2fwcmd_w_parm_no_rsp(ph2c, paddBaRsp_parm, CMD_ADD_BARSP); res = rtw_enqueue_cmd(pcmdpriv, ph2c); @@ -2055,7 +1618,7 @@ u8 rtw_reset_securitypriv_cmd(_adapter *padapter) pdrvextra_cmd_parm->size = 0; pdrvextra_cmd_parm->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ @@ -2103,7 +1666,7 @@ u8 rtw_free_assoc_resources_cmd(_adapter *padapter, u8 lock_scanned_queue, int f pdrvextra_cmd_parm->size = 0; pdrvextra_cmd_parm->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(cmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmd, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); if (flags & RTW_CMDF_WAIT_ACK) { cmd->sctx = &sctx; rtw_sctx_init(&sctx, 2000); @@ -2151,7 +1714,7 @@ u8 rtw_dynamic_chk_wk_cmd(_adapter *padapter) pdrvextra_cmd_parm->type = 0; pdrvextra_cmd_parm->size = 0; pdrvextra_cmd_parm->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ @@ -2164,6 +1727,47 @@ exit: } +u8 rtw_iqk_cmd(_adapter *padapter, u8 flags) +{ + struct cmd_obj *pcmdobj; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + struct submit_ctx sctx; + u8 res = _SUCCESS; + + if (flags & RTW_CMDF_DIRECTLY) { + /* no need to enqueue, do the cmd hdl */ + rtw_iqk_hdl(padapter, NULL); + } else { + /* need enqueue, prepare cmd_obj and enqueue */ + pcmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); + if (pcmdobj == NULL) { + res = _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_parm_rsp(pcmdobj, CMD_DO_IQK); + + if (flags & RTW_CMDF_WAIT_ACK) { + pcmdobj->sctx = &sctx; + rtw_sctx_init(&sctx, 10 * 1000); + } + + res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); + + if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) { + rtw_sctx_wait(&sctx, __func__); + _enter_critical_mutex(&pcmdpriv->sctx_mutex, NULL); + if (sctx.status == RTW_SCTX_SUBMITTED) + pcmdobj->sctx = NULL; + _exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL); + } + } + +exit: + + return res; +} + u8 rtw_set_chbw_cmd(_adapter *padapter, u8 ch, u8 bw, u8 ch_offset, u8 flags) { struct cmd_obj *pcmdobj; @@ -2203,7 +1807,7 @@ u8 rtw_set_chbw_cmd(_adapter *padapter, u8 ch, u8 bw, u8 ch_offset, u8 flags) goto exit; } - init_h2fwcmd_w_parm_no_rsp(pcmdobj, set_ch_parm, GEN_CMD_CODE(_SetChannel)); + init_h2fwcmd_w_parm_no_rsp(pcmdobj, set_ch_parm, CMD_SET_CHANNEL); if (flags & RTW_CMDF_WAIT_ACK) { pcmdobj->sctx = &sctx; @@ -2231,7 +1835,7 @@ exit: return res; } -u8 _rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, const struct country_chplan *country_ent, u8 swconfig) +static u8 _rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, const struct country_chplan *country_ent, enum regd_src_t regd_src, u8 swconfig) { struct cmd_obj *cmdobj; struct SetChannelPlan_param *parm; @@ -2239,7 +1843,6 @@ u8 _rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, const struct cou struct submit_ctx sctx; u8 res = _SUCCESS; - /* check if allow software config */ if (swconfig && rtw_hal_is_disable_sw_channel_plan(adapter) == _TRUE) { res = _FAIL; @@ -2251,7 +1854,7 @@ u8 _rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, const struct cou chplan = country_ent->chplan; /* check input parameter */ - if (!rtw_is_channel_plan_valid(chplan)) { + if (regd_src == REGD_SRC_RTK_PRIV && !rtw_is_channel_plan_valid(chplan)) { res = _FAIL; goto exit; } @@ -2262,12 +1865,13 @@ u8 _rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, const struct cou res = _FAIL; goto exit; } + parm->regd_src = regd_src; parm->country_ent = country_ent; parm->channel_plan = chplan; if (flags & RTW_CMDF_DIRECTLY) { /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ - if (H2C_SUCCESS != set_chplan_hdl(adapter, (u8 *)parm)) + if (H2C_SUCCESS != rtw_set_chplan_hdl(adapter, (u8 *)parm)) res = _FAIL; rtw_mfree((u8 *)parm, sizeof(*parm)); } else { @@ -2279,7 +1883,7 @@ u8 _rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, const struct cou goto exit; } - init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, GEN_CMD_CODE(_SetChannelPlan)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_SET_CHANPLAN); if (flags & RTW_CMDF_WAIT_ACK) { cmdobj->sctx = &sctx; @@ -2305,10 +1909,11 @@ u8 _rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, const struct cou res = _FAIL; goto exit; } + parm->regd_src = regd_src; parm->country_ent = country_ent; parm->channel_plan = chplan; - if (H2C_SUCCESS != set_chplan_hdl(adapter, (u8 *)parm)) + if (H2C_SUCCESS != rtw_set_chplan_hdl(adapter, (u8 *)parm)) res = _FAIL; else res = _SUCCESS; @@ -2322,15 +1927,15 @@ exit: inline u8 rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, u8 swconfig) { - return _rtw_set_chplan_cmd(adapter, flags, chplan, NULL, swconfig); + return _rtw_set_chplan_cmd(adapter, flags, chplan, NULL, REGD_SRC_RTK_PRIV, swconfig); } inline u8 rtw_set_country_cmd(_adapter *adapter, int flags, const char *country_code, u8 swconfig) { const struct country_chplan *ent; - if ((is_alpha(country_code[0]) == _FALSE - || is_alpha(country_code[1]) == _FALSE) - && (strncmp(country_code, "00", 2) != 0) + + if (is_alpha(country_code[0]) == _FALSE + || is_alpha(country_code[1]) == _FALSE ) { RTW_PRINT("%s input country_code is not alpha2\n", __func__); return _FAIL; @@ -2345,7 +1950,108 @@ inline u8 rtw_set_country_cmd(_adapter *adapter, int flags, const char *country_ RTW_PRINT("%s country_code:\"%c%c\" mapping to chplan:0x%02x\n", __func__, country_code[0], country_code[1], ent->chplan); - return _rtw_set_chplan_cmd(adapter, flags, RTW_CHPLAN_UNSPECIFIED, ent, swconfig); + return _rtw_set_chplan_cmd(adapter, flags, RTW_CHPLAN_UNSPECIFIED, ent, REGD_SRC_RTK_PRIV, swconfig); +} + +#ifdef CONFIG_REGD_SRC_FROM_OS +inline u8 rtw_sync_os_regd_cmd(_adapter *adapter, int flags, const char *country_code, u8 dfs_region) +{ + struct country_chplan *ent; + const struct country_chplan *rtk_ent; + + /* allocate entry for regd source out of driver */ + ent = rtw_malloc(sizeof(*ent)); + if (ent == NULL) + return _FAIL; + + rtk_ent = rtw_get_chplan_from_country(country_code); + + _rtw_memcpy(ent->alpha2, country_code, 2); + + /* + * Regulation follows OS, the internal txpwr limit selection is searched by alpha2 + * "00" => WW, others use string mapping + * When no matching txpwr limit selection is found, use + * 1. txpwr lmit selection associated with alpha2 inside driver regulation database + * 2. WW when driver has no support of this alpha2 + */ + + ent->chplan = rtk_ent ? rtk_ent->chplan : RTW_CHPLAN_UNSPECIFIED; + #ifdef CONFIG_80211AC_VHT + ent->en_11ac = 1; + #endif + + /* TODO: dfs_region */ + + return _rtw_set_chplan_cmd(adapter, flags, RTW_CHPLAN_UNSPECIFIED, ent, REGD_SRC_OS, 1); +} +#endif /* CONFIG_REGD_SRC_FROM_OS */ + +u8 rtw_get_chplan_cmd(_adapter *adapter, int flags, struct get_chplan_resp **resp) +{ + struct cmd_obj *cmdobj; + struct get_channel_plan_param *parm; + struct cmd_priv *pcmdpriv = &adapter->cmdpriv; + struct submit_ctx sctx; + u8 res = _FAIL; + + if (!(flags & (RTW_CMDF_DIRECTLY | RTW_CMDF_WAIT_ACK))) + goto exit; + + /* prepare cmd parameter */ + parm = rtw_zmalloc(sizeof(*parm)); + if (parm == NULL) + goto exit; + parm->resp = resp; + + if (flags & RTW_CMDF_DIRECTLY) { + /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ + if (H2C_SUCCESS == rtw_get_chplan_hdl(adapter, (u8 *)parm)) + res = _SUCCESS; + rtw_mfree((u8 *)parm, sizeof(*parm)); + } else { + /* need enqueue, prepare cmd_obj and enqueue */ + cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(*cmdobj)); + if (cmdobj == NULL) { + rtw_mfree((u8 *)parm, sizeof(*parm)); + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_GET_CHANPLAN); + + if (flags & RTW_CMDF_WAIT_ACK) { + cmdobj->sctx = &sctx; + rtw_sctx_init(&sctx, 2000); + } + + res = rtw_enqueue_cmd(pcmdpriv, cmdobj); + + if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) { + rtw_sctx_wait(&sctx, __func__); + _enter_critical_mutex(&pcmdpriv->sctx_mutex, NULL); + if (sctx.status == RTW_SCTX_SUBMITTED) + cmdobj->sctx = NULL; + _exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL); + if (sctx.status != RTW_SCTX_DONE_SUCCESS) + res = _FAIL; + } + + /* allow get channel plan when cmd_thread is not running */ + if (res != _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) { + parm = rtw_zmalloc(sizeof(*parm)); + if (parm == NULL) + goto exit; + parm->resp = resp; + + if (H2C_SUCCESS == rtw_get_chplan_hdl(adapter, (u8 *)parm)) + res = _SUCCESS; + + rtw_mfree((u8 *)parm, sizeof(*parm)); + } + } + +exit: + return res; } u8 rtw_led_blink_cmd(_adapter *padapter, void *pLed) @@ -2373,7 +2079,7 @@ u8 rtw_led_blink_cmd(_adapter *padapter, void *pLed) ledBlink_param->pLed = pLed; - init_h2fwcmd_w_parm_no_rsp(pcmdobj, ledBlink_param, GEN_CMD_CODE(_LedBlink)); + init_h2fwcmd_w_parm_no_rsp(pcmdobj, ledBlink_param, CMD_LEDBLINK); res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); exit: @@ -2394,7 +2100,7 @@ u8 rtw_set_csa_cmd(_adapter *adapter) goto exit; } - init_h2fwcmd_w_parm_no_parm_rsp(cmdobj, GEN_CMD_CODE(_SetChannelSwitch)); + init_h2fwcmd_w_parm_no_parm_rsp(cmdobj, CMD_SET_CHANSWITCH); res = rtw_enqueue_cmd(cmdpriv, cmdobj); exit: @@ -2428,7 +2134,7 @@ u8 rtw_tdls_cmd(_adapter *padapter, u8 *addr, u8 option) _rtw_memcpy(TDLSoption->addr, addr, 6); TDLSoption->option = option; _rtw_spinunlock(&(padapter->tdlsinfo.cmd_lock)); - init_h2fwcmd_w_parm_no_rsp(pcmdobj, TDLSoption, GEN_CMD_CODE(_TDLS)); + init_h2fwcmd_w_parm_no_rsp(pcmdobj, TDLSoption, CMD_TDLS); res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); exit: @@ -2463,7 +2169,7 @@ u8 rtw_enable_hw_update_tsf_cmd(_adapter *padapter) pdrvextra_cmd_parm->size = 0; pdrvextra_cmd_parm->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, ph2c); @@ -2496,7 +2202,7 @@ u8 rtw_periodic_tsf_update_end_cmd(_adapter *adapter) parm->size = 0; parm->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(cmdpriv, cmdobj); @@ -2557,7 +2263,7 @@ u8 rtw_ssmps_wk_cmd(_adapter *adapter, struct sta_info *sta, u8 smps, u8 enqueue cmd_parm->size = sizeof(struct ssmps_cmd_parm); cmd_parm->pbuf = (u8 *)ssmp_param; - init_h2fwcmd_w_parm_no_rsp(cmdobj, cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, cmdobj); } else { @@ -2742,7 +2448,7 @@ u8 rtw_ctrl_txss_wk_cmd(_adapter *adapter, struct sta_info *sta, bool tx_1ss, u8 cmd_parm->size = sizeof(struct txss_cmd_parm); cmd_parm->pbuf = (u8 *)txss_param; - init_h2fwcmd_w_parm_no_rsp(cmdobj, cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, cmd_parm, CMD_SET_DRV_EXTRA); if (flag & RTW_CMDF_WAIT_ACK) { cmdobj->sctx = &sctx; @@ -3094,7 +2800,7 @@ u8 traffic_status_watchdog(_adapter *padapter, u8 from_timer) /* */ /* Determine if our traffic is busy now */ /* */ - if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if ((check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) /*&& !MgntInitAdapterInProgress(pMgntInfo)*/) { /* if we raise bBusyTraffic in last watchdog, using lower threshold. */ if (pmlmepriv->LinkDetectInfo.bBusyTraffic) @@ -3199,7 +2905,7 @@ u8 traffic_status_watchdog(_adapter *padapter, u8 from_timer) } - +#ifdef CONFIG_AP_MODE /* for 11n Logo 4.2.31/4.2.32 */ static void dynamic_update_bcn_check(_adapter *padapter) { @@ -3252,10 +2958,12 @@ static void dynamic_update_bcn_check(_adapter *padapter) count ++; } } +#endif /* CONFIG_AP_MODE */ + void rtw_iface_dynamic_chk_wk_hdl(_adapter *padapter) { - #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK #ifdef CONFIG_AP_MODE + #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) { expire_timeout_chk(padapter); #ifdef CONFIG_RTW_MESH @@ -3263,17 +2971,19 @@ void rtw_iface_dynamic_chk_wk_hdl(_adapter *padapter) rtw_mesh_peer_status_chk(padapter); #endif } - #endif #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */ + dynamic_update_bcn_check(padapter); + #endif /* CONFIG_AP_MODE */ + linked_status_chk(padapter, 0); traffic_status_watchdog(padapter, 0); /* for debug purpose */ _linked_info_dump(padapter); -#ifdef CONFIG_RTW_CFGVEDNOR_RSSIMONITOR +#ifdef CONFIG_RTW_CFGVENDOR_RSSIMONITOR rtw_cfgvendor_rssi_monitor_evt(padapter); #endif @@ -3282,13 +2992,17 @@ void rtw_iface_dynamic_chk_wk_hdl(_adapter *padapter) void rtw_dynamic_chk_wk_hdl(_adapter *padapter) { rtw_mi_dynamic_chk_wk_hdl(padapter); - -#ifdef DBG_CONFIG_ERROR_DETECT - rtw_hal_sreset_xmit_status_check(padapter); - rtw_hal_sreset_linked_status_check(padapter); +#ifdef CONFIG_MP_INCLUDED + if (rtw_mp_mode_check(padapter) == _FALSE) #endif + { +#ifdef DBG_CONFIG_ERROR_DETECT + rtw_hal_sreset_xmit_status_check(padapter); + rtw_hal_sreset_linked_status_check(padapter); +#endif + } - /* if(check_fwstate(pmlmepriv, _FW_UNDER_LINKING|_FW_UNDER_SURVEY)==_FALSE) */ + /* if(check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_SURVEY)==_FALSE) */ { #ifdef DBG_RX_COUNTER_DUMP rtw_dump_rx_counters(padapter); @@ -3304,6 +3018,14 @@ void rtw_dynamic_chk_wk_hdl(_adapter *padapter) rtw_btcoex_Handler(padapter); #endif +#ifdef CONFIG_RTW_MULTI_AP + rtw_ch_util_rpt(padapter); +#endif + +#ifdef CONFIG_DFS_MASTER + rtw_chset_chk_non_ocp_finish(adapter_to_rfctl(padapter)); +#endif + #ifdef CONFIG_IPS_CHECK_IN_WD /* always call rtw_ps_processor() at last one. */ rtw_ps_processor(padapter); @@ -3341,7 +3063,7 @@ void lps_ctrl_wk_hdl(_adapter *padapter, u8 lps_ctrl_type, u8 *buf) #ifdef CONFIG_BT_COEXIST rtw_btcoex_ScanNotify(padapter, _TRUE); #endif /* CONFIG_BT_COEXIST */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { /* connect */ LPS_Leave(padapter, "LPS_CTRL_SCAN"); } @@ -3462,7 +3184,7 @@ static u8 _rtw_lps_ctrl_wk_cmd(_adapter *adapter, u8 lps_ctrl_type, s8 lps_level goto exit; } - init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_SET_DRV_EXTRA); if (flags & RTW_CMDF_WAIT_ACK) { cmdobj->sctx = &sctx; @@ -3534,7 +3256,7 @@ u8 rtw_dm_in_lps_wk_cmd(_adapter *padapter) pdrvextra_cmd_parm->size = 0; pdrvextra_cmd_parm->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, ph2c); @@ -3572,7 +3294,7 @@ void rtw_lps_change_dtim_hdl(_adapter *padapter, u8 dtim) /* RTW_INFO("change DTIM from %d to %d, ps_mode=%d\n", pwrpriv->dtim, dtim, ps_mode); */ - rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); + rtw_exec_lps(padapter, ps_mode); } #ifdef CONFIG_LPS_LCLK @@ -3614,7 +3336,7 @@ u8 rtw_lps_change_dtim_cmd(_adapter *padapter, u8 dtim) pdrvextra_cmd_parm->size = 0; pdrvextra_cmd_parm->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, ph2c); } @@ -3656,7 +3378,7 @@ u8 rtw_rpt_timer_cfg_cmd(_adapter *padapter, u16 minRptTime) pdrvextra_cmd_parm->type = minRptTime; pdrvextra_cmd_parm->size = 0; pdrvextra_cmd_parm->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, ph2c); exit: @@ -3710,7 +3432,7 @@ u8 rtw_antenna_select_cmd(_adapter *padapter, u8 antenna, u8 enqueue) pdrvextra_cmd_parm->type = antenna; pdrvextra_cmd_parm->size = 0; pdrvextra_cmd_parm->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, ph2c); } else @@ -3755,7 +3477,7 @@ u8 rtw_dm_ra_mask_wk_cmd(_adapter *padapter, u8 *psta) pdrvextra_cmd_parm->size = 0; pdrvextra_cmd_parm->pbuf = psta; - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, ph2c); @@ -3807,7 +3529,7 @@ u8 p2p_protocol_wk_cmd(_adapter *padapter, int intCmdType) pdrvextra_cmd_parm->size = 0; pdrvextra_cmd_parm->pbuf = NULL; /* Must be NULL here */ - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, ph2c); @@ -3817,28 +3539,22 @@ exit: return res; } +#endif /* CONFIG_P2P */ #ifdef CONFIG_IOCTL_CFG80211 -static u8 _p2p_roch_cmd(_adapter *adapter +static struct rtw_roch_parm *rtw_alloc_roch_parm(_adapter *adapter , u64 cookie, struct wireless_dev *wdev , struct ieee80211_channel *ch, enum nl80211_channel_type ch_type , unsigned int duration , u8 flags ) { - struct cmd_obj *cmdobj; - struct drvextra_cmd_parm *parm; - struct p2p_roch_parm *roch_parm; - struct cmd_priv *pcmdpriv = &adapter->cmdpriv; - struct submit_ctx sctx; - u8 cancel = duration ? 0 : 1; - u8 res = _SUCCESS; + struct rtw_roch_parm *roch_parm; + bool cancel = duration ? 0 : 1; - roch_parm = (struct p2p_roch_parm *)rtw_zmalloc(sizeof(struct p2p_roch_parm)); - if (roch_parm == NULL) { - res = _FAIL; - goto exit; - } + roch_parm = (struct rtw_roch_parm *)rtw_zmalloc(sizeof(struct rtw_roch_parm)); + if (!roch_parm) + return NULL; roch_parm->cookie = cookie; roch_parm->wdev = wdev; @@ -3848,76 +3564,36 @@ static u8 _p2p_roch_cmd(_adapter *adapter roch_parm->duration = duration; } - if (flags & RTW_CMDF_DIRECTLY) { - /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ - if (H2C_SUCCESS != p2p_protocol_wk_hdl(adapter, cancel ? P2P_CANCEL_RO_CH_WK : P2P_RO_CH_WK, (u8 *)roch_parm)) - res = _FAIL; - rtw_mfree((u8 *)roch_parm, sizeof(*roch_parm)); - } else { - /* need enqueue, prepare cmd_obj and enqueue */ - parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); - if (parm == NULL) { - rtw_mfree((u8 *)roch_parm, sizeof(*roch_parm)); - res = _FAIL; - goto exit; - } - - parm->ec_id = P2P_PROTO_WK_CID; - parm->type = cancel ? P2P_CANCEL_RO_CH_WK : P2P_RO_CH_WK; - parm->size = sizeof(*roch_parm); - parm->pbuf = (u8 *)roch_parm; - - cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(*cmdobj)); - if (cmdobj == NULL) { - res = _FAIL; - rtw_mfree((u8 *)roch_parm, sizeof(*roch_parm)); - rtw_mfree((u8 *)parm, sizeof(*parm)); - goto exit; - } - - init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, GEN_CMD_CODE(_Set_Drv_Extra)); - - if (flags & RTW_CMDF_WAIT_ACK) { - cmdobj->sctx = &sctx; - rtw_sctx_init(&sctx, 10 * 1000); - } - - res = rtw_enqueue_cmd(pcmdpriv, cmdobj); - - if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) { - rtw_sctx_wait(&sctx, __func__); - _enter_critical_mutex(&pcmdpriv->sctx_mutex, NULL); - if (sctx.status == RTW_SCTX_SUBMITTED) - cmdobj->sctx = NULL; - _exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL); - if (sctx.status != RTW_SCTX_DONE_SUCCESS) - res = _FAIL; - } - } - -exit: - return res; + return roch_parm; } -inline u8 p2p_roch_cmd(_adapter *adapter +inline u8 rtw_roch_cmd(_adapter *adapter , u64 cookie, struct wireless_dev *wdev , struct ieee80211_channel *ch, enum nl80211_channel_type ch_type , unsigned int duration , u8 flags ) { - return _p2p_roch_cmd(adapter, cookie, wdev, ch, ch_type, duration, flags); + struct rtw_roch_parm *roch_parm; + + roch_parm = rtw_alloc_roch_parm(adapter, cookie, wdev, ch, ch_type, duration, flags); + if (!roch_parm) + return _FAIL; + + return rtw_roch_wk_cmd(adapter, ROCH_RO_CH_WK, roch_parm, flags); } -inline u8 p2p_cancel_roch_cmd(_adapter *adapter, u64 cookie, struct wireless_dev *wdev, u8 flags) +inline u8 rtw_cancel_roch_cmd(_adapter *adapter, u64 cookie, struct wireless_dev *wdev, u8 flags) { - return _p2p_roch_cmd(adapter, cookie, wdev, NULL, 0, 0, flags); + struct rtw_roch_parm *roch_parm; + + roch_parm = rtw_alloc_roch_parm(adapter, cookie, wdev, NULL, 0, 0, flags); + if (!roch_parm) + return _FAIL; + + return rtw_roch_wk_cmd(adapter, ROCH_CANCEL_RO_CH_WK, roch_parm, flags); } -#endif /* CONFIG_IOCTL_CFG80211 */ -#endif /* CONFIG_P2P */ - -#ifdef CONFIG_IOCTL_CFG80211 inline u8 rtw_mgnt_tx_cmd(_adapter *adapter, u8 tx_ch, u8 no_cck, const u8 *buf, size_t len, int wait_ack, u8 flags) { struct cmd_obj *cmdobj; @@ -3966,7 +3642,7 @@ inline u8 rtw_mgnt_tx_cmd(_adapter *adapter, u8 tx_ch, u8 no_cck, const u8 *buf, goto exit; } - init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_SET_DRV_EXTRA); if (flags & RTW_CMDF_WAIT_ACK) { cmdobj->sctx = &sctx; @@ -4021,7 +3697,7 @@ u8 rtw_ps_cmd(_adapter *padapter) pdrvextra_cmd_parm->type = 0; pdrvextra_cmd_parm->size = 0; pdrvextra_cmd_parm->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, ppscmd); @@ -4037,9 +3713,11 @@ void rtw_dfs_ch_switch_hdl(struct dvobj_priv *dvobj) { struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); _adapter *pri_adapter = dvobj_get_primary_adapter(dvobj); + struct mlme_ext_priv *pmlmeext = &pri_adapter->mlmeextpriv; u8 ifbmp_m = rtw_mi_get_ap_mesh_ifbmp(pri_adapter); u8 ifbmp_s = rtw_mi_get_ld_sta_ifbmp(pri_adapter); s16 req_ch; + u8 req_bw = CHANNEL_WIDTH_20, req_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; rtw_hal_macid_sleep_all_used(pri_adapter); @@ -4066,7 +3744,29 @@ void rtw_dfs_ch_switch_hdl(struct dvobj_priv *dvobj) RTW_INFO("%s switch to ch%d\n", __func__, req_ch); } - /* issue deauth for all asoc STA ifaces */ + /* only support 80 Mhz so far */ + if(rfctl->csa_ch_width == 1 || rfctl->csa_ch_width == 2 || rfctl->csa_ch_width == 3) { + if (rtw_get_offset_by_chbw(req_ch, CHANNEL_WIDTH_80, &req_offset)) { + req_bw = CHANNEL_WIDTH_80; + } else { + req_bw = CHANNEL_WIDTH_20; + req_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + } + } else if(rfctl->csa_ch_offset == 1) { + req_bw = CHANNEL_WIDTH_40; + req_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + } else if(rfctl->csa_ch_offset == 3) { + req_bw = CHANNEL_WIDTH_40; + req_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + } else{ + req_bw = CHANNEL_WIDTH_20; + req_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + } + + RTW_INFO("req_ch=%d, req_bw=%d, req_offset=%d, ifbmp_m=0x%02x, ifbmp_s=0x%02x\n" + , req_ch, req_bw, req_offset, ifbmp_m, ifbmp_s); + + /* update ch, bw, offset for all asoc STA ifaces */ if (ifbmp_s) { _adapter *iface; int i; @@ -4075,47 +3775,50 @@ void rtw_dfs_ch_switch_hdl(struct dvobj_priv *dvobj) iface = dvobj->padapters[i]; if (!iface || !(ifbmp_s & BIT(iface->iface_id))) continue; - set_fwstate(&iface->mlmepriv, WIFI_OP_CH_SWITCHING); - - /* TODO: true op ch switching */ - issue_deauth(iface, get_bssid(&iface->mlmepriv), WLAN_REASON_DEAUTH_LEAVING); + + /* update STA mode ch/bw/offset */ + iface->mlmeextpriv.cur_channel = req_ch; + iface->mlmeextpriv.cur_bwmode = req_bw; + iface->mlmeextpriv.cur_ch_offset = req_offset; + /* updaet STA mode DSConfig , ap mode will update in rtw_change_bss_chbw_cmd */ + iface->mlmepriv.cur_network.network.Configuration.DSConfig = req_ch; + set_fwstate(&iface->mlmepriv, WIFI_CSA_UPDATE_BEACON); + } } + if (rfctl->csa_ch > 0) { + RTW_INFO("pmlmeext->csa_timer 70 seconds\n"); + /* wait 70 seconds for receiving beacons */ + _set_timer(&pmlmeext->csa_timer, CAC_TIME_MS + 10000); + } + #ifdef CONFIG_AP_MODE if (ifbmp_m) { - /* trigger channel selection without consideraton of asoc STA ifaces */ + /* trigger channel selection with consideraton of asoc STA ifaces */ rtw_change_bss_chbw_cmd(dvobj_get_primary_adapter(dvobj), RTW_CMDF_DIRECTLY - , ifbmp_m, ifbmp_s, req_ch, REQ_BW_ORI, REQ_OFFSET_NONE); + , ifbmp_m, 0, req_ch, REQ_BW_ORI, REQ_OFFSET_NONE); } else #endif { /* no AP/MESH iface, switch DFS status and channel directly */ rtw_warn_on(req_ch <= 0); #ifdef CONFIG_DFS_MASTER - rtw_dfs_rd_en_decision(pri_adapter, MLME_OPCH_SWITCH, ifbmp_s); + rtw_dfs_rd_en_decision(pri_adapter, MLME_OPCH_SWITCH, 0); #endif - set_channel_bwmode(pri_adapter, req_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + LeaveAllPowerSaveModeDirect(pri_adapter); + set_channel_bwmode(pri_adapter, req_ch, req_offset, req_bw); + /* update union ch/bw/offset for STA only */ + rtw_mi_update_union_chan_inf(pri_adapter, req_ch, req_offset, req_bw); + rtw_rfctl_update_op_mode(rfctl, 0, 0); } - - /* make asoc STA ifaces disconnect */ - /* TODO: true op ch switching */ - if (ifbmp_s) { - _adapter *iface; - int i; - for (i = 0; i < dvobj->iface_nums; i++) { - iface = dvobj->padapters[i]; - if (!iface || !(ifbmp_s & BIT(iface->iface_id))) - continue; - rtw_disassoc_cmd(iface, 0, RTW_CMDF_DIRECTLY); - rtw_indicate_disconnect(iface, 0, _FALSE); - rtw_free_assoc_resources(iface, _TRUE); - rtw_free_network_queue(iface, _TRUE); - } - } - rfctl->csa_ch = 0; + rfctl->csa_switch_cnt = 0; + rfctl->csa_ch_offset = 0; + rfctl->csa_ch_width = 0; + rfctl->csa_ch_freq_seg0 = 0; + rfctl->csa_ch_freq_seg1 = 0; rtw_hal_macid_wakeup_all_used(pri_adapter); rtw_mi_os_xmit_schedule(pri_adapter); @@ -4186,7 +3889,7 @@ u8 rtw_chk_hi_queue_cmd(_adapter *padapter) pdrvextra_cmd_parm->size = 0; pdrvextra_cmd_parm->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, ph2c); @@ -4201,10 +3904,13 @@ u8 rtw_dfs_rd_hdl(_adapter *adapter) { struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + u8 cch; if (!rfctl->radar_detect_enabled) goto exit; + cch = rtw_get_center_ch(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset); + if (dvobj->oper_channel != rfctl->radar_detect_ch || rtw_get_passing_time_ms(rtw_get_on_oper_ch_time(adapter)) < 300 ) { @@ -4241,6 +3947,10 @@ u8 rtw_dfs_rd_hdl(_adapter *adapter) rtw_chset_update_non_ocp(rfctl->channel_set , rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset); + if (IS_UNDER_CAC(rfctl)) + rtw_nlrtw_cac_abort_event(adapter, cch, rfctl->radar_detect_bw); + rtw_nlrtw_radar_detect_event(adapter, cch, rfctl->radar_detect_bw); + rtw_dfs_ch_switch_hdl(dvobj); if (rfctl->radar_detect_enabled) @@ -4258,8 +3968,9 @@ cac_status_chk: rtw_hal_set_hwreg(adapter, HW_VAR_TXPAUSE, &pause); rfctl->cac_start_time = rfctl->cac_end_time = RTW_CAC_STOPPED; + rtw_nlrtw_cac_finish_event(adapter, cch, rfctl->radar_detect_bw); - if (rtw_mi_check_fwstate(adapter, WIFI_UNDER_LINKING|WIFI_SITE_MONITOR) == _FALSE) { + if (rtw_mi_check_fwstate(adapter, WIFI_UNDER_LINKING|WIFI_UNDER_SURVEY) == _FALSE) { u8 doiqk = _TRUE; u8 u_ch, u_bw, u_offset; @@ -4273,8 +3984,10 @@ cac_status_chk: doiqk = _FALSE; rtw_hal_set_hwreg(adapter , HW_VAR_DO_IQK , &doiqk); + #ifdef CONFIG_AP_MODE ResumeTxBeacon(adapter); rtw_mi_tx_beacon_hdl(adapter); + #endif } } @@ -4309,7 +4022,7 @@ u8 rtw_dfs_rd_cmd(_adapter *adapter, bool enqueue) parm->size = 0; parm->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(cmdpriv, cmdobj); } else { rtw_dfs_rd_hdl(adapter); @@ -4389,7 +4102,7 @@ static void rtw_dfs_rd_disable(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, rfctl->cac_start_time = rfctl->cac_end_time = RTW_CAC_STOPPED; _cancel_timer_ex(&rfctl->radar_detect_timer); - if (rtw_mi_check_fwstate(adapter, WIFI_UNDER_LINKING|WIFI_SITE_MONITOR) == _FALSE) { + if (rtw_mi_check_fwstate(adapter, WIFI_UNDER_LINKING|WIFI_UNDER_SURVEY) == _FALSE) { ResumeTxBeacon(adapter); rtw_mi_tx_beacon_hdl(adapter); } @@ -4406,6 +4119,10 @@ static void rtw_dfs_rd_disable(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, rfctl->radar_detect_ch = ch; rfctl->radar_detect_bw = bw; rfctl->radar_detect_offset = offset; + } else { + rfctl->radar_detect_ch = 0; + rfctl->radar_detect_bw = 0; + rfctl->radar_detect_offset = 0; } } @@ -4543,7 +4260,7 @@ u8 rtw_dfs_rd_en_decision_cmd(_adapter *adapter) parm->size = 0; parm->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(cmdpriv, cmdobj); exit: @@ -4697,7 +4414,7 @@ u8 rtw_btinfo_cmd(_adapter *adapter, u8 *buf, u16 len) _rtw_memcpy(btinfo, buf, len); - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, ph2c); @@ -4739,7 +4456,7 @@ u8 rtw_btc_reduce_wl_txpwr_cmd(_adapter *adapter, u32 val) pdrvextra_cmd_parm->size = 0; pdrvextra_cmd_parm->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(pcmdobj, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(pcmdobj, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); @@ -4784,7 +4501,7 @@ u8 rtw_test_h2c_cmd(_adapter *adapter, u8 *buf, u8 len) _rtw_memcpy(ph2c_content, buf, len); - init_h2fwcmd_w_parm_no_rsp(pcmdobj, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(pcmdobj, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); @@ -4804,7 +4521,7 @@ static s32 rtw_mp_cmd_hdl(_adapter *padapter, u8 mp_cmd_id) rtw_intf_stop(padapter); rtw_hal_deinit(padapter); padapter->registrypriv.mp_mode = 1; -#if (CONFIG_BTCOEX_SUPPORT_WIFI_ONLY_CFG == 1) +#ifdef CONFIG_BT_COEXIST padapter->mppriv.CureFuseBTCoex = pHalData->EEPROMBluetoothCoexist; pHalData->EEPROMBluetoothCoexist = _FALSE; #endif @@ -4876,7 +4593,7 @@ static s32 rtw_mp_cmd_hdl(_adapter *padapter, u8 mp_cmd_id) rtw_intf_stop(padapter); rtw_hal_deinit(padapter); padapter->registrypriv.mp_mode = 0; -#if (CONFIG_BTCOEX_SUPPORT_WIFI_ONLY_CFG == 1) +#ifdef CONFIG_BT_COEXIST pHalData->EEPROMBluetoothCoexist = padapter->mppriv.CureFuseBTCoex; #endif rtw_reset_drv_sw(padapter); @@ -4949,7 +4666,7 @@ u8 rtw_mp_cmd(_adapter *adapter, u8 mp_cmd_id, u8 flags) goto exit; } - init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_SET_DRV_EXTRA); if (flags & RTW_CMDF_WAIT_ACK) { cmdobj->sctx = &sctx; @@ -5029,7 +4746,7 @@ static u8 rtw_customer_str_cmd(_adapter *adapter, u8 write, const u8 *cstr) goto exit; } - init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_SET_DRV_EXTRA); cmdobj->sctx = &sctx; rtw_sctx_init(&sctx, 2 * 1000); @@ -5096,7 +4813,7 @@ u8 rtw_c2h_wk_cmd(PADAPTER padapter, u8 *pbuf, u16 length, u8 type) pdrvextra_cmd_parm->size = length; pdrvextra_cmd_parm->pbuf = extra_cmd_buf; - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, ph2c); @@ -5141,7 +4858,7 @@ static u8 _rtw_run_in_thread_cmd(_adapter *adapter, void (*func)(void *), void * parm->func = func; parm->context = context; - init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, GEN_CMD_CODE(_RunInThreadCMD)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_RUN_INTHREAD); if (timeout_ms >= 0) { cmdobj->sctx = &sctx; @@ -5243,7 +4960,7 @@ u8 session_tracker_cmd(_adapter *adapter, u8 cmd, struct sta_info *sta, u8 *loca cmd_parm->type = 0; cmd_parm->size = sizeof(struct st_cmd_parm); cmd_parm->pbuf = (u8 *)st_parm; - init_h2fwcmd_w_parm_no_rsp(cmdobj, cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, cmd_parm, CMD_SET_DRV_EXTRA); cmdobj->no_io = 1; res = rtw_enqueue_cmd(cmdpriv, cmdobj); @@ -5280,7 +4997,7 @@ void session_tracker_chk_for_sta(_adapter *adapter, struct sta_info *sta) if (DBG_SESSION_TRACKER) RTW_INFO(FUNC_ADPT_FMT" sta:%p\n", FUNC_ADPT_ARG(adapter), sta); - if (!(sta->state & _FW_LINKED)) + if (!(sta->state & WIFI_ASOC_STATE)) goto exit; for (i = 0; i < SESSION_TRACKER_REG_ID_NUM; i++) { @@ -5413,7 +5130,7 @@ void session_tracker_cmd_hdl(_adapter *adapter, struct st_cmd_parm *parm) , IP_ARG(&remote_naddr), PORT_ARG(&remote_port) ); - if (!(sta->state & _FW_LINKED)) + if (!(sta->state & WIFI_ASOC_STATE)) goto exit; st_ctl = &sta->st_ctl; @@ -5533,7 +5250,7 @@ u8 rtw_req_per_cmd(_adapter *adapter) goto exit; } - init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, cmdobj); @@ -5721,6 +5438,13 @@ u8 rtw_drvextra_cmd_hdl(_adapter *padapter, unsigned char *pbuf) ret = rtw_mgnt_tx_handler(padapter, pdrvextra_cmd->pbuf); break; #endif /* CONFIG_IOCTL_CFG80211 */ + +#if (defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)) || defined(CONFIG_IOCTL_CFG80211) + case ROCH_WK_CID: + ret = rtw_roch_wk_hdl(padapter, pdrvextra_cmd->type, pdrvextra_cmd->pbuf); + break; +#endif /* (defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)) || defined(CONFIG_IOCTL_CFG80211) */ + #ifdef CONFIG_MCC_MODE case MCC_CMD_WK_CID: ret = rtw_mcc_cmd_hdl(padapter, pdrvextra_cmd->type, pdrvextra_cmd->pbuf); @@ -5748,6 +5472,11 @@ u8 rtw_drvextra_cmd_hdl(_adapter *padapter, unsigned char *pbuf) case STOP_AP_WK_CID: stop_ap_hdl(padapter); break; +#endif +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + case TBTX_CONTROL_TX_WK_CID: + tx_control_hdl(padapter); + break; #endif default: break; @@ -5784,7 +5513,7 @@ void rtw_disassoc_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd) if (pcmd->res != H2C_SUCCESS) { _enter_critical_bh(&pmlmepriv->lock, &irqL); - set_fwstate(pmlmepriv, _FW_LINKED); + set_fwstate(pmlmepriv, WIFI_ASOC_STATE); _exit_critical_bh(&pmlmepriv->lock, &irqL); goto exit; } @@ -5800,15 +5529,6 @@ exit: return; } - -void rtw_getmacreg_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd) -{ - - - rtw_free_cmd_obj(pcmd); - -} - void rtw_joinbss_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -5867,9 +5587,9 @@ void rtw_create_ibss_post_hdl(_adapter *padapter, int status) mlme_cur_network->network.Configuration.DSConfig = (u32)rtw_ch2freq(pdev_network->Configuration.DSConfig); #endif - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING); _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); - /* we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback) */ + /* we will set WIFI_ASOC_STATE when there is one more sat to join us (rtw_stassoc_event_callback) */ } createbss_cmd_fail: @@ -5899,36 +5619,7 @@ exit: } -void rtw_setassocsta_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd) -{ - _irqL irqL; - struct sta_priv *pstapriv = &padapter->stapriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct set_assocsta_parm *passocsta_parm = (struct set_assocsta_parm *)(pcmd->parmbuf); - struct set_assocsta_rsp *passocsta_rsp = (struct set_assocsta_rsp *)(pcmd->rsp); - struct sta_info *psta = rtw_get_stainfo(pstapriv, passocsta_parm->addr); - - if (psta == NULL) { - goto exit; - } - - psta->cmn.aid = psta->cmn.mac_id = passocsta_rsp->cam_id; - - _enter_critical_bh(&pmlmepriv->lock, &irqL); - - if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)) - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); - - set_fwstate(pmlmepriv, _FW_LINKED); - _exit_critical_bh(&pmlmepriv->lock, &irqL); - -exit: - rtw_free_cmd_obj(pcmd); - -} - -void rtw_getrttbl_cmd_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); void rtw_getrttbl_cmd_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd) { @@ -5980,9 +5671,40 @@ u8 set_txq_params_cmd(_adapter *adapter, u32 ac_parm, u8 ac_type) _rtw_memcpy(ac_parm_buf, &ac_parm, sz); - init_h2fwcmd_w_parm_no_rsp(cmdobj, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, cmdobj); exit: return res; } + +/* Driver writes beacon length to REG for FW adjusting beacon receive time */ +#ifdef CONFIG_WRITE_BCN_LEN_TO_FW +u8 rtw_write_bcnlen_to_fw_cmd(_adapter *padapter, u16 bcn_len) +{ + struct cmd_obj *pcmd; + struct write_bcnlen_param *parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + + pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); + if (pcmd == NULL) { + res = _FAIL; + goto exit; + } + + parm = (struct write_bcnlen_param *)rtw_zmalloc(sizeof(struct write_bcnlen_param)); + if (parm == NULL) { + rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj)); + res = _FAIL; + goto exit; + } + + parm->bcn_len = bcn_len; + init_h2fwcmd_w_parm_no_rsp(pcmd, parm, CMD_WRITE_BCN_LEN); + res = rtw_enqueue_cmd(pcmdpriv, pcmd); + +exit: + return res; +} +#endif /* CONFIG_WRITE_BCN_LEN_TO_FW */ diff --git a/core/rtw_debug.c b/core/rtw_debug.c index ee0bd33..99cf624 100644 --- a/core/rtw_debug.c +++ b/core/rtw_debug.c @@ -42,11 +42,14 @@ const char *rtw_log_level_str[] = { void dump_drv_version(void *sel) { RTW_PRINT_SEL(sel, "%s %s\n", DRV_NAME, DRIVERVERSION); - // RTW_PRINT_SEL(sel, "build time: %s %s\n", __DATE__, __TIME__); + RTW_PRINT_SEL(sel, "build time: %s %s\n", __DATE__, __TIME__); } +#ifdef CONFIG_PROC_DEBUG void dump_drv_cfg(void *sel) { +extern uint rtw_recvbuf_nr; + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)) char *kernel_version = utsname()->release; @@ -157,12 +160,16 @@ void dump_drv_cfg(void *sel) RTW_PRINT_SEL(sel, "CONFIG_RTW_WIFI_HAL\n"); #endif +#ifdef RTW_BUSY_DENY_SCAN + RTW_PRINT_SEL(sel, "RTW_BUSY_DENY_SCAN\n"); + RTW_PRINT_SEL(sel, "BUSY_TRAFFIC_SCAN_DENY_PERIOD = %u ms\n", \ + BUSY_TRAFFIC_SCAN_DENY_PERIOD); +#endif + #ifdef CONFIG_RTW_TPT_MODE RTW_PRINT_SEL(sel, "CONFIG_RTW_TPT_MODE\n"); #endif - RTW_PRINT_SEL(sel, "RTW_VHT_2G4=%d\n", RTW_VHT_2G4); - #ifdef CONFIG_USB_HCI #ifdef CONFIG_SUPPORT_USB_INT RTW_PRINT_SEL(sel, "CONFIG_SUPPORT_USB_INT\n"); @@ -241,10 +248,12 @@ void dump_drv_cfg(void *sel) RTW_PRINT_SEL(sel, "\n=== RECV-INFO ===\n"); RTW_PRINT_SEL(sel, "NR_RECVFRAME = %d\n", NR_RECVFRAME); - RTW_PRINT_SEL(sel, "NR_RECVBUFF = %d\n", NR_RECVBUFF); + RTW_PRINT_SEL(sel, "NR_RECVBUFF = %d, rtw_recvbuf_nr = %d\n", NR_RECVBUFF, rtw_recvbuf_nr); RTW_PRINT_SEL(sel, "MAX_RECVBUF_SZ = %d\n", MAX_RECVBUF_SZ); } +#endif /* CONFIG_PROC_DEBUG */ + void dump_log_level(void *sel) { @@ -320,7 +329,8 @@ void mac_reg_dump(void *sel, _adapter *adapter) } #endif /* CONFIG_RTL8814A */ -#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) ||defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) +#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) \ + || defined(CONFIG_RTL8723F) for (i = 0x1000; i < 0x1800; i += 4) { if (j % 4 == 1) RTW_PRINT_SEL(sel, "0x%04x", i); @@ -328,7 +338,24 @@ void mac_reg_dump(void *sel, _adapter *adapter) if ((j++) % 4 == 0) _RTW_PRINT_SEL(sel, "\n"); } -#endif /* CONFIG_RTL8822B or 8821c or 8192f*/ +#endif /* CONFIG_RTL8822B or 8821c*/ + +#if defined(CONFIG_RTL8192F) + for (i = 0x1000; i < 0x1100; i += 4) { + if (j % 4 == 1) + RTW_PRINT_SEL(sel, "0x%04x", i); + _RTW_PRINT_SEL(sel, " 0x%08x ", rtw_read32(adapter, i)); + if ((j++) % 4 == 0) + _RTW_PRINT_SEL(sel, "\n"); + } + for (i = 0x1300; i < 0x1360; i += 4) { + if (j % 4 == 1) + RTW_PRINT_SEL(sel, "0x%04x", i); + _RTW_PRINT_SEL(sel, " 0x%08x ", rtw_read32(adapter, i)); + if ((j++) % 4 == 0) + _RTW_PRINT_SEL(sel, "\n"); + } +#endif #if defined(CONFIG_RTL8814B) for (i = 0x2000; i < 0x2800; i += 4) { @@ -363,7 +390,8 @@ void bb_reg_dump(void *sel, _adapter *adapter) _RTW_PRINT_SEL(sel, "\n"); } -#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) +#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) \ + || defined(CONFIG_RTL8723F) for (i = 0x1800; i < 0x2000; i += 4) { if (j % 4 == 1) RTW_PRINT_SEL(sel, "0x%04x", i); @@ -373,7 +401,7 @@ void bb_reg_dump(void *sel, _adapter *adapter) } #endif /* CONFIG_RTL8822B */ -#if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) +#if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) || defined(CONFIG_RTL8723F) for (i = 0x2c00; i < 0x2c60; i += 4) { if (j % 4 == 1) RTW_PRINT_SEL(sel, "0x%04x", i); @@ -388,7 +416,7 @@ void bb_reg_dump(void *sel, _adapter *adapter) _RTW_PRINT_SEL(sel, " 0x%08x ", rtw_read32(adapter, i)); if ((j++) % 4 == 0) _RTW_PRINT_SEL(sel, "\n"); - } + } for (i = 0x4000; i < 0x4060; i += 4) { if (j % 4 == 1) @@ -396,7 +424,7 @@ void bb_reg_dump(void *sel, _adapter *adapter) _RTW_PRINT_SEL(sel, " 0x%08x ", rtw_read32(adapter, i)); if ((j++) % 4 == 0) _RTW_PRINT_SEL(sel, "\n"); - } + } for (i = 0x4100; i < 0x4200; i += 4) { if (j % 4 == 1) @@ -404,9 +432,9 @@ void bb_reg_dump(void *sel, _adapter *adapter) _RTW_PRINT_SEL(sel, " 0x%08x ", rtw_read32(adapter, i)); if ((j++) % 4 == 0) _RTW_PRINT_SEL(sel, "\n"); - } + } -#endif /* CONFIG_RTL8822C || CONFIG_RTL8814B */ +#endif /* CONFIG_RTL8822C || CONFIG_RTL8814B || CONFIG_8723F */ #if defined(CONFIG_RTL8814B) for (i = 0x5200; i < 0x5400; i += 4) { @@ -417,6 +445,17 @@ void bb_reg_dump(void *sel, _adapter *adapter) _RTW_PRINT_SEL(sel, "\n"); } #endif /* CONFIG_RTL8814B */ + +#if defined(CONFIG_RTL8723F) + /* TSSI related */ + for (i = 0x4300; i < 0x43C0; i += 4) { + if (j % 4 == 1) + RTW_PRINT_SEL(sel, "0x%04x", i); + _RTW_PRINT_SEL(sel, " 0x%08x ", rtw_read32(adapter, i)); + if ((j++) % 4 == 0) + _RTW_PRINT_SEL(sel, "\n"); + } +#endif /* CONFIG_RTL8723F */ } void bb_reg_dump_ex(void *sel, _adapter *adapter) @@ -441,9 +480,10 @@ void bb_reg_dump_ex(void *sel, _adapter *adapter) void rf_reg_dump(void *sel, _adapter *adapter) { + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); int i, j = 1, path; u32 value; - u8 path_nums = GET_HAL_RFPATH_NUM(adapter); + u8 path_nums = hal_spec->rf_reg_path_num; RTW_PRINT_SEL(sel, "======= RF REG =======\n"); @@ -537,6 +577,7 @@ void dump_tx_rate_bmp(void *sel, struct dvobj_priv *dvobj) void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) { +#if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG) struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); int i; _adapter *iface; @@ -610,11 +651,11 @@ void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) #define INFO_CNT_ARG #endif - RTW_PRINT_SEL(sel, "%-2s %-15s %c %-3s %-3s %-3s %-17s %-4s %-7s" + RTW_PRINT_SEL(sel, "%-2s %-15s %c %-3s %-3s %-3s %-17s %-4s %-7s %-5s" P2P_INFO_TITLE_FMT TSF_PAUSE_TIME_TITLE_FMT " %s"INFO_FMT"\n" - , "id", "ifname", ' ', "bup", "nup", "ncd", "macaddr", "port", "ch" + , "id", "ifname", ' ', "bup", "nup", "ncd", "macaddr", "port", "ch", "class" P2P_INFO_TITLE_ARG TSF_PAUSE_TIME_TITLE_ARG , "status"INFO_ARG); @@ -629,7 +670,7 @@ void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) #if (defined(CONFIG_SUPPORT_MULTI_BCN) && defined(CONFIG_FW_HANDLE_TXBCN)) || defined(CONFIG_CLIENT_PORT_CFG) _rtw_memset(&str_val, '\0', sizeof(str_val)); #endif - #if defined(CONFIG_SUPPORT_MULTI_BCN) && defined(CONFIG_FW_HANDLE_TXBCN) + #if defined(CONFIG_AP_MODE) && defined(CONFIG_SUPPORT_MULTI_BCN) && defined(CONFIG_FW_HANDLE_TXBCN) if (MLME_IS_AP(iface) || MLME_IS_MESH(iface)) { u8 len; char *p = str_val; @@ -666,7 +707,7 @@ void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) } #endif - RTW_PRINT_SEL(sel, "%2d %-15s %c %3u %3u %3u "MAC_FMT" %4hhu %3u,%u,%u" + RTW_PRINT_SEL(sel, "%2d %-15s %c %3u %3u %3u "MAC_FMT" %4hhu %3u,%u,%u %5u" P2P_INFO_VALUE_FMT TSF_PAUSE_TIME_VALUE_FMT " "MLME_STATE_FMT" " INFO_CNT_FMT"\n" @@ -680,6 +721,9 @@ void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) , iface->mlmeextpriv.cur_channel , iface->mlmeextpriv.cur_bwmode , iface->mlmeextpriv.cur_ch_offset + , rtw_get_op_class_by_chbw(iface->mlmeextpriv.cur_channel + , iface->mlmeextpriv.cur_bwmode + , iface->mlmeextpriv.cur_ch_offset) P2P_INFO_VALUE_ARG TSF_PAUSE_TIME_VALUE_ARG , MLME_STATE_ARG(iface) @@ -693,9 +737,9 @@ void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) "-------\n"); if (rtw_mi_get_ch_setting_union(dvobj_get_primary_adapter(dvobj), &u_ch, &u_bw, &u_offset)) - RTW_PRINT_SEL(sel, "%55s %3u,%u,%u\n" + RTW_PRINT_SEL(sel, "%55s %3u,%u,%u %5u\n" , "union:" - , u_ch, u_bw, u_offset); + , u_ch, u_bw, u_offset, rtw_get_op_class_by_chbw(u_ch, u_bw, u_offset)); RTW_PRINT_SEL(sel, "%55s %3u,%u,%u offch_state:%d\n" , "oper:" @@ -721,7 +765,7 @@ void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) u32 cac_ms; u8 dfs_domain = rtw_rfctl_get_dfs_domain(rfctl); - _RTW_PRINT_SEL(sel, ", domain:%u", dfs_domain); + _RTW_PRINT_SEL(sel, ", domain:%s(%u)", rtw_dfs_regd_str(dfs_domain), dfs_domain); rtw_get_ch_waiting_ms(rfctl , rfctl->radar_detect_ch @@ -740,22 +784,26 @@ void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) _RTW_PRINT_SEL(sel, "\n"); } #endif /* CONFIG_DFS_MASTER */ +#endif /* CONFIG_RTW_DEBUG || CONFIG_PROC_DEBUG */ } +#if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG) #define SEC_CAM_ENT_ID_TITLE_FMT "%-2s" #define SEC_CAM_ENT_ID_TITLE_ARG "id" #define SEC_CAM_ENT_ID_VALUE_FMT "%2u" #define SEC_CAM_ENT_ID_VALUE_ARG(id) (id) -#define SEC_CAM_ENT_TITLE_FMT "%-6s %-17s %-32s %-3s %-7s %-2s %-2s %-5s" +#define SEC_CAM_ENT_TITLE_FMT "%-6s %-17s %-32s %-3s %-8s %-2s %-2s %-5s" #define SEC_CAM_ENT_TITLE_ARG "ctrl", "addr", "key", "kid", "type", "MK", "GK", "valid" -#define SEC_CAM_ENT_VALUE_FMT "0x%04x "MAC_FMT" "KEY_FMT" %3u %-7s %2u %2u %5u" +#define SEC_CAM_ENT_VALUE_FMT "0x%04x "MAC_FMT" "KEY_FMT" %3u %-8s %2u %2u %5u" #define SEC_CAM_ENT_VALUE_ARG(ent) \ (ent)->ctrl \ , MAC_ARG((ent)->mac) \ , KEY_ARG((ent)->key) \ , ((ent)->ctrl) & 0x03 \ - , security_type_str((((ent)->ctrl) >> 2) & 0x07) \ + , (((ent)->ctrl) & 0x200) ? \ + security_type_str((((ent)->ctrl) >> 2 & 0x7) | _SEC_TYPE_256_) : \ + security_type_str(((ent)->ctrl) >> 2 & 0x7) \ , (((ent)->ctrl) >> 5) & 0x01 \ , (((ent)->ctrl) >> 6) & 0x01 \ , (((ent)->ctrl) >> 15) & 0x01 @@ -777,9 +825,11 @@ void dump_sec_cam_ent_title(void *sel, u8 has_id) } else RTW_PRINT_SEL(sel, SEC_CAM_ENT_TITLE_FMT"\n", SEC_CAM_ENT_TITLE_ARG); } +#endif void dump_sec_cam(void *sel, _adapter *adapter) { +#if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG) struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; struct sec_cam_ent ent; @@ -791,10 +841,12 @@ void dump_sec_cam(void *sel, _adapter *adapter) rtw_sec_read_cam_ent(adapter, i, (u8 *)(&ent.ctrl), ent.mac, ent.key); dump_sec_cam_ent(sel , &ent, i); } +#endif } void dump_sec_cam_cache(void *sel, _adapter *adapter) { +#if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG) struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; int i; @@ -805,7 +857,7 @@ void dump_sec_cam_cache(void *sel, _adapter *adapter) if (dvobj->cam_cache[i].ctrl != 0) dump_sec_cam_ent(sel, &dvobj->cam_cache[i], i); } - +#endif } static u8 fwdl_test_chksum_fail = 0; @@ -885,6 +937,53 @@ u16 rtw_ap_linking_test_force_asoc_fail(void) #endif #ifdef CONFIG_PROC_DEBUG +int proc_get_defs_param(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *mlme = &adapter->mlmepriv; + + RTW_PRINT_SEL(m, "%s %15s\n", "lmt_sta", "lmt_time"); + RTW_PRINT_SEL(m, "%-15u %-15u\n" + , mlme->defs_lmt_sta + , mlme->defs_lmt_time + ); + + return 0; +} + +ssize_t proc_set_defs_param(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *mlme = &adapter->mlmepriv; + + char tmp[32]; + u32 defs_lmt_sta; + u32 defs_lmt_time; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%u %u", &defs_lmt_sta, &defs_lmt_time); + + if (num >= 1) + mlme->defs_lmt_sta = defs_lmt_sta; + if (num >= 2) + mlme->defs_lmt_time = defs_lmt_time; + } + + return count; + +} + ssize_t proc_set_write_reg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) { struct net_device *dev = data; @@ -1061,6 +1160,11 @@ int proc_get_tx_stat(struct seq_file *m, void *v) u8 null_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; struct submit_ctx gotc2h; + if (!adapter->hal_func.reqtxrpt) { + RTW_PRINT_SEL(m, "Not support.\n"); + return 0; + } + _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); for (i = 0; i < NUM_STA; i++) { phead = &(pstapriv->sta_hash[i]); @@ -1088,7 +1192,7 @@ int proc_get_tx_stat(struct seq_file *m, void *v) psta = rtw_get_stainfo(pstapriv, &sta_mac[i][0]); if(psta) { pstats = &psta->sta_stats; -#ifndef ROKU_PRIVATE +#if (!defined(ROKU_PRIVATE) && !defined(CONFIG_RTW_MULTI_AP)) RTW_PRINT_SEL(m, "data_sent_cnt :\t%u\n", pstats->tx_ok_cnt + pstats->tx_fail_cnt); RTW_PRINT_SEL(m, "success_cnt :\t%u\n", pstats->tx_ok_cnt); RTW_PRINT_SEL(m, "failure_cnt :\t%u\n", pstats->tx_fail_cnt); @@ -1153,6 +1257,11 @@ int proc_get_sec_info(struct seq_file *m, void *v) , sec->aes_sw_enc_cnt_bc , sec->aes_sw_enc_cnt_mc, sec->aes_sw_enc_cnt_uc); RTW_PRINT_SEL(m, "aes_sw_dec_cnt=%llu, %llu, %llu\n" , sec->aes_sw_dec_cnt_bc , sec->aes_sw_dec_cnt_mc, sec->aes_sw_dec_cnt_uc); + + RTW_PRINT_SEL(m, "gcmp_sw_enc_cnt=%llu, %llu, %llu\n" + , sec->gcmp_sw_enc_cnt_bc , sec->gcmp_sw_enc_cnt_mc, sec->gcmp_sw_enc_cnt_uc); + RTW_PRINT_SEL(m, "gcmp_sw_dec_cnt=%llu, %llu, %llu\n" + , sec->gcmp_sw_dec_cnt_bc , sec->gcmp_sw_dec_cnt_mc, sec->gcmp_sw_dec_cnt_uc); #endif /* DBG_SW_SEC_CNT */ return 0; @@ -1293,44 +1402,609 @@ ssize_t proc_set_roam_tgt_addr(struct file *file, const char __user *buffer, siz } #endif /* CONFIG_LAYER2_ROAMING */ -#ifdef CONFIG_RTW_80211R -ssize_t proc_set_ft_flags(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +#ifdef CONFIG_WAR_OFFLOAD +int proc_get_war_offload_enable(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + + if (_TRUE == pwrpriv->wowlan_war_offload_mode) { + RTW_PRINT_SEL(m, "\n[ Offload Feature Enabled ]\n"); + + if (WAR_ARP_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) { + RTW_PRINT_SEL(m, "\n ARP Reponse offload enabled\n"); + } +#ifdef CONFIG_OFFLOAD_MDNS_V4 + if (WAR_MDNS_V4_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) { + RTW_PRINT_SEL(m, "\n MDNS v4 Reponse offload enabled\n"); + } + if (WAR_MDNS_V4_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl) { + RTW_PRINT_SEL(m, "\n MDNS v4 Wakeup offload enabled\n"); + } +#endif /* CONFIG_OFFLOAD_MDNS_v4 */ +#ifdef CONFIG_OFFLOAD_MDNS_V6 + if (WAR_MDNS_V6_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) { + RTW_PRINT_SEL(m, "\n MDNS v6 Reponse offload enabled\n"); + } + if (WAR_MDNS_V6_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl) { + RTW_PRINT_SEL(m, "\n MDNS v6 Wakeup offload enabled\n"); + } +#endif /* CONFIG_OFFLOAD_MDNS_V6 */ + + if (WAR_ARP_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl) { + RTW_PRINT_SEL(m, "\n ARP Request wakeup enabled\n"); + } + + } else { + RTW_PRINT_SEL(m, "\n[ Offload Feature Disabled ]\n"); + } + + return 0; +} + +ssize_t proc_set_war_offload_enable(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) { struct net_device *dev = data; - _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); - + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); char tmp[32]; - u8 flags; + u32 offload_cfg = 0; - if (count < 1) + if (NULL == buffer) { + RTW_INFO(FUNC_ADPT_FMT ": input buffer is NULL!\n", FUNC_ADPT_ARG(padapter)); return -EFAULT; + } + + if (count < 1) { + RTW_INFO(FUNC_ADPT_FMT ": input length is 0!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } if (count > sizeof(tmp)) { + RTW_INFO(FUNC_ADPT_FMT ": input length is too large\n", FUNC_ADPT_ARG(padapter)); rtw_warn_on(1); return -EFAULT; } if (buffer && !copy_from_user(tmp, buffer, count)) { - int num = sscanf(tmp, "%hhx", &flags); + int num = sscanf(tmp, "%x", &offload_cfg); - if (num == 1) - adapter->mlmepriv.ft_roam.ft_flags = flags; + if (num == 1) { + RTW_INFO(FUNC_ADPT_FMT ": Set war offload cfg = %x\n", FUNC_ADPT_ARG(padapter), offload_cfg); + pwrpriv->wowlan_war_offload_ctrl = offload_cfg; + pwrpriv->wowlan_war_offload_mode = offload_cfg?_TRUE:_FALSE; + + } } return count; +} + +ssize_t proc_set_war_offload_ipv4_addr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + char tmp[128]; + u32 ip_addr = 0, ip_subnet = 0, ip_gateway = 0, index = 0; + struct war_ipv4_fmt* pip_info = &pwrpriv->wowlan_war_offload_ipv4; + + if (NULL == buffer) { + RTW_INFO(FUNC_ADPT_FMT ": input buffer is NULL!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count < 1) { + RTW_INFO(FUNC_ADPT_FMT ": input length is 0!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count > sizeof(tmp)) { + RTW_INFO(FUNC_ADPT_FMT ": input length is too large\n", FUNC_ADPT_ARG(padapter)); + rtw_warn_on(1); + return -EFAULT; + } + + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%d %x %x %x", &index, &ip_addr, &ip_subnet, &ip_gateway); + + if (num == 4) { + pip_info->ip_addr[index-1] = ip_addr; + pip_info->ip_subnet[index-1] = ip_subnet; + pip_info->ip_gateway[index-1] = ip_gateway; + RTW_INFO(FUNC_ADPT_FMT "Setup IPv4 address:\n", FUNC_ADPT_ARG(padapter)); + RTW_INFO("Index(%d) IP=%d.%d.%d.%d\n", index, (ip_addr & 0xff), ((ip_addr & 0xff00)>>8), ((ip_addr & 0xff0000)>>16), ((ip_addr & 0xff000000)>>24)); + } else { + RTW_INFO("Wrong input buffer count (%d)\n", num); + return -EFAULT; + } + } + + return count; +} + +ssize_t proc_set_war_offload_ipv6_addr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + char tmp[255]; + u32 ip_addr = 0, ip_subnet = 0, ip_gateway = 0; + struct war_ipv6_fmt* pip_info = &pwrpriv->wowlan_war_offload_ipv6; + + if (NULL == buffer) { + RTW_INFO(FUNC_ADPT_FMT ": input buffer is NULL!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count < 1) { + RTW_INFO(FUNC_ADPT_FMT ": input length is 0!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count > sizeof(tmp)) { + RTW_INFO(FUNC_ADPT_FMT ": input length is too large\n", FUNC_ADPT_ARG(padapter)); + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num; + int i; + u32 index; + u16 val[64]; + u16 big_endian_val[64]; + + num = sscanf(tmp, "%d %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", &index, &val[0], &val[1], &val[2], &val[3], &val[4], &val[5], &val[6], &val[7]); + for (i=0;i<8;i++) { + big_endian_val[i] = htons(val[i]); + } + _rtw_memcpy(pip_info->ipv6_addr[index-1], big_endian_val, RTW_IPv6_ADDR_LEN); + + if (num == 9) { + RTW_INFO(FUNC_ADPT_FMT "Setup IPv6 address\n", FUNC_ADPT_ARG(padapter)); + } else { + RTW_INFO("Wrong input count (%d)\n", num); + return -EFAULT; + } + } + + return count; +} + +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) + +int proc_get_war_offload_mdns_domain_name(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + + if (_TRUE == pwrpriv->wowlan_war_offload_mode) { + if ((WAR_MDNS_V4_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V4_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl)) { + RTW_PRINT_SEL(m, "\nDomain Name:[%s](%d)\n\n", + pwrpriv->wowlan_war_offload_mdns_domain_name, pwrpriv->wowlan_war_offload_mdns_domain_name_len); + } else { + RTW_PRINT_SEL(m, "\nMSND RSP Not enabled\n\n"); + } + } else { + RTW_PRINT_SEL(m, "\nOffload Not enabled\n\n"); + } + + return 0; +} + +ssize_t proc_set_war_offload_mdns_domain_name(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + char tmp[MAX_MDNS_DOMAIN_NAME_LEN+1]; + char domain_name[MAX_MDNS_DOMAIN_NAME_LEN+1]; + + if (NULL == buffer) { + RTW_INFO(FUNC_ADPT_FMT ": input buffer is NULL!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count < 1) { + RTW_INFO(FUNC_ADPT_FMT ": input length is 0!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count > sizeof(tmp)) { + RTW_INFO(FUNC_ADPT_FMT ": input length is large than MAX_MDNS_DOMAIN_NAME_LEN(%d)\n", FUNC_ADPT_ARG(padapter), MAX_MDNS_DOMAIN_NAME_LEN); + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%s", domain_name); + if(1 == num) { + pwrpriv->wowlan_war_offload_mdns_domain_name_len = strlen(domain_name); + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_domain_name, 0x00, MAX_MDNS_DOMAIN_NAME_LEN); + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_domain_name, domain_name, strlen(domain_name)); + } + } + + return count; +} + + +int proc_get_war_offload_mdns_machine_name(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + int i=0; + + if (_TRUE == pwrpriv->wowlan_war_offload_mode) { + if ((WAR_MDNS_V4_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V4_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl)) { + for(i=0; iwowlan_war_offload_mdns_mnane_num; i++) + { + RTW_PRINT_SEL(m, "[%d]", i); + rtw_wow_war_mdns_dump_buf(m, "Machine Name", + pwrpriv->wowlan_war_offload_mdns_mnane[i].name, pwrpriv->wowlan_war_offload_mdns_mnane[i].name_len); + } + RTW_PRINT_SEL(m, "\n"); + } else { + RTW_PRINT_SEL(m, "\nMSND RSP Not enabled\n\n"); + } + } else { + RTW_PRINT_SEL(m, "\nOffload Not enabled\n\n"); + } + + return 0; +} + + +ssize_t proc_set_war_offload_mdns_machine_name(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + char tmp[MAX_MDNS_MACHINE_NAME_LEN*3-1+1]; + + if (NULL == buffer) { + RTW_INFO(FUNC_ADPT_FMT ": input buffer is NULL!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count < 1) { + RTW_INFO(FUNC_ADPT_FMT ": input length is 0!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count > sizeof(tmp)) { + RTW_INFO(FUNC_ADPT_FMT ": input length, %lu, is large than MAX_MDNS_MACHINE_NAME_LEN(%d)\n", FUNC_ADPT_ARG(padapter), (count+1)/3, MAX_MDNS_MACHINE_NAME_LEN); + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + if( strncmp(tmp, "clean", 5) == 0 ) + { + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_mnane, 0, sizeof(pwrpriv->wowlan_war_offload_mdns_mnane)); + pwrpriv->wowlan_war_offload_mdns_mnane_num = 0; + }else{ + int idx = pwrpriv->wowlan_war_offload_mdns_mnane_num; + if(idx == MAX_MDNS_MACHINE_NAME_NUM){ + RTW_INFO(FUNC_ADPT_FMT ": the num of machine name is already %d(MAX_MDNS_MACHINE_NAME_NUM)!\n", FUNC_ADPT_ARG(padapter), MAX_MDNS_MACHINE_NAME_NUM); + return -EFAULT; + } + if(rtw_wow_war_mdns_parser_pattern(tmp, pwrpriv->wowlan_war_offload_mdns_mnane[idx].name, + (u32 *) &pwrpriv->wowlan_war_offload_mdns_mnane[idx].name_len, MAX_MDNS_MACHINE_NAME_LEN)) + pwrpriv->wowlan_war_offload_mdns_mnane_num++; + } + } + + return count; +} + + +int proc_get_war_offload_mdns_service_info(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + struct war_mdns_service_info *psinfo = pwrpriv->wowlan_war_offload_mdns_service; + int i=0, j=0; + + if (_TRUE == pwrpriv->wowlan_war_offload_mode) { + if ((WAR_MDNS_V4_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V4_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl)) { + for(i=0; iwowlan_war_offload_mdns_service_info_num; i++) + { + RTW_PRINT_SEL(m, "[%d] service info ===> \n", i+1); + RTW_PRINT_SEL(m, "\tservice-transport-domain : %s(%d)- %s(%d)- %s(%d)\n", + psinfo[i].service, psinfo[i].service_len, + psinfo[i].transport, psinfo[i].transport_len, + psinfo[i].domain, psinfo[i].domain_len); + RTW_PRINT_SEL(m, "\ttarget for srv rsp : %s(%d)\n", psinfo[i].target, psinfo[i].target_len); + RTW_PRINT_SEL(m, "\tport : %x-%x, ttl : %d \n", psinfo[i].port[0], psinfo[i].port[1], psinfo[i].ttl); + j = psinfo[i].txt_rsp_idx; + RTW_PRINT_SEL(m, "\ttype txt rsp. [%d] \n", j); + rtw_wow_war_mdns_dump_txt(m, "type txt rsp. (Str)", + pwrpriv->wowlan_war_offload_mdns_txt_rsp[j].txt, pwrpriv->wowlan_war_offload_mdns_txt_rsp[j].txt_len); + + } + RTW_PRINT_SEL(m, "\n"); + } else { + RTW_PRINT_SEL(m, "\nMSND RSP Not enabled\n\n"); + } + } else { + RTW_PRINT_SEL(m, "\nOffload Not enabled\n\n"); + } + + return 0; +} + +ssize_t proc_set_war_offload_mdns_service_info(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + struct war_mdns_service_info *psinfo = pwrpriv->wowlan_war_offload_mdns_service; + u8 idx = 0, port[2], i=0; + char *tmp=NULL; + char srv[MAX_MDNS_SERVICE_NAME_LEN+1], trans[MAX_MDNS_TRANS_LEN+1], domain[MAX_MDNS_DOMAIN_LEN+1]; + char target[MAX_MDNS_TARGET_LEN+1]; + u32 ttl, tmp_txt_len=0, port0 =0, port1 =0; + u16 max_input_size = (MAX_MDNS_SERVICE_NAME_LEN+MAX_MDNS_TRANS_LEN+MAX_MDNS_DOMAIN_LEN+MAX_MDNS_TARGET_LEN+2); + int txt_idx; + + if (NULL == buffer) { + RTW_INFO(FUNC_ADPT_FMT ": input buffer is NULL!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count < 1) { + RTW_INFO(FUNC_ADPT_FMT ": input length is 0!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count > (sizeof(char)*(max_input_size)) ) { + RTW_INFO(FUNC_ADPT_FMT ": input length is too large\n", FUNC_ADPT_ARG(padapter)); + rtw_warn_on(1); + return -EFAULT; + } + + tmp = rtw_zvmalloc(sizeof(char)*(max_input_size)); + if (NULL == tmp) { + RTW_INFO(FUNC_ADPT_FMT ": tmp buffer allocate fail!!\n", FUNC_ADPT_ARG(padapter)); + count = -EFAULT; + goto exit; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%15s %4s %5s %63s %x %x %u %d", srv, trans, domain, target, &port0, &port1, &ttl, &txt_idx); + /* MAX_MDNS_SERVICE_NAME_LEN(15), MAX_MDNS_TRANS_LEN(4), MAX_MDNS_DOMAIN_LEN(5), MAX_MDNS_TARGET_LEN(63) */ + int idx = pwrpriv->wowlan_war_offload_mdns_service_info_num; + u16 curent_txt_total_size = 0; + //u16 sscanf_parameter_length = strlen(srv)+strlen(trans)+strlen(domain)+strlen(target)+2+2+4+1+num; + + if( strncmp(srv, "clean", 5) == 0 ) { + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_service, 0, sizeof(pwrpriv->wowlan_war_offload_mdns_service)); + pwrpriv->wowlan_war_offload_mdns_service_info_num = 0; + } + /*else if(count != sscanf_parameter_length) + { + RTW_INFO(FUNC_ADPT_FMT ": Length of total parameters does not match the input buffer. (%d != %lu)\n", + FUNC_ADPT_ARG(padapter), sscanf_parameter_length, count); + RTW_INFO(FUNC_ADPT_FMT ": Please check the content and length of each parameter.\n", FUNC_ADPT_ARG(padapter)); + RTW_INFO(FUNC_ADPT_FMT ": input buffer = (%s)(%lu)!\n\n", FUNC_ADPT_ARG(padapter), tmp, count); + RTW_INFO(FUNC_ADPT_FMT ": srv = %s (%lu)!\n", FUNC_ADPT_ARG(padapter), srv, strlen(srv)); + RTW_INFO(FUNC_ADPT_FMT ": trans = %s (%lu)!\n", FUNC_ADPT_ARG(padapter), trans, strlen(trans)); + RTW_INFO(FUNC_ADPT_FMT ": domain = %s (%lu)!\n", FUNC_ADPT_ARG(padapter), domain, strlen(domain)); + RTW_INFO(FUNC_ADPT_FMT ": target = %s (%lu)!\n", FUNC_ADPT_ARG(padapter), target, strlen(target)); + RTW_INFO(FUNC_ADPT_FMT ": port = %x-%x, ttl = %d!\n", FUNC_ADPT_ARG(padapter), port0, port1, ttl); + RTW_INFO(FUNC_ADPT_FMT ": txt idx = %d!\n", FUNC_ADPT_ARG(padapter), txt_idx); + count = -EFAULT; + goto exit; + }*/else + { + port[0] = (u8)port0; + port[1] = (u8)port1; + + if(txt_idx >= MAX_MDNS_TXT_NUM) { + RTW_INFO(FUNC_ADPT_FMT ": input txt idx, %d, is out of range (0~%d)!\n", FUNC_ADPT_ARG(padapter), txt_idx, MAX_MDNS_TXT_NUM-1); + count = -EFAULT; + goto exit; + } + + if(pwrpriv->wowlan_war_offload_mdns_txt_rsp[txt_idx].txt_len == 0) { + RTW_INFO(FUNC_ADPT_FMT ": wowlan_war_offload_mdns_txt_rsp[%d] is null! Please initiate it first.\n", FUNC_ADPT_ARG(padapter), txt_idx); + count = -EFAULT; + goto exit; + } + + // 1. set the value of members for this new service + psinfo[idx].service_len = strlen(srv); + _rtw_memcpy(psinfo[idx].service, srv, psinfo[idx].service_len ); + psinfo[idx].transport_len = strlen(trans); + _rtw_memcpy(psinfo[idx].transport, trans, psinfo[idx].transport_len ); + psinfo[idx].domain_len = strlen(domain); + _rtw_memcpy(psinfo[idx].domain, domain, psinfo[idx].domain_len ); + psinfo[idx].target_len = strlen(target); + _rtw_memcpy(psinfo[idx].target, target, psinfo[idx].target_len ); + _rtw_memcpy(psinfo[idx].port, port, 2 ); + psinfo[idx].ttl = ttl; + psinfo[idx].txt_rsp_idx = txt_idx; + pwrpriv->wowlan_war_offload_mdns_service_info_num++; + } + } + +exit: + if(tmp) + rtw_vmfree(tmp, sizeof(char)*(max_input_size)); + return count; } -int proc_get_ft_flags(struct seq_file *m, void *v) +int proc_get_war_offload_mdns_txt_rsp(struct seq_file *m, void *v) { struct net_device *dev = m->private; _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + int i=0; - RTW_PRINT_SEL(m, "0x%02x\n", adapter->mlmepriv.ft_roam.ft_flags); + if (_TRUE == pwrpriv->wowlan_war_offload_mode) { + if ((WAR_MDNS_V4_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) ) { + for(i=0; iwowlan_war_offload_mdns_txt_rsp_num; i++) { + RTW_PRINT_SEL(m, "[%d]", i); + if(pwrpriv->wowlan_war_offload_mdns_txt_rsp[i].txt_len==0){ + RTW_PRINT_SEL(m, " (null)\n"); + continue; + } + rtw_wow_war_mdns_dump_txt(m, "type txt rsp. (Str)", + pwrpriv->wowlan_war_offload_mdns_txt_rsp[i].txt, pwrpriv->wowlan_war_offload_mdns_txt_rsp[i].txt_len); + rtw_wow_war_mdns_dump_buf(m, "type txt rsp. (Hex)", + pwrpriv->wowlan_war_offload_mdns_txt_rsp[i].txt, pwrpriv->wowlan_war_offload_mdns_txt_rsp[i].txt_len); + } + RTW_PRINT_SEL(m, "\n"); + } else { + RTW_PRINT_SEL(m, "\nMSND RSP Not enabled\n\n"); + } + } else { + RTW_PRINT_SEL(m, "\nOffload Not enabled\n\n"); + } return 0; } -#endif + +ssize_t proc_set_war_offload_mdns_txt_rsp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + u16 max_input_size = (1+6+MAX_MDNS_TXT_SINGLE_LEN+2); + char* tmp=NULL; + char op[7]={0}, txt_str[MAX_MDNS_TXT_SINGLE_LEN+1]={0}; + int idx; + + if (NULL == buffer) { + RTW_INFO(FUNC_ADPT_FMT ": input buffer is NULL!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count < 1) { + RTW_INFO(FUNC_ADPT_FMT ": input length is 0!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + tmp = rtw_zvmalloc(sizeof(char)*(max_input_size)); + if (NULL == tmp) { + RTW_INFO(FUNC_ADPT_FMT ": tmp buffer allocate fail!!\n", FUNC_ADPT_ARG(padapter)); + count = -EFAULT; + goto exit; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + if( strncmp(tmp, "clean", 5) == 0 ) + { + /* clean ==> */ + if(pwrpriv->wowlan_war_offload_mdns_service_info_num==0){ + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_txt_rsp, 0, sizeof(pwrpriv->wowlan_war_offload_mdns_txt_rsp)); + }else{ + RTW_INFO(FUNC_ADPT_FMT ": Txt rsp are refered! (Current service_info_num = %d)\n", FUNC_ADPT_ARG(padapter), pwrpriv->wowlan_war_offload_mdns_service_info_num); + count = -EFAULT; + goto exit; + } + + }else{ + /* set ==> */ + int num = sscanf(tmp, "%d %6s %256c", &idx, op, txt_str); + u16 sscanf_parameter_length = 0, txt_len = 0; + + txt_len = (strlen(txt_str)>MAX_MDNS_TXT_SINGLE_LEN)?MAX_MDNS_TXT_SINGLE_LEN:(strlen(txt_str)-1); + txt_str[txt_len]='\0'; + sscanf_parameter_length = 1 + strlen(op) + txt_len + num; + + if(count != sscanf_parameter_length) { + RTW_INFO(FUNC_ADPT_FMT ": Length of total parameters does not match the input buffer. (%d != %lu)(num=%d)\n", + FUNC_ADPT_ARG(padapter), sscanf_parameter_length, count, num); + RTW_INFO(FUNC_ADPT_FMT ": Please check the content and length of each parameter.\n", FUNC_ADPT_ARG(padapter)); + RTW_INFO(FUNC_ADPT_FMT ": input buffer = (%s)(%lu)!\n\n", FUNC_ADPT_ARG(padapter), tmp, count); + RTW_INFO(FUNC_ADPT_FMT ": op. = %s (%lu)!\n", FUNC_ADPT_ARG(padapter), op, strlen(op)); + RTW_INFO(FUNC_ADPT_FMT ": txt = %s (%lu)!\n", FUNC_ADPT_ARG(padapter), txt_str, strlen(txt_str)); + count = -EFAULT; + goto exit; + } else { + + u16 offset; + + if(idx >= MAX_MDNS_TXT_NUM) { + RTW_INFO(FUNC_ADPT_FMT ": the index, %d, is over the range of txt rsp(0~%d)!\n", FUNC_ADPT_ARG(padapter), idx, MAX_MDNS_TXT_NUM-1); + count = -EFAULT; + goto exit; + } + + if( strncmp(op, "new", 3) == 0 ) { + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt, 0, pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt_len); + pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt_len = 0; + }else if(strncmp(op, "append", 6) == 0 ){ + if((pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt_len+strlen(txt_str)+1) > MAX_MDNS_TXT_LEN) { + RTW_INFO(FUNC_ADPT_FMT ": the txt rsp(%d) will be over the limitation(%d) if append input string(%lu)!\n", FUNC_ADPT_ARG(padapter), + pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt_len, + MAX_MDNS_TXT_LEN, strlen(txt_str)+1); + count = -EFAULT; + goto exit; + } + }else{ + RTW_INFO(FUNC_ADPT_FMT ": Invaild op str %s (new/append only)!\n", FUNC_ADPT_ARG(padapter), op); + count = -EFAULT; + goto exit; + } + + offset = pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt_len; + pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt[offset++] = strlen(txt_str); + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt + offset, txt_str, strlen(txt_str)); + pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt_len += (strlen(txt_str) + 1); /* actul len with length field */ + + /* Dump ==> */ + //RTW_PRINT_SEL(RTW_DBGDUMP, "[%d]", idx); + //rtw_wow_war_mdns_dump_txt(RTW_DBGDUMP, "type txt rsp. (Str)", + // pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt, pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt_len); + } + } + } + +exit: + if(tmp) + rtw_vmfree(tmp, sizeof(char)*(max_input_size)); + return count; + +} + +#endif /* CONFIG_OFFLOAD_MDNS_V4 || CONFIG_OFFLOAD_MDNS_V6 */ +#endif /* CONFIG_WAR_OFFLOAD */ + + int proc_get_qos_option(struct seq_file *m, void *v) { @@ -1578,6 +2252,7 @@ int proc_get_survey_info(struct seq_file *m, void *v) #else const char *ssid_title_str = "ssid"; #endif + u8 rsni = 255; _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); phead = get_list_head(queue); @@ -1591,7 +2266,8 @@ int proc_get_survey_info(struct seq_file *m, void *v) rtw_rson_show_survey_info(m, plist, phead); #else - RTW_PRINT_SEL(m, "%5s %-17s %3s %-3s %-4s %-4s %5s %32s %32s\n", "index", "bssid", "ch", "RSSI", "SdBm", "Noise", "age", "flag", ssid_title_str); + RTW_PRINT_SEL(m, "%5s %-17s %3s %-3s %-4s %-4s %4s %5s %32s %32s \n", + "index", "bssid", "ch", "RSSI", "SdBm", "Noise", "rsni", "age", "flag", ssid_title_str); while (1) { if (rtw_end_of_queue_search(phead, plist) == _TRUE) break; @@ -1600,7 +2276,7 @@ int proc_get_survey_info(struct seq_file *m, void *v) if (!pnetwork) break; - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE && is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) { notify_signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);/* dbm */ } else { @@ -1611,12 +2287,17 @@ int proc_get_survey_info(struct seq_file *m, void *v) if (IS_NM_ENABLE(padapter)) notify_noise = rtw_noise_query_by_chan_num(padapter, pnetwork->network.Configuration.DSConfig); #endif +#ifdef CONFIG_RTW_ACS + rsni = rtw_acs_get_rsni(padapter, (int)(pnetwork->network.Rssi), pnetwork->network.Configuration.DSConfig); +#endif ie_wpa = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &ielen, pnetwork->network.IELength - 12); ie_wpa2 = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &ielen, pnetwork->network.IELength - 12); ie_cap = rtw_get_capability(&pnetwork->network); ie_wps = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsielen); +#ifdef CONFIG_P2P ie_p2p = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &ielen); +#endif ssid = pnetwork->network.Ssid.Ssid; sprintf(flag_str, "%s%s%s%s%s%s%s", (ie_wpa) ? "[WPA]" : "", @@ -1627,13 +2308,14 @@ int proc_get_survey_info(struct seq_file *m, void *v) (pnetwork->network.InfrastructureMode == Ndis802_11_mesh) ? "[MESH]" : "", (ie_cap & BIT(0)) ? "[ESS]" : "", (ie_p2p) ? "[P2P]" : ""); - RTW_PRINT_SEL(m, "%5d "MAC_FMT" %3d %3d %4d %4d %5d %32s %32s\n", + RTW_PRINT_SEL(m, "%5d "MAC_FMT" %3d %4d %4d %4d %4d %5d %32s %32s\n", ++index, MAC_ARG(pnetwork->network.MacAddress), pnetwork->network.Configuration.DSConfig, (int)pnetwork->network.Rssi, notify_signal, notify_noise, + rsni, rtw_get_passing_time_ms(pnetwork->last_scanned), flag_str, pnetwork->network.InfrastructureMode == Ndis802_11_mesh ? pnetwork->network.mesh_id.Ssid : pnetwork->network.Ssid.Ssid @@ -1708,7 +2390,7 @@ ssize_t proc_set_survey_info(struct file *file, const char __user *buffer, size_ goto cancel_ps_deny; } - if (rtw_mi_busy_traffic_check(padapter, _FALSE)) { + if (rtw_mi_busy_traffic_check(padapter)) { RTW_INFO("scan abort!! BusyTraffic == _TRUE\n"); goto cancel_ps_deny; } @@ -1717,14 +2399,14 @@ ssize_t proc_set_survey_info(struct file *file, const char __user *buffer, size_ RTW_INFO("scan abort!! AP mode process WPS\n"); goto cancel_ps_deny; } - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING) == _TRUE) { RTW_INFO("scan abort!! fwstate=0x%x\n", pmlmepriv->fw_state); goto cancel_ps_deny; } #ifdef CONFIG_CONCURRENT_MODE if (rtw_mi_buddy_check_fwstate(padapter, - _FW_UNDER_SURVEY | _FW_UNDER_LINKING | WIFI_UNDER_WPS)) { + WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING | WIFI_UNDER_WPS)) { RTW_INFO("scan abort!! buddy_fwstate check failed\n"); goto cancel_ps_deny; } @@ -1928,9 +2610,14 @@ int proc_get_trx_info(struct seq_file *m, void *v) RTW_PRINT_SEL(m, "free_recvframe_cnt=%d\n" , precvpriv->free_recvframe_cnt); - for (i = 0; i < 4; i++) { + for (i = 0; i < pxmitpriv->hwxmit_entry; i++) { phwxmit = pxmitpriv->hwxmits + i; - RTW_PRINT_SEL(m, "%d, hwq.accnt=%d\n", i, phwxmit->accnt); +#ifdef CONFIG_RTW_MGMT_QUEUE + if (i == pxmitpriv->hwxmit_entry - 1) + RTW_PRINT_SEL(m, "%d, hw_mgmt_q.accnt=%d\n", i, phwxmit->accnt); + else +#endif + RTW_PRINT_SEL(m, "%d, hwq.accnt=%d\n", i, phwxmit->accnt); } rtw_hal_get_hwreg(padapter, HW_VAR_DUMP_MAC_TXFIFO, (u8 *)m); @@ -2756,7 +3443,7 @@ int proc_get_huawei_trx_info(struct seq_file *sel, void *v) u8 mac_id; #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA u8 isCCKrate, rf_path; - PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info; #endif @@ -2788,7 +3475,9 @@ int proc_get_huawei_trx_info(struct seq_file *sel, void *v) #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE; - for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) { + for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) { + if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path))) + continue; if (!isCCKrate) _RTW_PRINT_SEL(sel , "RF_PATH_%d : rx_ofdm_pwr:%d(dBm), rx_ofdm_snr:%d(dB)\n", rf_path, psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]); @@ -3135,6 +3824,66 @@ ssize_t proc_set_rx_ampdu(struct file *file, const char __user *buffer, size_t c return count; } +#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT +int proc_get_tx_aval_th(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + + if (padapter) { + + switch(dvobj->tx_aval_int_thr_mode) { + case 0: + RTW_PRINT_SEL(m, "tx_aval_int_thr_mode = %u (auto) \n", dvobj->tx_aval_int_thr_mode); + break; + case 1: + RTW_PRINT_SEL(m, "tx_aval_int_thr_mode = %u (fixed)\n", dvobj->tx_aval_int_thr_mode); + RTW_PRINT_SEL(m, "tx_aval_threshold = 0x%x\n", dvobj->tx_aval_int_thr_value); + break; + case 2: + RTW_PRINT_SEL(m, "tx_aval_int_thr_mode = %u(by sdio_tx_max_len)\n", dvobj->tx_aval_int_thr_mode); + break; + default: + break; + } + } + return 0; +} + +ssize_t proc_set_tx_aval_th(struct file *file, const char __user *buffer + , size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + char tmp[32]; + u32 mode; + u32 threshold; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%d %d ",&mode, &threshold); + + if(num >= 1) + dvobj->tx_aval_int_thr_mode = mode; + if(num >= 2) + dvobj->tx_aval_int_thr_value = threshold; + RTW_INFO("dvobj->tx_aval_int_thr_mode= 0x%x\n", mode); + RTW_INFO("dvobj->tx_aval_int_thr_value= 0x%x(range need 1~255)\n", threshold); + } + + return count; +} +#endif /*CONFIG_SDIO_TX_ENABLE_AVAL_INT*/ int proc_get_rx_ampdu_factor(struct seq_file *m, void *v) { @@ -3311,6 +4060,46 @@ ssize_t proc_set_tx_ampdu_density(struct file *file, const char __user *buffer, return count; } +int proc_get_tx_quick_addba_req(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + + if (padapter) + RTW_PRINT_SEL(m, "tx_quick_addba_req = %x\n", pregpriv->tx_quick_addba_req); + + return 0; +} + +ssize_t proc_set_tx_quick_addba_req(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + char tmp[32]; + u32 enable; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%d ", &enable); + + if (padapter && (num == 1)) { + pregpriv->tx_quick_addba_req = enable; + RTW_INFO("tx_quick_addba_req = %d\n", pregpriv->tx_quick_addba_req); + } + } + + return count; +} #ifdef CONFIG_TX_AMSDU int proc_get_tx_amsdu(struct seq_file *m, void *v) { @@ -3411,6 +4200,95 @@ ssize_t proc_set_tx_amsdu_rate(struct file *file, const char __user *buffer, siz #endif /* CONFIG_TX_AMSDU */ #endif /* CONFIG_80211N_HT */ +#ifdef CONFIG_80211AC_VHT +int proc_get_vht_24g_enable(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + + if (pregpriv) + RTW_PRINT_SEL(m, "%d\n", pregpriv->vht_24g_enable); + + return 0; +} + +ssize_t proc_set_vht_24g_enable(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + char tmp[32]; + u32 mode; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%d ", &mode); + + if ((num == 1) && pregpriv && (mode < 2)) { + pregpriv->vht_24g_enable = mode; + RTW_INFO("vht_24g_enable = %d\n", pregpriv->vht_24g_enable); + } + } + + return count; + +} +#endif + +ssize_t proc_set_dyn_rrsr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + + char tmp[32] = {0}; + u32 num = 0, enable = 0, rrsr_val = 0; /* gpio_mode:0 input 1:output; */ + + if (count < 2) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + num = sscanf(tmp, "%d 0x%x", &enable, &rrsr_val); + RTW_INFO("num=%u enable=%d rrsr_val=0x%x\n", num, enable, rrsr_val); + pregpriv->en_dyn_rrsr = enable; + pregpriv->set_rrsr_value = rrsr_val; + rtw_phydm_dyn_rrsr_en(padapter, enable); + rtw_phydm_set_rrsr(padapter, rrsr_val, TRUE); + + } + return count; + +} +int proc_get_dyn_rrsr(struct seq_file *m, void *v) { + + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + u32 init_rrsr =0xFFFFFFFF; + + if (padapter) + RTW_PRINT_SEL(m, "en_dyn_rrsr = %d fixed_rrsr_value =0x%x %s\n" + , pregpriv->en_dyn_rrsr + , pregpriv->set_rrsr_value + , (pregpriv->set_rrsr_value == init_rrsr)?"(default)":"(fixed)" + ); + + return 0; +} int proc_get_en_fwps(struct seq_file *m, void *v) { struct net_device *dev = m->private; @@ -3824,7 +4702,8 @@ int proc_get_all_sta_info(struct seq_file *m, void *v) RTW_PRINT_SEL(m,"Vendor Realtek 8812\n"); #endif/*CONFIG_RTS_FULL_BW*/ #ifdef CONFIG_80211N_HT - RTW_PRINT_SEL(m, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); + RTW_PRINT_SEL(m, "qos_en=%d, ht_en=%d, init_rate=%d, ht_bitrate=%u\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate + , rtw_desc_rate_to_bitrate(psta->cmn.bw_mode, psta->init_rate, psta->cmn.bw_mode ? psta->htpriv.sgi_40m : psta->htpriv.sgi_20m) / 10); RTW_PRINT_SEL(m, "bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n" , psta->cmn.bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m); RTW_PRINT_SEL(m, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable); @@ -3832,7 +4711,8 @@ int proc_get_all_sta_info(struct seq_file *m, void *v) RTW_PRINT_SEL(m, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); #endif /* CONFIG_80211N_HT */ #ifdef CONFIG_80211AC_VHT - RTW_PRINT_SEL(m, "vht_en=%d, vht_sgi_80m=%d\n", psta->vhtpriv.vht_option, psta->vhtpriv.sgi_80m); + RTW_PRINT_SEL(m, "vht_en=%d, vht_sgi_80m=%d, vht_bitrate=%u\n", psta->vhtpriv.vht_option, psta->vhtpriv.sgi_80m + , psta->vhtpriv.vht_option ? rtw_vht_mcs_to_data_rate(CHANNEL_WIDTH_80, psta->vhtpriv.sgi_80m, psta->vhtpriv.vht_highest_rate) / 2 : 0); RTW_PRINT_SEL(m, "vht_ldpc_cap=0x%x, vht_stbc_cap=0x%x, vht_beamform_cap=0x%x\n", psta->vhtpriv.ldpc_cap, psta->vhtpriv.stbc_cap, psta->vhtpriv.beamform_cap); RTW_PRINT_SEL(m, "vht_mcs_map=0x%x, vht_highest_rate=0x%x, vht_ampdu_len=%d\n", *(u16 *)psta->vhtpriv.vht_mcs_map, psta->vhtpriv.vht_highest_rate, psta->vhtpriv.ampdu_len); #endif @@ -3842,6 +4722,11 @@ int proc_get_all_sta_info(struct seq_file *m, void *v) RTW_PRINT_SEL(m, "sta_xmitpriv.be_q_qcnt=%d\n", psta->sta_xmitpriv.be_q.qcnt); RTW_PRINT_SEL(m, "sta_xmitpriv.bk_q_qcnt=%d\n", psta->sta_xmitpriv.bk_q.qcnt); +#ifdef CONFIG_RTW_MGMT_QUEUE + RTW_PRINT_SEL(m, "management sleepq_len=%d\n", psta->mgmt_sleepq_len); + RTW_PRINT_SEL(m, "sta_xmitpriv.mgmt_q_qcnt=%d\n", psta->sta_xmitpriv.mgmt_q.qcnt); +#endif + RTW_PRINT_SEL(m, "capability=0x%x\n", psta->capability); RTW_PRINT_SEL(m, "flags=0x%x\n", psta->flags); RTW_PRINT_SEL(m, "wpa_psk=0x%x\n", psta->wpa_psk); @@ -3881,6 +4766,9 @@ int proc_get_all_sta_info(struct seq_file *m, void *v) if (STA_OP_WFD_MODE(psta)) RTW_PRINT_SEL(m, "op_wfd_mode:0x%02x\n", STA_OP_WFD_MODE(psta)); + RTW_PRINT_SEL(m, "tx_bitrate_100kbps=%u\n", rtw_desc_rate_to_bitrate(psta->cmn.bw_mode, rtw_get_current_tx_rate(padapter, psta), rtw_get_current_tx_sgi(padapter, psta))); + RTW_PRINT_SEL(m, "rx_bitrate_100kbps=%u\n", rtw_desc_rate_to_bitrate(psta->cmn.bw_mode, psta->curr_rx_rate & 0x7f, (psta->curr_rx_rate & 0x80) >> 7)); + RTW_PRINT_SEL(m, "rssi=%d\n", psta->cmn.rssi_stat.rssi); RTW_PRINT_SEL(m, "==============================\n"); } @@ -4677,6 +5565,59 @@ ssize_t proc_set_tx_ring_ext(struct file *file, const char __user *buffer, size_ #endif #ifdef CONFIG_WOWLAN +int proc_get_wow_enable(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *registry_pair = &padapter->registrypriv; + + RTW_PRINT_SEL(m, "wow - %s\n", (registry_pair->wowlan_enable)? "enable" : "disable"); + return 0; +} + +ssize_t proc_set_wow_enable(struct file *file, const char __user *buffer, + size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *registry_pair = &padapter->registrypriv; + char tmp[8]; + int num = 0; + int mode = 0; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) + num = sscanf(tmp, "%d", &mode); + else + return -EFAULT; + + if (num != 1) { + RTW_ERR("%s: %s - invalid parameter!\n", __func__, tmp); + return -EINVAL; + } + + if (mode == 1) { + RTW_PRINT("%s: wowlan - enable\n", __func__); + } else if (mode == 0) { + RTW_PRINT("%s: wowlan - disable\n", __func__); + } else { + RTW_ERR("%s: %s - invalid parameter!, mode=%d\n", + __func__, tmp, mode); + return -EINVAL; + } + + registry_pair->wowlan_enable = mode; + + return count; +} + int proc_get_pattern_info(struct seq_file *m, void *v) { struct net_device *dev = m->private; @@ -4823,7 +5764,7 @@ ssize_t proc_set_wakeup_event(struct file *file, const char __user *buffer, else return -EFAULT; - if (num == 1 && wakeup_event <= 0x07) { + if (num == 1 && wakeup_event <= 0x0f) { registry_par->wakeup_event = wakeup_event; if (wakeup_event & BIT(1)) @@ -4853,6 +5794,30 @@ int proc_get_wakeup_reason(struct seq_file *m, void *v) RTW_PRINT_SEL(m, "last wake reason: %#02x\n", val); return 0; } +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +int proc_dump_wow_keep_alive_info(struct seq_file *m, void *v) { + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + int i; + + RTW_PRINT_SEL(m, "wowlan_keep_alive_mode: %d\n", pwrpriv->wowlan_keep_alive_mode); + RTW_PRINT_SEL(m,"LocKeepAlive: %d\n", pwrpriv->keep_alive_pattern_loc ); + RTW_PRINT_SEL(m, "keep_alive_pattern_len: %d\n", pwrpriv->keep_alive_pattern_len); + RTW_PRINT_SEL(m,"keep_alive_pattern= \n" ); + for (i=0 ; i < pwrpriv->keep_alive_pattern_len ; i++) { + RTW_PRINT_SEL(m,"[0x%x] ",pwrpriv->keep_alive_pattern[i]); + if(i%8 == 7) + RTW_PRINT_SEL(m,"\n"); + } + RTW_PRINT_SEL(m,"\n"); + RTW_PRINT_SEL(m," wowlan_keep_alive_period= %d ms\n", pwrpriv->wowlan_keep_alive_period*100); + RTW_PRINT_SEL(m," wowlan_keep_alive_retry_counter= %d\n", pwrpriv->wowlan_keep_alive_retry_counter); + RTW_PRINT_SEL(m," wowlan_keep_alive_retry_interval= %d ms\n", pwrpriv->wowlan_keep_alive_retry_interval*100); + return 0; +} +#endif /* CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + #endif /*CONFIG_WOWLAN*/ #ifdef CONFIG_GPIO_WAKEUP @@ -4861,9 +5826,14 @@ int proc_get_wowlan_gpio_info(struct seq_file *m, void *v) struct net_device *dev = m->private; _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + u8 gpio_index = pwrpriv->wowlan_gpio_index; + u8 gpio_output_state = pwrpriv->wowlan_gpio_output_state; u8 val = pwrpriv->is_high_active; - RTW_PRINT_SEL(m, "wakeup_gpio_idx: %d\n", WAKEUP_GPIO_IDX); + RTW_PRINT_SEL(m, "wakeup_gpio_idx: %d\n", gpio_index); +#if (!defined(CONFIG_WAKEUP_GPIO_INPUT_MODE) && !defined(CONFIG_RTW_ONE_PIN_GPIO)) + RTW_PRINT_SEL(m, "current_gpio_output_state: %d\n", gpio_output_state); +#endif RTW_PRINT_SEL(m, "high_active: %d\n", val); return 0; @@ -4904,22 +5874,22 @@ ssize_t proc_set_wowlan_gpio_info(struct file *file, const char __user *buffer, rtw_ps_deny(padapter, PS_DENY_IOCTL); LeaveAllPowerSaveModeDirect(padapter); - #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE +#ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE if (pwrpriv->is_high_active == 0) - rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX); + rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index); else - rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, 0); - #else + rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, + GPIO_OUTPUT_LOW); +#else val8 = (pwrpriv->is_high_active == 0) ? 1 : 0; - rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE); - rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8); - #endif + rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE); + rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, val8); +#endif rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL); - RTW_INFO("set %s %d\n", "gpio_high_active", - pwrpriv->is_high_active); - RTW_INFO("%s: set GPIO_%d %d as default.\n", - __func__, WAKEUP_GPIO_IDX, val8); + RTW_INFO("%s set GPIO_%d to %s_ACTIVE\n", __func__, + pwrpriv->wowlan_gpio_index, + pwrpriv->is_high_active ? "HIGH" : "LOW"); } return count; @@ -5375,7 +6345,7 @@ static int proc_tdls_display_network_info(struct seq_file *m) /* Display the linked AP/GO info */ RTW_PRINT_SEL(m, "============[Associated AP/GO Info]============\n"); - if ((pmlmepriv->fw_state & WIFI_STATION_STATE) && (pmlmepriv->fw_state & _FW_LINKED)) { + if ((pmlmepriv->fw_state & WIFI_STATION_STATE) && (pmlmepriv->fw_state & WIFI_ASOC_STATE)) { RTW_PRINT_SEL(m, "%-*s = %s\n", SpaceBtwnItemAndValue, "BSSID", cur_network->network.Ssid.Ssid); RTW_PRINT_SEL(m, "%-*s = "MAC_FMT"\n", SpaceBtwnItemAndValue, "Mac Address", MAC_ARG(cur_network->network.MacAddress)); @@ -5429,14 +6399,16 @@ static int proc_tdls_display_network_info(struct seq_file *m) case _WEP104_: RTW_PRINT_SEL(m, "%s\n", "WEP 104"); break; +#if 0 /* no this setting */ case _WEP_WPA_MIXED_: RTW_PRINT_SEL(m, "%s\n", "WEP/WPA Mixed"); break; +#endif case _SMS4_: RTW_PRINT_SEL(m, "%s\n", "SMS4"); break; #ifdef CONFIG_IEEE80211W - case _BIP_: + case _BIP_CMAC_128_: RTW_PRINT_SEL(m, "%s\n", "BIP"); break; #endif /* CONFIG_IEEE80211W */ @@ -5630,14 +6602,16 @@ static int proc_tdls_display_tdls_sta_info(struct seq_file *m) case _WEP104_: RTW_PRINT_SEL(m, "%s\n", "WEP 104"); break; +#if 0 /* no this setting */ case _WEP_WPA_MIXED_: RTW_PRINT_SEL(m, "%s\n", "WEP/WPA Mixed"); break; +#endif case _SMS4_: RTW_PRINT_SEL(m, "%s\n", "SMS4"); break; #ifdef CONFIG_IEEE80211W - case _BIP_: + case _BIP_CMAC_128_: RTW_PRINT_SEL(m, "%s\n", "BIP"); break; #endif /* CONFIG_IEEE80211W */ @@ -5695,11 +6669,14 @@ int proc_get_monitor(struct seq_file *m, void *v) _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - if (WIFI_MONITOR_STATE == get_fwstate(pmlmepriv)) { + if (MLME_IS_MONITOR(padapter)) { RTW_PRINT_SEL(m, "Monitor mode : Enable\n"); + RTW_PRINT_SEL(m, "Device type : %u\n", dev->type); RTW_PRINT_SEL(m, "ch=%d, ch_offset=%d, bw=%d\n", - rtw_get_oper_ch(padapter), rtw_get_oper_choffset(padapter), rtw_get_oper_bw(padapter)); + rtw_get_oper_ch(padapter), + rtw_get_oper_choffset(padapter), + rtw_get_oper_bw(padapter)); } else RTW_PRINT_SEL(m, "Monitor mode : Disable\n"); @@ -5711,7 +6688,8 @@ ssize_t proc_set_monitor(struct file *file, const char __user *buffer, size_t co char tmp[32]; struct net_device *dev = data; _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); - u8 target_chan, target_offset, target_bw; + u16 target_type; + u8 target_ch, target_offset, target_bw; if (count < 3) { RTW_INFO("argument size is less than 3\n"); @@ -5724,19 +6702,68 @@ ssize_t proc_set_monitor(struct file *file, const char __user *buffer, size_t co } if (buffer && !copy_from_user(tmp, buffer, count)) { - int num = sscanf(tmp, "%hhu %hhu %hhu", &target_chan, &target_offset, &target_bw); + int num = 0; + num = sscanf(tmp, "type %hu", &target_type); + if ((num == 1) && + ((target_type != ARPHRD_IEEE80211) && + (target_type != ARPHRD_IEEE80211_RADIOTAP))) { + dev->type = ARPHRD_IEEE80211_RADIOTAP; + return count; + } + + num = sscanf(tmp, "%hhu %hhu %hhu", &target_ch, &target_offset, &target_bw); if (num != 3) { RTW_INFO("invalid write_reg parameter!\n"); return count; } - padapter->mlmeextpriv.cur_channel = target_chan; - set_channel_bwmode(padapter, target_chan, target_offset, target_bw); + padapter->mlmeextpriv.cur_channel = target_ch; + set_channel_bwmode(padapter, target_ch, target_offset, target_bw); } return count; } + +#ifdef RTW_SIMPLE_CONFIG +/* For RtwSimleConfig */ +int proc_get_simple_config(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + RTW_PRINT_SEL(m, "RTW Simple Config : %s\n", padapter->rtw_simple_config ? "Enable" : "Disable"); + + return 0; +} + +ssize_t proc_set_simple_config(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + char tmp[32]; + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 ret; + + if (count < 1) { + RTW_INFO("argument size is less than 1\n"); + return -EFAULT; + } + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%hhd", &ret); + + padapter->rtw_simple_config = ret ? _TRUE : _FALSE; + } + + return count; +} +#endif + #ifdef DBG_XMIT_BLOCK int proc_get_xmit_block(struct seq_file *m, void *v) { @@ -5802,7 +6829,7 @@ int proc_get_efuse_map(struct seq_file *m, void *v) ips_mode = pwrctrlpriv->ips_mode; rtw_pm_set_ips(padapter, IPS_NONE); - +#ifdef CONFIG_EFUSE_CONFIG_FILE if (pHalData->efuse_file_status == EFUSE_FILE_LOADED) { RTW_PRINT_SEL(m, "File eFuse Map loaded! file path:%s\nDriver eFuse Map From File\n", EFUSE_MAP_PATH); if (pHalData->bautoload_fail_flag) @@ -5811,7 +6838,10 @@ int proc_get_efuse_map(struct seq_file *m, void *v) RTW_PRINT_SEL(m, "Open File eFuse Map Fail ! file path:%s\nDriver eFuse Map From Default\n", EFUSE_MAP_PATH); if (pHalData->bautoload_fail_flag) RTW_PRINT_SEL(m, "HW Autoload fail!!!\n"); - } else { + } else +#endif + + { RTW_PRINT_SEL(m, "Driver eFuse Map From HW\n"); if (pHalData->bautoload_fail_flag) RTW_PRINT_SEL(m, "HW Autoload fail!!!\n"); @@ -5926,7 +6956,7 @@ ssize_t proc_set_tx_sa_query(struct file *file, const char __user *buffer, size_ } if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) - && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) && SEC_IS_BIP_KEY_INSTALLED(&padapter->securitypriv) == _TRUE) { + && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) && SEC_IS_BIP_KEY_INSTALLED(&padapter->securitypriv) == _TRUE) { RTW_INFO("STA:"MAC_FMT"\n", MAC_ARG(get_my_bssid(&(pmlmeinfo->network)))); /* TX unicast sa_query to AP */ issue_action_SA_Query(padapter, get_my_bssid(&(pmlmeinfo->network)), 0, 0, (u8)key_type); @@ -5986,7 +7016,7 @@ ssize_t proc_set_tx_deauth(struct file *file, const char __user *buffer, size_t char tmp[16]; u8 mac_addr[NUM_STA][ETH_ALEN]; u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - u32 key_type = -1; + u32 key_type; u8 index; @@ -6009,11 +7039,12 @@ ssize_t proc_set_tx_deauth(struct file *file, const char __user *buffer, size_t return count; if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) - && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) { + && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) { if (key_type == 3) /* key_type 3 only for AP mode */ return count; /* TX unicast deauth to AP */ issue_deauth_11w(padapter, get_my_bssid(&(pmlmeinfo->network)), 0, (u8)key_type); +#ifdef CONFIG_AP_MODE } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) { u8 updated = _FALSE; @@ -6048,6 +7079,10 @@ ssize_t proc_set_tx_deauth(struct file *file, const char __user *buffer, size_t if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) { rtw_list_delete(&psta->asoc_list); pstapriv->asoc_list_cnt--; + #ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (psta->tbtx_enable) + pstapriv->tbtx_asoc_list_cnt--; + #endif updated |= ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_PREV_AUTH_NOT_VALID, _TRUE); } @@ -6060,6 +7095,7 @@ ssize_t proc_set_tx_deauth(struct file *file, const char __user *buffer, size_t } associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL); +#endif /* CONFIG_AP_MODE */ } return count; @@ -6111,7 +7147,7 @@ ssize_t proc_set_tx_auth(struct file *file, const char __user *buffer, size_t co } if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) - && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) { + && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) { if (tx_auth == 1) { /* TX unicast auth to AP */ issue_auth(padapter, NULL, 0); diff --git a/core/rtw_ft.c b/core/rtw_ft.c new file mode 100644 index 0000000..1ba55ce --- /dev/null +++ b/core/rtw_ft.c @@ -0,0 +1,668 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#include +#include + +#ifdef CONFIG_RTW_80211R + +#ifndef RTW_FT_DBG + #define RTW_FT_DBG 0 +#endif +#if RTW_FT_DBG + #define RTW_FT_INFO(fmt, arg...) \ + RTW_INFO(fmt, arg) + #define RTW_FT_DUMP(str, data, len) \ + RTW_INFO_DUMP(str, data, len) +#else + #define RTW_FT_INFO(fmt, arg...) do {} while (0) + #define RTW_FT_DUMP(str, data, len) do {} while (0) +#endif + +void rtw_ft_info_init(struct ft_roam_info *pft) +{ + _rtw_memset(pft, 0, sizeof(struct ft_roam_info)); + pft->ft_flags = 0 + | RTW_FT_EN + /* | RTW_FT_OTD_EN */ +#ifdef CONFIG_RTW_BTM_ROAM + | RTW_FT_BTM_ROAM +#endif + ; + pft->ft_updated_bcn = _FALSE; + RTW_FT_INFO("%s : ft_flags=0x%02x\n", __func__, pft->ft_flags); +} + +ssize_t rtw_ft_proc_flags_set(struct file *file, + const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + char tmp[32]; + u8 flags; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%hhx", &flags); + if (num == 1) + adapter->mlmepriv.ft_roam.ft_flags = flags; + } + + return count; + +} + +int rtw_ft_proc_flags_get(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + RTW_PRINT_SEL(m, "0x%02x\n", adapter->mlmepriv.ft_roam.ft_flags); + + return 0; +} + +u8 rtw_ft_chk_roaming_candidate( + _adapter *padapter, struct wlan_network *competitor) +{ + u8 *pmdie; + u32 mdie_len = 0; + struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); + + if (!(pmdie = rtw_get_ie(&competitor->network.IEs[12], + _MDIE_, &mdie_len, competitor->network.IELength-12))) { + RTW_INFO("FT : MDIE not foud in competitor!\n"); + return _FALSE; + } + + if (!_rtw_memcmp(&pft_roam->mdid, (pmdie+2), 2)) { + RTW_INFO("FT : unmatched MDIE!\n"); + return _FALSE; + } + + /*The candidate don't support over-the-DS*/ + if (rtw_ft_valid_otd_candidate(padapter, pmdie)) { + RTW_INFO("FT: ignore the candidate(" + MAC_FMT ") for over-the-DS\n", + MAC_ARG(competitor->network.MacAddress)); + /* rtw_ft_clr_flags(padapter, RTW_FT_PEER_OTD_EN); */ + return _FALSE; + } + + if (rtw_ft_chk_flags(padapter, RTW_FT_TEST_RSSI_ROAM)) { + if (!_rtw_memcmp(padapter->mlmepriv.cur_network.network.MacAddress, + competitor->network.MacAddress, ETH_ALEN) ) { + competitor->network.Rssi +=20; + RTW_FT_INFO("%s : update "MAC_FMT" RSSI to %d for RTW_FT_TEST_RSSI_ROAM\n", + __func__, MAC_ARG(competitor->network.MacAddress), + (int)competitor->network.Rssi); + rtw_ft_clr_flags(padapter, RTW_FT_TEST_RSSI_ROAM); + } + } + + return _TRUE; +} + +void rtw_ft_update_stainfo(_adapter *padapter, WLAN_BSSID_EX *pnetwork) +{ + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta = NULL; + + psta = rtw_get_stainfo(pstapriv, pnetwork->MacAddress); + if (psta == NULL) + psta = rtw_alloc_stainfo(pstapriv, pnetwork->MacAddress); + + if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { + + padapter->securitypriv.binstallGrpkey = _FALSE; + padapter->securitypriv.busetkipkey = _FALSE; + padapter->securitypriv.bgrpkey_handshake = _FALSE; + + psta->ieee8021x_blocked = _TRUE; + psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; + + _rtw_memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype)); + _rtw_memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype)); + _rtw_memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype)); + } + +} + +void rtw_ft_reassoc_event_callback(_adapter *padapter, u8 *pbuf) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf; + struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&(pmlmeinfo->network); + struct cfg80211_ft_event_params ft_evt_parms; + _irqL irqL; + + _rtw_memset(&ft_evt_parms, 0, sizeof(ft_evt_parms)); + rtw_ft_update_stainfo(padapter, pnetwork); + ft_evt_parms.ies_len = pft_roam->ft_event.ies_len; + ft_evt_parms.ies = rtw_zmalloc(ft_evt_parms.ies_len); + if (ft_evt_parms.ies) + _rtw_memcpy((void *)ft_evt_parms.ies, pft_roam->ft_event.ies, ft_evt_parms.ies_len); + else + goto err_2; + + ft_evt_parms.target_ap = rtw_zmalloc(ETH_ALEN); + if (ft_evt_parms.target_ap) + _rtw_memcpy((void *)ft_evt_parms.target_ap, pstassoc->macaddr, ETH_ALEN); + else + goto err_1; + + ft_evt_parms.ric_ies = pft_roam->ft_event.ric_ies; + ft_evt_parms.ric_ies_len = pft_roam->ft_event.ric_ies_len; + + /* It's a KERNEL issue between v4.11 ~ v4.16, + * <= v4.10, NLMSG_DEFAULT_SIZE is used for nlmsg_new(). + * v4.11 ~ v4.16, only used "100 + >ric_ies_len" for nlmsg_new() + * even then DRIVER don't support RIC. + * >= v4.17, issue should correct as "100 + ies_len + ric_ies_len". + */ + #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0))) + if (!ft_evt_parms.ric_ies_len) + ft_evt_parms.ric_ies_len = ft_evt_parms.ies_len; + else + ft_evt_parms.ric_ies_len += ft_evt_parms.ies_len; + #endif + + rtw_ft_lock_set_status(padapter, RTW_FT_AUTHENTICATED_STA, &irqL); + rtw_cfg80211_ft_event(padapter, &ft_evt_parms); + RTW_INFO("%s: to "MAC_FMT"\n", __func__, MAC_ARG(ft_evt_parms.target_ap)); + + rtw_mfree((u8 *)pft_roam->ft_event.target_ap, ETH_ALEN); +err_1: + rtw_mfree((u8 *)ft_evt_parms.ies, ft_evt_parms.ies_len); +err_2: + return; +} + +void rtw_ft_validate_akm_type(_adapter *padapter, + struct wlan_network *pnetwork) +{ + struct security_priv *psecuritypriv = &(padapter->securitypriv); + struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); + u32 tmp_len; + u8 *ptmp; + + /*IEEE802.11-2012 Std. Table 8-101-AKM suite selectors*/ + if (rtw_ft_valid_akm(padapter, psecuritypriv->rsn_akm_suite_type)) { + ptmp = rtw_get_ie(&pnetwork->network.IEs[12], + _MDIE_, &tmp_len, (pnetwork->network.IELength-12)); + if (ptmp) { + pft_roam->mdid = *(u16 *)(ptmp+2); + pft_roam->ft_cap = *(ptmp+4); + + RTW_INFO("FT: target " MAC_FMT " mdid=(0x%2x), capacity=(0x%2x)\n", + MAC_ARG(pnetwork->network.MacAddress), pft_roam->mdid, pft_roam->ft_cap); + rtw_ft_set_flags(padapter, RTW_FT_PEER_EN); + RTW_FT_INFO("%s : peer support FTOTA(0x%02x)\n", __func__, pft_roam->ft_flags); + + if (rtw_ft_otd_roam_en(padapter)) { + rtw_ft_set_flags(padapter, RTW_FT_PEER_OTD_EN); + RTW_FT_INFO("%s : peer support FTOTD(0x%02x)\n", __func__, pft_roam->ft_flags); + } + } else { + /* Don't use FT roaming if target AP cannot support FT */ + rtw_ft_clr_flags(padapter, (RTW_FT_PEER_EN|RTW_FT_PEER_OTD_EN)); + rtw_ft_reset_status(padapter); + } + } else { + /* It could be a non-FT connection */ + rtw_ft_clr_flags(padapter, (RTW_FT_PEER_EN|RTW_FT_PEER_OTD_EN)); + rtw_ft_reset_status(padapter); + } + + RTW_FT_INFO("%s : ft_flags=0x%02x\n", __func__, pft_roam->ft_flags); +} + +void rtw_ft_update_bcn(_adapter *padapter, union recv_frame *precv_frame) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint len = precv_frame->u.hdr.len; + WLAN_BSSID_EX *pbss; + + if (rtw_ft_chk_status(padapter,RTW_FT_ASSOCIATED_STA) + && (pmlmepriv->ft_roam.ft_updated_bcn == _FALSE)) { + pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX)); + if (pbss) { + if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) { + struct beacon_keys recv_beacon; + + update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE); + /* Move into rtw_get_bcn_keys */ + /* rtw_get_bcn_info(&(pmlmepriv->cur_network)); */ + + /* update bcn keys */ + if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) { + RTW_FT_INFO("%s: beacon keys ready\n", __func__); + _rtw_memcpy(&pmlmepriv->cur_beacon_keys, + &recv_beacon, sizeof(recv_beacon)); + if (is_hidden_ssid(recv_beacon.ssid, recv_beacon.ssid_len)) { + _rtw_memcpy(pmlmepriv->cur_beacon_keys.ssid, pmlmeinfo->network.Ssid.Ssid, IW_ESSID_MAX_SIZE); + pmlmepriv->cur_beacon_keys.ssid_len = pmlmeinfo->network.Ssid.SsidLength; + } + } else { + RTW_ERR("%s: get beacon keys failed\n", __func__); + _rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon)); + } + #ifdef CONFIG_BCN_CNT_CONFIRM_HDL + pmlmepriv->new_beacon_cnts = 0; + #endif + } + rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX)); + } + + /* check the vendor of the assoc AP */ + pmlmeinfo->assoc_AP_vendor = + check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), + (len - sizeof(struct rtw_ieee80211_hdr_3addr))); + + /* update TSF Value */ + update_TSF(pmlmeext, pframe, len); + pmlmeext->bcn_cnt = 0; + pmlmeext->last_bcn_cnt = 0; + pmlmepriv->ft_roam.ft_updated_bcn = _TRUE; + } +} + +void rtw_ft_start_clnt_join(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); + + if (rtw_ft_otd_roam(padapter)) { + pmlmeinfo->state = WIFI_FW_AUTH_SUCCESS | WIFI_FW_STATION_STATE; + pft_roam->ft_event.ies = + (pft_roam->ft_action + sizeof(struct rtw_ieee80211_hdr_3addr) + 16); + pft_roam->ft_event.ies_len = + (pft_roam->ft_action_len - sizeof(struct rtw_ieee80211_hdr_3addr)); + + /*Not support RIC*/ + pft_roam->ft_event.ric_ies = NULL; + pft_roam->ft_event.ric_ies_len = 0; + rtw_ft_report_evt(padapter); + return; + } + + pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE; + start_clnt_auth(padapter); +} + +u8 rtw_ft_update_rsnie( + _adapter *padapter, u8 bwrite, + struct pkt_attrib *pattrib, u8 **pframe) +{ + struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); + u8 *pie; + u32 len; + + pie = rtw_get_ie(pft_roam->updated_ft_ies, EID_WPA2, &len, + pft_roam->updated_ft_ies_len); + + if (!bwrite) + return (pie)?_SUCCESS:_FAIL; + + if (pie) { + *pframe = rtw_set_ie(((u8 *)*pframe), EID_WPA2, len, + pie+2, &(pattrib->pktlen)); + } else + return _FAIL; + + return _SUCCESS; +} + +static u8 rtw_ft_update_mdie( + _adapter *padapter, struct pkt_attrib *pattrib, u8 **pframe) +{ + struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); + u8 *pie, mdie[3]; + u32 len = 3; + + if (rtw_ft_roam(padapter)) { + if ((pie = rtw_get_ie(pft_roam->updated_ft_ies, _MDIE_, + &len, pft_roam->updated_ft_ies_len))) { + pie = (pie + 2); /* ignore md-id & length */ + } else + return _FAIL; + } else { + *((u16 *)&mdie[0]) = pft_roam->mdid; + mdie[2] = pft_roam->ft_cap; + pie = &mdie[0]; + } + + *pframe = rtw_set_ie(((u8 *)*pframe), _MDIE_, len , pie, &(pattrib->pktlen)); + return _SUCCESS; +} + +static u8 rtw_ft_update_ftie( + _adapter *padapter, struct pkt_attrib *pattrib, u8 **pframe) +{ + struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); + u8 *pie; + u32 len; + + if ((pie = rtw_get_ie(pft_roam->updated_ft_ies, _FTIE_, &len, + pft_roam->updated_ft_ies_len)) != NULL) { + *pframe = rtw_set_ie(*pframe, _FTIE_, len , + (pie+2), &(pattrib->pktlen)); + } else + return _FAIL; + + return _SUCCESS; +} + +void rtw_ft_build_auth_req_ies(_adapter *padapter, + struct pkt_attrib *pattrib, u8 **pframe) +{ + u8 ftie_append = _TRUE; + + if (!pattrib || !(*pframe)) + return; + + if (!rtw_ft_roam(padapter)) + return; + + ftie_append = rtw_ft_update_rsnie(padapter, _TRUE, pattrib, pframe); + rtw_ft_update_mdie(padapter, pattrib, pframe); + if (ftie_append) + rtw_ft_update_ftie(padapter, pattrib, pframe); +} + +void rtw_ft_build_assoc_req_ies(_adapter *padapter, + u8 is_reassoc, struct pkt_attrib *pattrib, u8 **pframe) +{ + if (!pattrib || !(*pframe)) + return; + + if (rtw_ft_chk_flags(padapter, RTW_FT_PEER_EN)) + rtw_ft_update_mdie(padapter, pattrib, pframe); + + if ((!is_reassoc) || (!rtw_ft_roam(padapter))) + return; + + if (rtw_ft_update_rsnie(padapter, _FALSE, pattrib, pframe)) + rtw_ft_update_ftie(padapter, pattrib, pframe); +} + +u8 rtw_ft_update_auth_rsp_ies(_adapter *padapter, u8 *pframe, u32 len) +{ + u8 ret = _SUCCESS; + u8 target_ap_addr[ETH_ALEN] = {0}; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); + + if (!rtw_ft_roam(padapter)) + return _FAIL; + + /*rtw_ft_report_reassoc_evt already, + * and waiting for cfg80211_rtw_update_ft_ies */ + if (rtw_ft_authed_sta(padapter)) + return ret; + + if (!pframe || !len) + return _FAIL; + + rtw_buf_update(&pmlmepriv->auth_rsp, + &pmlmepriv->auth_rsp_len, pframe, len); + pft_roam->ft_event.ies = + (pmlmepriv->auth_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6); + pft_roam->ft_event.ies_len = + (pmlmepriv->auth_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6); + + /*Not support RIC*/ + pft_roam->ft_event.ric_ies = NULL; + pft_roam->ft_event.ric_ies_len = 0; + _rtw_memcpy(target_ap_addr, pmlmepriv->assoc_bssid, ETH_ALEN); + rtw_ft_report_reassoc_evt(padapter, target_ap_addr); + + return ret; +} + +static void rtw_ft_start_clnt_action(_adapter *padapter, u8 *pTargetAddr) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + rtw_ft_set_status(padapter, RTW_FT_REQUESTING_STA); + rtw_ft_issue_action_req(padapter, pTargetAddr); + _set_timer(&pmlmeext->ft_link_timer, REASSOC_TO); +} + +void rtw_ft_start_roam(_adapter *padapter, u8 *pTargetAddr) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + if (rtw_ft_otd_roam(padapter)) { + RTW_FT_INFO("%s : try OTD roaming\n", __func__); + rtw_ft_start_clnt_action(padapter, pTargetAddr); + } else { + /*wait a little time to retrieve packets buffered in the current ap while scan*/ + RTW_FT_INFO("%s : start roaming timer\n", __func__); + _set_timer(&pmlmeext->ft_roam_timer, 30); + } +} + +void rtw_ft_issue_action_req(_adapter *padapter, u8 *pTargetAddr) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct xmit_frame *pmgntframe; + struct rtw_ieee80211_hdr *pwlanhdr; + struct pkt_attrib *pattrib; + u8 *pframe; + u8 category = RTW_WLAN_CATEGORY_FT; + u8 action = RTW_WLAN_ACTION_FT_REQ; + + pmgntframe = alloc_mgtxmitframe(pxmitpriv); + if (pmgntframe == NULL) + return; + + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); + + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + pwlanhdr->frame_ctl = 0; + + _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + set_frame_sub_type(pframe, WIFI_ACTION); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); + + _rtw_memcpy(pframe, adapter_mac_addr(padapter), ETH_ALEN); + pframe += ETH_ALEN; + pattrib->pktlen += ETH_ALEN; + + _rtw_memcpy(pframe, pTargetAddr, ETH_ALEN); + pframe += ETH_ALEN; + pattrib->pktlen += ETH_ALEN; + + rtw_ft_update_mdie(padapter, pattrib, &pframe); + if (rtw_ft_update_rsnie(padapter, _TRUE, pattrib, &pframe)) + rtw_ft_update_ftie(padapter, pattrib, &pframe); + + RTW_INFO("FT : issue RTW_WLAN_ACTION_FT_REQ\n"); + pattrib->last_txcmdsz = pattrib->pktlen; + dump_mgntframe(padapter, pmgntframe); +} + +void rtw_ft_report_evt(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&(pmlmeinfo->network); + struct cfg80211_ft_event_params ft_evt_parms; + _irqL irqL; + + _rtw_memset(&ft_evt_parms, 0, sizeof(ft_evt_parms)); + rtw_ft_update_stainfo(padapter, pnetwork); + + if (!pnetwork) + goto err_2; + + ft_evt_parms.ies_len = pft_roam->ft_event.ies_len; + ft_evt_parms.ies = rtw_zmalloc(ft_evt_parms.ies_len); + if (ft_evt_parms.ies) + _rtw_memcpy((void *)ft_evt_parms.ies, pft_roam->ft_event.ies, ft_evt_parms.ies_len); + else + goto err_2; + + ft_evt_parms.target_ap = rtw_zmalloc(ETH_ALEN); + if (ft_evt_parms.target_ap) + _rtw_memcpy((void *)ft_evt_parms.target_ap, pnetwork->MacAddress, ETH_ALEN); + else + goto err_1; + + ft_evt_parms.ric_ies = pft_roam->ft_event.ric_ies; + ft_evt_parms.ric_ies_len = pft_roam->ft_event.ric_ies_len; + + /* It's a KERNEL issue between v4.11 ~ v4.16, + * <= v4.10, NLMSG_DEFAULT_SIZE is used for nlmsg_new(). + * v4.11 ~ v4.16, only used "100 + >ric_ies_len" for nlmsg_new() + * even then DRIVER don't support RIC. + * >= v4.17, issue should correct as "100 + ies_len + ric_ies_len". + */ + #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0))) + ft_evt_parms.ric_ies_len = (ft_evt_parms.ies_len <= 100 )? + (0):(ft_evt_parms.ies_len - 100); + #endif + + rtw_ft_lock_set_status(padapter, RTW_FT_AUTHENTICATED_STA, &irqL); + rtw_cfg80211_ft_event(padapter, &ft_evt_parms); + RTW_INFO("FT: rtw_ft_report_evt\n"); + rtw_mfree((u8 *)pft_roam->ft_event.target_ap, ETH_ALEN); +err_1: + rtw_mfree((u8 *)ft_evt_parms.ies, ft_evt_parms.ies_len); +err_2: + return; +} + +void rtw_ft_report_reassoc_evt(_adapter *padapter, u8 *pMacAddr) +{ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); + struct cmd_obj *pcmd_obj = NULL; + struct stassoc_event *passoc_sta_evt = NULL; + struct rtw_evt_header *evt_hdr = NULL; + u8 *pevtcmd = NULL; + u32 cmdsz = 0; + + pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); + if (pcmd_obj == NULL) + return; + + cmdsz = (sizeof(struct stassoc_event) + sizeof(struct rtw_evt_header)); + pevtcmd = (u8 *)rtw_zmalloc(cmdsz); + if (pevtcmd == NULL) { + rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); + return; + } + + _rtw_init_listhead(&pcmd_obj->list); + pcmd_obj->cmdcode = CMD_SET_MLME_EVT; + pcmd_obj->cmdsz = cmdsz; + pcmd_obj->parmbuf = pevtcmd; + pcmd_obj->rsp = NULL; + pcmd_obj->rspsz = 0; + + evt_hdr = (struct rtw_evt_header *)(pevtcmd); + evt_hdr->len = sizeof(struct stassoc_event); + evt_hdr->id = EVT_FT_REASSOC; + evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + + passoc_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct rtw_evt_header)); + _rtw_memcpy((unsigned char *)(&(passoc_sta_evt->macaddr)), pMacAddr, ETH_ALEN); + rtw_enqueue_cmd(pcmdpriv, pcmd_obj); +} + +void rtw_ft_link_timer_hdl(void *ctx) +{ + _adapter *padapter = (_adapter *)ctx; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); + + if (rtw_ft_chk_status(padapter, RTW_FT_REQUESTING_STA)) { + if (pft_roam->ft_req_retry_cnt < RTW_FT_ACTION_REQ_LMT) { + pft_roam->ft_req_retry_cnt++; + rtw_ft_issue_action_req(padapter, (u8 *)pmlmepriv->roam_network->network.MacAddress); + _set_timer(&pmlmeext->ft_link_timer, REASSOC_TO); + } else { + pft_roam->ft_req_retry_cnt = 0; + if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) + rtw_ft_set_status(padapter, RTW_FT_ASSOCIATED_STA); + else + rtw_ft_reset_status(padapter); + } + } +} + +void rtw_ft_roam_timer_hdl(void *ctx) +{ + _adapter *padapter = (_adapter *)ctx; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + RTW_FT_INFO("%s : try roaming\n", __func__); + receive_disconnect(padapter, pmlmepriv->cur_network.network.MacAddress + , WLAN_REASON_ACTIVE_ROAM, _FALSE); +} + +void rtw_ft_roam_status_reset(_adapter *padapter) +{ + struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); + + if ((rtw_to_roam(padapter) > 0) && + (!rtw_ft_chk_status(padapter, RTW_FT_REQUESTED_STA))) { + rtw_ft_reset_status(padapter); + } + + padapter->mlmepriv.ft_roam.ft_updated_bcn = _FALSE; +} + +#endif /* CONFIG_RTW_80211R */ diff --git a/core/rtw_ieee80211.c b/core/rtw_ieee80211.c index 345a01b..d9bf9cb 100644 --- a/core/rtw_ieee80211.c +++ b/core/rtw_ieee80211.c @@ -38,6 +38,13 @@ u8 RSN_CIPHER_SUITE_WEP40[] = { 0x00, 0x0f, 0xac, 1 }; u8 RSN_CIPHER_SUITE_TKIP[] = { 0x00, 0x0f, 0xac, 2 }; u8 RSN_CIPHER_SUITE_WRAP[] = { 0x00, 0x0f, 0xac, 3 }; u8 RSN_CIPHER_SUITE_CCMP[] = { 0x00, 0x0f, 0xac, 4 }; +u8 RSN_CIPHER_SUITE_AES_128_CMAC[] = { 0x00, 0x0f, 0xac, 6 }; +u8 RSN_CIPHER_SUITE_GCMP[] = { 0x00, 0x0f, 0xac, 8 }; +u8 RSN_CIPHER_SUITE_GCMP_256[] = { 0x00, 0x0f, 0xac, 9 }; +u8 RSN_CIPHER_SUITE_CCMP_256[] = { 0x00, 0x0f, 0xac, 10 }; +u8 RSN_CIPHER_SUITE_BIP_GMAC_128[] = { 0x00, 0x0f, 0xac, 11 }; +u8 RSN_CIPHER_SUITE_BIP_GMAC_256[] = { 0x00, 0x0f, 0xac, 12 }; +u8 RSN_CIPHER_SUITE_BIP_CMAC_256[] = { 0x00, 0x0f, 0xac, 13 }; u8 RSN_CIPHER_SUITE_WEP104[] = { 0x00, 0x0f, 0xac, 5 }; u8 WLAN_AKM_8021X[] = {0x00, 0x0f, 0xac, 1}; @@ -77,6 +84,20 @@ u8 WIFI_OFDMRATES[] = { IEEE80211_OFDM_RATE_54MB }; +const char *MGN_RATE_STR(enum MGN_RATE rate) +{ + u8 hw_rate; + + if (rate == MGN_MCS32) + return "MCS32"; + + hw_rate = MRateToHwRate(rate); + if (hw_rate == DESC_RATE1M && rate != MGN_1M) + hw_rate = DESC_RATE_NUM; /* invalid case */ + + return HDATA_RATE(hw_rate); +} + u8 mgn_rates_cck[4] = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M}; u8 mgn_rates_ofdm[8] = {MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M}; u8 mgn_rates_mcs0_7[8] = {MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7}; @@ -516,17 +537,24 @@ u8 rtw_update_rate_bymode(WLAN_BSSID_EX *pbss_network, u32 mode) pbss_network->IELength -= ie_len; } network_type = WIRELESS_11B; - } else if ((mode & WIRELESS_11B) == 0) { - /* Remove CCK in support_rate IE */ - rtw_filter_suppport_rateie(pbss_network, OFDM); - if (pbss_network->Configuration.DSConfig > 14) + } else { + if (pbss_network->Configuration.DSConfig > 14) { + /* Remove CCK in support_rate IE */ + rtw_filter_suppport_rateie(pbss_network, OFDM); network_type = WIRELESS_11A; - else - network_type = WIRELESS_11G; - } else - network_type = WIRELESS_11BG; /* do nothing */ + } else { + if ((mode & WIRELESS_11B) == 0) { + /* Remove CCK in support_rate IE */ + rtw_filter_suppport_rateie(pbss_network, OFDM); + network_type = WIRELESS_11G; + } else { + network_type = WIRELESS_11BG; + } + } + } rtw_set_supported_rate(pbss_network->SupportedRates, network_type); + return network_type; } @@ -706,7 +734,7 @@ int rtw_get_wpa_cipher_suite(u8 *s) return 0; } -int rtw_get_wpa2_cipher_suite(u8 *s) +int rtw_get_rsn_cipher_suite(u8 *s) { if (_rtw_memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN) == _TRUE) return WPA_CIPHER_NONE; @@ -716,9 +744,22 @@ int rtw_get_wpa2_cipher_suite(u8 *s) return WPA_CIPHER_TKIP; if (_rtw_memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN) == _TRUE) return WPA_CIPHER_CCMP; + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_GCMP, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_GCMP; + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_GCMP_256, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_GCMP_256; + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_CCMP_256, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_CCMP_256; if (_rtw_memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN) == _TRUE) return WPA_CIPHER_WEP104; - + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_AES_128_CMAC, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_BIP_CMAC_128; + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_BIP_GMAC_128, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_BIP_GMAC_128; + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_BIP_GMAC_256, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_BIP_GMAC_256; + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_BIP_CMAC_256, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_BIP_CMAC_256; return 0; } @@ -834,6 +875,7 @@ int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int rtw_rsne_info_parse(const u8 *ie, uint ie_len, struct rsne_info *info) { const u8 *pos = ie; + u16 ver; u16 cnt; _rtw_memset(info, 0, sizeof(struct rsne_info)); @@ -843,7 +885,13 @@ int rtw_rsne_info_parse(const u8 *ie, uint ie_len, struct rsne_info *info) if (*ie != WLAN_EID_RSN || *(ie + 1) != ie_len - 2) goto err; - pos += 2 + 2; + pos += 2; + + /* Version */ + ver = RTW_GET_LE16(pos); + if(1 != ver) + goto err; + pos += 2; /* Group CS */ if (ie + ie_len < pos + 4) { @@ -905,11 +953,8 @@ int rtw_rsne_info_parse(const u8 *ie, uint ie_len, struct rsne_info *info) } cnt = RTW_GET_LE16(pos); pos += 2; - if (ie + ie_len < pos + 16 * cnt) { - if (ie + ie_len != pos) - goto err; - goto exit; - } + if (ie + ie_len < pos + 16 * cnt) + goto err; info->pmkid_cnt = cnt; info->pmkid_list = (u8 *)pos; pos += 16 * cnt; @@ -931,7 +976,7 @@ err: } int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, - int *pairwise_cipher, u32 *akm, u8 *mfp_opt) + int *pairwise_cipher, int *gmcs, u32 *akm, u8 *mfp_opt, u8 *spp_opt) { struct rsne_info info; int i, ret = _SUCCESS; @@ -942,21 +987,32 @@ int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, if (group_cipher) { if (info.gcs) - *group_cipher = rtw_get_wpa2_cipher_suite(info.gcs); + *group_cipher = rtw_get_rsn_cipher_suite(info.gcs); else *group_cipher = 0; } if (pairwise_cipher) { *pairwise_cipher = 0; - for (i = 0; i < info.pcs_cnt; i++) - *pairwise_cipher |= rtw_get_wpa2_cipher_suite(info.pcs_list + 4 * i); + if (info.pcs_list) { + for (i = 0; i < info.pcs_cnt; i++) + *pairwise_cipher |= rtw_get_rsn_cipher_suite(info.pcs_list + 4 * i); + } + } + + if (gmcs) { + if (info.gmcs) + *gmcs = rtw_get_rsn_cipher_suite(info.gmcs); + else + *gmcs = WPA_CIPHER_BIP_CMAC_128; /* default value when absent */ } if (akm) { *akm = 0; - for (i = 0; i < info.akm_cnt; i++) - *akm |= rtw_get_akm_suite_bitmap(info.akm_list + 4 * i); + if (info.akm_list) { + for (i = 0; i < info.akm_cnt; i++) + *akm |= rtw_get_akm_suite_bitmap(info.akm_list + 4 * i); + } } if (mfp_opt) { @@ -965,6 +1021,12 @@ int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, *mfp_opt = GET_RSN_CAP_MFP_OPTION(info.cap); } + if (spp_opt) { + *spp_opt = 0; + if (info.cap) + *spp_opt = GET_RSN_CAP_SPP_OPT(info.cap); + } + exit: return ret; } @@ -1378,7 +1440,14 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, return -1; } break; - +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + case OUI_REALTEK: + if (elen == 8) { // TBTX capable IE length is 8 + elems->tbtx_cap = pos; + elems->tbtx_cap_len = elen; + } + break; +#endif default: RTW_DBG("unknown vendor specific information " "element ignored (vendor OUI %02x:%02x:%02x " @@ -1735,6 +1804,7 @@ err_chk: RTW_INFO("%s mac addr:"MAC_FMT"\n", __func__, MAC_ARG(out)); } +#ifdef CONFIG_RTW_DEBUG #ifdef CONFIG_80211N_HT void dump_ht_cap_ie_content(void *sel, const u8 *buf, u32 buf_len) { @@ -1797,36 +1867,6 @@ void dump_ht_op_ie(void *sel, const u8 *ie, u32 ie_len) } #endif /* CONFIG_80211N_HT */ -void dump_ies(void *sel, const u8 *buf, u32 buf_len) -{ - const u8 *pos = buf; - u8 id, len; - - while (pos - buf + 1 < buf_len) { - id = *pos; - len = *(pos + 1); - - RTW_PRINT_SEL(sel, "%s ID:%u, LEN:%u\n", __FUNCTION__, id, len); -#ifdef CONFIG_80211N_HT - dump_ht_cap_ie(sel, pos, len + 2); - dump_ht_op_ie(sel, pos, len + 2); -#endif -#ifdef CONFIG_80211AC_VHT - dump_vht_cap_ie(sel, pos, len + 2); - dump_vht_op_ie(sel, pos, len + 2); -#endif - dump_wps_ie(sel, pos, len + 2); -#ifdef CONFIG_P2P - dump_p2p_ie(sel, pos, len + 2); -#ifdef CONFIG_WFD - dump_wfd_ie(sel, pos, len + 2); -#endif -#endif - - pos += (2 + len); - } -} - void dump_wps_ie(void *sel, const u8 *ie, u32 ie_len) { const u8 *pos = ie; @@ -1851,6 +1891,41 @@ void dump_wps_ie(void *sel, const u8 *ie, u32 ie_len) pos += (4 + len); } } +#endif /* CONFIG_RTW_DEBUG */ +void dump_ies(void *sel, const u8 *buf, u32 buf_len) +{ +#ifdef CONFIG_RTW_DEBUG + const u8 *pos = buf; + u8 id, len; + + while (pos - buf + 1 < buf_len) { + id = *pos; + len = *(pos + 1); + + RTW_PRINT_SEL(sel, "%s ID:%u, LEN:%u\n", __FUNCTION__, id, len); +#ifdef CONFIG_80211N_HT + dump_ht_cap_ie(sel, pos, len + 2); + dump_ht_op_ie(sel, pos, len + 2); +#endif +#ifdef CONFIG_80211AC_VHT + dump_vht_cap_ie(sel, pos, len + 2); + dump_vht_op_ie(sel, pos, len + 2); +#endif + dump_wps_ie(sel, pos, len + 2); +#ifdef CONFIG_P2P + dump_p2p_ie(sel, pos, len + 2); +#ifdef CONFIG_WFD + dump_wfd_ie(sel, pos, len + 2); +#endif +#endif +#ifdef CONFIG_RTW_MULTI_AP + dump_multi_ap_ie(sel, pos, len + 2); +#endif + + pos += (2 + len); + } +#endif /* CONFIG_RTW_DEBUG */ +} /** * rtw_ies_get_chbw - get operation ch, bw, offset from IEs of BSS. @@ -2032,6 +2107,7 @@ void rtw_sync_chbw(u8 *req_ch, u8 *req_bw, u8 *req_offset } } +#ifdef CONFIG_P2P /** * rtw_get_p2p_merged_len - Get merged ie length from muitiple p2p ies. * @in_ie: Pointer of the first p2p ie @@ -2441,31 +2517,7 @@ void rtw_bss_ex_del_p2p_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id) break; } } - -void dump_wfd_ie(void *sel, const u8 *ie, u32 ie_len) -{ - const u8 *pos = ie; - u8 id; - u16 len; - - const u8 *wfd_ie; - uint wfd_ielen; - - wfd_ie = rtw_get_wfd_ie(ie, ie_len, NULL, &wfd_ielen); - if (wfd_ie != ie || wfd_ielen == 0) - return; - - pos += 6; - while (pos - ie + 3 <= ie_len) { - id = *pos; - len = RTW_GET_BE16(pos + 1); - - RTW_PRINT_SEL(sel, "%s ID:%u, LEN:%u%s\n", __func__, id, len - , ((pos - ie + 3 + len) <= ie_len) ? "" : "(exceed ie_len)"); - - pos += (3 + len); - } -} +#endif /* CONFIG_P2P */ /** * rtw_get_wfd_ie - Search WFD IE from a series of IEs @@ -2521,6 +2573,84 @@ u8 *rtw_get_wfd_ie(const u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen) return (u8 *)wfd_ie_ptr; } +uint rtw_del_wfd_ie(u8 *ies, uint ies_len_ori, const char *msg) +{ +#define DBG_DEL_WFD_IE 0 + + u8 *target_ie; + u32 target_ie_len; + uint ies_len = ies_len_ori; + int index = 0; + + while (1) { + target_ie = rtw_get_wfd_ie(ies, ies_len, NULL, &target_ie_len); + if (target_ie && target_ie_len) { + u8 *next_ie = target_ie + target_ie_len; + uint remain_len = ies_len - (next_ie - ies); + + if (DBG_DEL_WFD_IE && msg) { + RTW_INFO("%s %d before\n", __func__, index); + dump_ies(RTW_DBGDUMP, ies, ies_len); + + RTW_INFO("ies:%p, ies_len:%u\n", ies, ies_len); + RTW_INFO("target_ie:%p, target_ie_len:%u\n", target_ie, target_ie_len); + RTW_INFO("next_ie:%p, remain_len:%u\n", next_ie, remain_len); + } + + _rtw_memmove(target_ie, next_ie, remain_len); + _rtw_memset(target_ie + remain_len, 0, target_ie_len); + ies_len -= target_ie_len; + + if (DBG_DEL_WFD_IE && msg) { + RTW_INFO("%s %d after\n", __func__, index); + dump_ies(RTW_DBGDUMP, ies, ies_len); + } + + index++; + } else + break; + } + + return ies_len; +} + +void rtw_bss_ex_del_wfd_ie(WLAN_BSSID_EX *bss_ex) +{ +#define DBG_BSS_EX_DEL_WFD_IE 0 + u8 *ies = BSS_EX_TLV_IES(bss_ex); + uint ies_len_ori = BSS_EX_TLV_IES_LEN(bss_ex); + uint ies_len; + + ies_len = rtw_del_wfd_ie(ies, ies_len_ori, DBG_BSS_EX_DEL_WFD_IE ? __func__ : NULL); + bss_ex->IELength -= ies_len_ori - ies_len; +} + +#ifdef CONFIG_WFD +void dump_wfd_ie(void *sel, const u8 *ie, u32 ie_len) +{ + const u8 *pos = ie; + u8 id; + u16 len; + + const u8 *wfd_ie; + uint wfd_ielen; + + wfd_ie = rtw_get_wfd_ie(ie, ie_len, NULL, &wfd_ielen); + if (wfd_ie != ie || wfd_ielen == 0) + return; + + pos += 6; + while (pos - ie + 3 <= ie_len) { + id = *pos; + len = RTW_GET_BE16(pos + 1); + + RTW_PRINT_SEL(sel, "%s ID:%u, LEN:%u%s\n", __func__, id, len + , ((pos - ie + 3 + len) <= ie_len) ? "" : "(exceed ie_len)"); + + pos += (3 + len); + } +} + /** * rtw_get_wfd_attr - Search a specific WFD attribute from a given WFD IE * @wfd_ie: Address of WFD IE to search @@ -2611,47 +2741,6 @@ u8 *rtw_get_wfd_attr_content(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id, u8 * return NULL; } -uint rtw_del_wfd_ie(u8 *ies, uint ies_len_ori, const char *msg) -{ -#define DBG_DEL_WFD_IE 0 - - u8 *target_ie; - u32 target_ie_len; - uint ies_len = ies_len_ori; - int index = 0; - - while (1) { - target_ie = rtw_get_wfd_ie(ies, ies_len, NULL, &target_ie_len); - if (target_ie && target_ie_len) { - u8 *next_ie = target_ie + target_ie_len; - uint remain_len = ies_len - (next_ie - ies); - - if (DBG_DEL_WFD_IE && msg) { - RTW_INFO("%s %d before\n", __func__, index); - dump_ies(RTW_DBGDUMP, ies, ies_len); - - RTW_INFO("ies:%p, ies_len:%u\n", ies, ies_len); - RTW_INFO("target_ie:%p, target_ie_len:%u\n", target_ie, target_ie_len); - RTW_INFO("next_ie:%p, remain_len:%u\n", next_ie, remain_len); - } - - _rtw_memmove(target_ie, next_ie, remain_len); - _rtw_memset(target_ie + remain_len, 0, target_ie_len); - ies_len -= target_ie_len; - - if (DBG_DEL_WFD_IE && msg) { - RTW_INFO("%s %d after\n", __func__, index); - dump_ies(RTW_DBGDUMP, ies, ies_len); - } - - index++; - } else - break; - } - - return ies_len; -} - uint rtw_del_wfd_attr(u8 *ie, uint ielen_ori, u8 attr_id) { #define DBG_DEL_WFD_ATTR 0 @@ -2699,17 +2788,6 @@ inline u8 *rtw_bss_ex_get_wfd_ie(WLAN_BSSID_EX *bss_ex, u8 *wfd_ie, uint *wfd_ie return rtw_get_wfd_ie(BSS_EX_TLV_IES(bss_ex), BSS_EX_TLV_IES_LEN(bss_ex), wfd_ie, wfd_ielen); } -void rtw_bss_ex_del_wfd_ie(WLAN_BSSID_EX *bss_ex) -{ -#define DBG_BSS_EX_DEL_WFD_IE 0 - u8 *ies = BSS_EX_TLV_IES(bss_ex); - uint ies_len_ori = BSS_EX_TLV_IES_LEN(bss_ex); - uint ies_len; - - ies_len = rtw_del_wfd_ie(ies, ies_len_ori, DBG_BSS_EX_DEL_WFD_IE ? __func__ : NULL); - bss_ex->IELength -= ies_len_ori - ies_len; -} - void rtw_bss_ex_del_wfd_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id) { #define DBG_BSS_EX_DEL_WFD_ATTR 0 @@ -2767,6 +2845,79 @@ void rtw_bss_ex_del_wfd_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id) break; } } +#endif /* CONFIG_WFD */ + +#ifdef CONFIG_RTW_MULTI_AP +void dump_multi_ap_ie(void *sel, const u8 *ie, u32 ie_len) +{ + const u8 *pos = ie; + u8 id; + u8 len; + + const u8 *multi_ap_ie; + uint multi_ap_ielen; + + multi_ap_ie = rtw_get_ie_ex(ie, ie_len, WLAN_EID_VENDOR_SPECIFIC, MULTI_AP_OUI, 4, NULL, &multi_ap_ielen); + if (multi_ap_ie != ie || multi_ap_ielen == 0) + return; + + pos += 6; + while (pos - ie + 2 <= ie_len) { + id = *pos; + len = *(pos + 1); + + RTW_PRINT_SEL(sel, "%s ID:%u, LEN:%u%s\n", __func__, id, len + , ((pos - ie + 2 + len) <= ie_len) ? "" : "(exceed ie_len)"); + RTW_DUMP_SEL(sel, pos + 2, len); + + pos += (2 + len); + } +} + +/** + * rtw_get_multi_ap_ext - Search Multi-AP IE from a series of IEs and return extension subelement value + * @ies: Address of IEs to search + * @ies_len: Length limit from in_ie + * + * Returns: The address of the target IE found, or NULL + */ +u8 rtw_get_multi_ap_ie_ext(const u8 *ies, int ies_len) +{ + u8 *ie; + uint ielen; + u8 val = 0; + + ie = rtw_get_ie_ex(ies, ies_len, WLAN_EID_VENDOR_SPECIFIC, MULTI_AP_OUI, 4, NULL, &ielen); + if (ielen < 9) + goto exit; + + if (ie[6] != MULTI_AP_SUB_ELEM_TYPE) + goto exit; + + val = ie[8]; + +exit: + return val; +} + +u8 *rtw_set_multi_ap_ie_ext(u8 *pbuf, uint *frlen, u8 val) +{ + u8 cont_len = 7; + + *pbuf++ = WLAN_EID_VENDOR_SPECIFIC; + *pbuf++ = cont_len; + _rtw_memcpy(pbuf, MULTI_AP_OUI, 4); + pbuf += 4; + *pbuf++ = MULTI_AP_SUB_ELEM_TYPE; + *pbuf++ = 1; /* len */ + *pbuf++ = val; + + if (frlen) + *frlen = *frlen + (cont_len + 2); + + return pbuf; +} +#endif /* CONFIG_RTW_MULTI_AP */ /* Baron adds to avoid FreeBSD warning */ int ieee80211_is_empty_essid(const char *essid, int essid_len) @@ -2922,6 +3073,23 @@ u16 rtw_ht_mcs_rate(u8 bw_40MHz, u8 short_GI, unsigned char *MCS_rate) return max_rate; } +u8 rtw_ht_cap_get_rx_nss(u8 *ht_cap) +{ + u8 *ht_mcs_set = HT_CAP_ELE_SUP_MCS_SET(ht_cap); + + return rtw_ht_mcsset_to_nss(ht_mcs_set); +} + +u8 rtw_ht_cap_get_tx_nss(u8 *ht_cap) +{ + u8 *ht_mcs_set = HT_CAP_ELE_SUP_MCS_SET(ht_cap); + + if (GET_HT_CAP_ELE_TX_MCS_DEF(ht_cap) && GET_HT_CAP_ELE_TRX_MCS_NEQ(ht_cap)) + return GET_HT_CAP_ELE_TX_MAX_SS(ht_cap) + 1; + + return rtw_ht_cap_get_rx_nss(ht_cap); +} + int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8 *category, u8 *action) { const u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr); @@ -2954,23 +3122,41 @@ int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8 *category, u8 *act } static const char *_action_public_str[] = { - "ACT_PUB_BSSCOEXIST", - "ACT_PUB_DSE_ENABLE", - "ACT_PUB_DSE_DEENABLE", - "ACT_PUB_DSE_REG_LOCATION", - "ACT_PUB_EXT_CHL_SWITCH", - "ACT_PUB_DSE_MSR_REQ", - "ACT_PUB_DSE_MSR_RPRT", - "ACT_PUB_MP", - "ACT_PUB_DSE_PWR_CONSTRAINT", - "ACT_PUB_VENDOR", - "ACT_PUB_GAS_INITIAL_REQ", - "ACT_PUB_GAS_INITIAL_RSP", - "ACT_PUB_GAS_COMEBACK_REQ", - "ACT_PUB_GAS_COMEBACK_RSP", - "ACT_PUB_TDLS_DISCOVERY_RSP", - "ACT_PUB_LOCATION_TRACK", - "ACT_PUB_RSVD", + [ACT_PUBLIC_BSSCOEXIST] = "ACT_PUB_BSSCOEXIST", + [ACT_PUBLIC_DSE_ENABLE] = "ACT_PUB_DSE_ENABLE", + [ACT_PUBLIC_DSE_DEENABLE] = "ACT_PUB_DSE_DEENABLE", + [ACT_PUBLIC_DSE_REG_LOCATION] = "ACT_PUB_DSE_REG_LOCATION", + [ACT_PUBLIC_EXT_CHL_SWITCH] = "ACT_PUB_EXT_CHL_SWITCH", + [ACT_PUBLIC_DSE_MSR_REQ] = "ACT_PUB_DSE_MSR_REQ", + [ACT_PUBLIC_DSE_MSR_RPRT] = "ACT_PUB_DSE_MSR_RPRT", + [ACT_PUBLIC_MP] = "ACT_PUB_MP", + [ACT_PUBLIC_DSE_PWR_CONSTRAINT] = "ACT_PUB_DSE_PWR_CONSTRAINT", + [ACT_PUBLIC_VENDOR] = "ACT_PUB_VENDOR", + [ACT_PUBLIC_GAS_INITIAL_REQ] = "ACT_PUB_GAS_INITIAL_REQ", + [ACT_PUBLIC_GAS_INITIAL_RSP] = "ACT_PUB_GAS_INITIAL_RSP", + [ACT_PUBLIC_GAS_COMEBACK_REQ] = "ACT_PUB_GAS_COMEBACK_REQ", + [ACT_PUBLIC_GAS_COMEBACK_RSP] = "ACT_PUB_GAS_COMEBACK_RSP", + [ACT_PUBLIC_TDLS_DISCOVERY_RSP] = "ACT_PUB_TDLS_DISCOVERY_RSP", + [ACT_PUBLIC_LOCATION_TRACK] = "ACT_PUB_LOCATION_TRACK", + [ACT_PUBLIC_QAB_REQ] = "ACT_PUB_QAB_REQ", + [ACT_PUBLIC_QAB_RSP] = "ACT_PUB_QAB_RSP", + [ACT_PUBLIC_QMF_POLICY] = "ACT_PUB_QMF_POLICY", + [ACT_PUBLIC_QMF_POLICY_CHANGE] = "ACT_PUB_QMF_POLICY_CHANGE", + [ACT_PUBLIC_QLOAD_REQ] = "ACT_PUB_QLOAD_REQ", + [ACT_PUBLIC_QLOAD_REPORT] = "ACT_PUB_QLOAD_REPORT", + [ACT_PUBLIC_HCCA_TXOP_ADV] = "ACT_PUB_HCCA_TXOP_ADV", + [ACT_PUBLIC_HCCA_TXOP_RSP] = "ACT_PUB_HCCA_TXOP_RSP", + [ACT_PUBLIC_PUBLIC_KEY] = "ACT_PUB_PUBLIC_KEY", + [ACT_PUBLIC_CH_AVAILABILITY_QUERY] = "ACT_PUB_CH_AVAILABILITY_QUERY", + [ACT_PUBLIC_CH_SCHEDULE_MGMT] = "ACT_PUB_CH_SCHEDULE_MGMT", + [ACT_PUBLIC_CONTACT_VERI_SIGNAL] = "ACT_PUB_CONTACT_VERI_SIGNAL", + [ACT_PUBLIC_GDD_ENABLE_REQ] = "ACT_PUB_GDD_ENABLE_REQ", + [ACT_PUBLIC_GDD_ENABLE_RSP] = "ACT_PUB_GDD_ENABLE_RSP", + [ACT_PUBLIC_NETWORK_CH_CONTROL] = "ACT_PUB_NETWORK_CH_CONTROL", + [ACT_PUBLIC_WHITE_SPACE_MAP_ANN] = "ACT_PUB_WHITE_SPACE_MAP_ANN", + [ACT_PUBLIC_FTM_REQ] = "ACT_PUB_FTM_REQ", + [ACT_PUBLIC_FTM] = "ACT_PUB_FTM", + [ACT_PUBLIC_MAX] = "ACT_PUB_RSVD", }; const char *action_public_str(u8 action) @@ -2979,3 +3165,53 @@ const char *action_public_str(u8 action) return _action_public_str[action]; } +#if 0 +/*tmp for sta mode, root cause have to wait supplicant's update.*/ +void rtw_set_spp_amsdu_mode(u8 mode, u8 *rsn_ie, int rsn_ie_len) +{ + struct rsne_info info; + int i, ret = _SUCCESS; + u8 spp_req_cap = 0; + + ret = rtw_rsne_info_parse(rsn_ie, rsn_ie_len, &info); + if (ret != _SUCCESS) + return; + + if (mode == RTW_AMSDU_MODE_NON_SPP ) { + spp_req_cap = 0; /* SPP_CAP=0, SPP_REQ=0 */ + } else if (mode == RTW_AMSDU_MODE_SPP) { + spp_req_cap = SPP_CAP | SPP_REQ; + } else if (mode == RTW_AMSDU_MODE_ALL_DROP) { + spp_req_cap = SPP_REQ; /* SPP_CAP=0, SPP_REQ=1 */ + } else { + RTW_INFO("%s unexpected mode = %d, please check the config\n", __func__, mode); + return; + } + + SET_RSN_CAP_SPP(info.cap, spp_req_cap); + RTW_INFO("%s set spp opt = %d\n", __func__, GET_RSN_CAP_SPP_OPT(info.cap)); +} +#endif + +/* Returns: + _TRUE -- Disable AMSDU + _FALSE -- Enable AMSDU +*/ +u8 rtw_check_amsdu_disable(u8 mode, u8 spp_opt) +{ + u8 ret = _FALSE; + + /* pp amsdu: peer's required has to be 0, or disable */ + if ((mode == RTW_AMSDU_MODE_NON_SPP) && (spp_opt & SPP_REQ)) + ret = _TRUE; + /* spp amsdu: peer's cap has to be 1, or disable */ + else if ((mode == RTW_AMSDU_MODE_SPP) && (!(spp_opt & SPP_CAP))) + ret = _TRUE; + /* mode = all drop */ + else if (mode == RTW_AMSDU_MODE_ALL_DROP) + ret = _TRUE; + else + ret = _FALSE; + return ret; +} + diff --git a/core/rtw_ioctl_set.c b/core/rtw_ioctl_set.c index a44ca12..060546c 100644 --- a/core/rtw_ioctl_set.c +++ b/core/rtw_ioctl_set.c @@ -88,7 +88,7 @@ u8 rtw_do_join(_adapter *padapter) pmlmepriv->cur_network.join_res = -2; - set_fwstate(pmlmepriv, _FW_UNDER_LINKING); + set_fwstate(pmlmepriv, WIFI_UNDER_LINKING); pmlmepriv->pscanned = plist; @@ -106,7 +106,7 @@ u8 rtw_do_join(_adapter *padapter) if (_rtw_queue_empty(queue) == _TRUE) { _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING); /* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */ /* we try to issue sitesurvey firstly */ @@ -141,6 +141,7 @@ u8 rtw_do_join(_adapter *padapter) _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); } else { if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) { + #ifdef CONFIG_AP_MODE /* submit createbss_cmd to change to a ADHOC_MASTER */ /* pmlmepriv->lock has been acquired by caller... */ @@ -164,11 +165,10 @@ u8 rtw_do_join(_adapter *padapter) } pmlmepriv->to_join = _FALSE; - - + #endif /* CONFIG_AP_MODE */ } else { /* can't associate ; reset under-linking */ - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING); /* when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue */ /* we try to issue sitesurvey firstly */ @@ -223,12 +223,12 @@ u8 rtw_set_802_11_bssid(_adapter *padapter, u8 *bssid) RTW_INFO("Set BSSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv)); - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE) goto handle_tkip_countermeasure; - else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) + else if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE) goto release_mlme_lock; - if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE) { if (_rtw_memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN) == _TRUE) { if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE) @@ -237,7 +237,7 @@ u8 rtw_set_802_11_bssid(_adapter *padapter, u8 *bssid) rtw_disassoc_cmd(padapter, 0, 0); - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) rtw_indicate_disconnect(padapter, 0, _FALSE); rtw_free_assoc_resources_cmd(padapter, _TRUE, 0); @@ -260,7 +260,7 @@ handle_tkip_countermeasure: pmlmepriv->assoc_ch = 0; pmlmepriv->assoc_by_bssid = _TRUE; - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE) pmlmepriv->to_join = _TRUE; else status = rtw_do_join(padapter); @@ -294,12 +294,12 @@ u8 rtw_set_802_11_ssid(_adapter *padapter, NDIS_802_11_SSID *ssid) _enter_critical_bh(&pmlmepriv->lock, &irqL); RTW_INFO("Set SSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv)); - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE) goto handle_tkip_countermeasure; - else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) + else if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE) goto release_mlme_lock; - if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE) { if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && (_rtw_memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength) == _TRUE)) { @@ -309,7 +309,7 @@ u8 rtw_set_802_11_ssid(_adapter *padapter, NDIS_802_11_SSID *ssid) /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */ rtw_disassoc_cmd(padapter, 0, 0); - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) rtw_indicate_disconnect(padapter, 0, _FALSE); rtw_free_assoc_resources_cmd(padapter, _TRUE, 0); @@ -330,7 +330,7 @@ u8 rtw_set_802_11_ssid(_adapter *padapter, NDIS_802_11_SSID *ssid) rtw_disassoc_cmd(padapter, 0, 0); - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) rtw_indicate_disconnect(padapter, 0, _FALSE); rtw_free_assoc_resources_cmd(padapter, _TRUE, 0); @@ -357,7 +357,7 @@ handle_tkip_countermeasure: pmlmepriv->assoc_ch = 0; pmlmepriv->assoc_by_bssid = _FALSE; - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE) pmlmepriv->to_join = _TRUE; else status = rtw_do_join(padapter); @@ -405,9 +405,9 @@ u8 rtw_set_802_11_connect(_adapter *padapter, RTW_PRINT(FUNC_ADPT_FMT" fw_state=0x%08x\n", FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv)); - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE) goto handle_tkip_countermeasure; - else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) + else if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE) goto release_mlme_lock; handle_tkip_countermeasure: @@ -429,7 +429,7 @@ handle_tkip_countermeasure: pmlmepriv->assoc_ch = ch; - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE) pmlmepriv->to_join = _TRUE; else status = rtw_do_join(padapter); @@ -467,7 +467,7 @@ u8 rtw_set_802_11_infrastructure_mode(_adapter *padapter, } _enter_critical_bh(&pmlmepriv->lock, &irqL); - is_linked = check_fwstate(pmlmepriv, _FW_LINKED); + is_linked = check_fwstate(pmlmepriv, WIFI_ASOC_STATE); is_adhoc_master = check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE); /* flags = 0, means enqueue cmd and no wait */ @@ -526,9 +526,11 @@ u8 rtw_set_802_11_infrastructure_mode(_adapter *padapter, case Ndis802_11AutoUnknown: case Ndis802_11InfrastructureMax: break; +#ifdef CONFIG_WIFI_MONITOR case Ndis802_11Monitor: set_fwstate(pmlmepriv, WIFI_MONITOR_STATE); break; +#endif /* CONFIG_WIFI_MONITOR */ default: ret = _FALSE; rtw_warn_on(1); @@ -552,7 +554,7 @@ u8 rtw_set_802_11_disassociate(_adapter *padapter) _enter_critical_bh(&pmlmepriv->lock, &irqL); - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { rtw_disassoc_cmd(padapter, 0, 0); rtw_indicate_disconnect(padapter, 0, _FALSE); @@ -600,7 +602,7 @@ u8 rtw_set_802_11_bssid_list_scan(_adapter *padapter, struct sitesurvey_parm *pp goto exit; } - if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) || + if ((check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING) == _TRUE) || (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)) { /* Scan or linking is in progress, do nothing. */ res = _TRUE; @@ -795,7 +797,7 @@ u16 rtw_get_cur_max_rate(_adapter *adapter) } #endif - if ((check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE) + if ((check_fwstate(pmlmepriv, WIFI_ASOC_STATE) != _TRUE) && (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE)) return 0; @@ -880,8 +882,12 @@ int rtw_set_scan_mode(_adapter *adapter, RT_SCAN_TYPE scan_mode) */ int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan) { - /* handle by cmd_thread to sync with scan operation */ - return rtw_set_chplan_cmd(adapter, RTW_CMDF_WAIT_ACK, channel_plan, 1); + struct registry_priv *regsty = adapter_to_regsty(adapter); + + if (!REGSTY_REGD_SRC_FROM_OS(regsty)) + return rtw_set_chplan_cmd(adapter, RTW_CMDF_WAIT_ACK, channel_plan, 1); + RTW_WARN("%s(): not applied\n", __func__); + return _SUCCESS; } /* @@ -894,11 +900,13 @@ int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan) int rtw_set_country(_adapter *adapter, const char *country_code) { #ifdef CONFIG_RTW_IOCTL_SET_COUNTRY - return rtw_set_country_cmd(adapter, RTW_CMDF_WAIT_ACK, country_code, 1); -#else - RTW_INFO("%s(): not applied\n", __func__); - return _SUCCESS; + struct registry_priv *regsty = adapter_to_regsty(adapter); + + if (!REGSTY_REGD_SRC_FROM_OS(regsty)) + return rtw_set_country_cmd(adapter, RTW_CMDF_WAIT_ACK, country_code, 1); #endif + RTW_WARN("%s(): not applied\n", __func__); + return _SUCCESS; } /* diff --git a/core/rtw_iol.c b/core/rtw_iol.c index 6063ea6..714a3f4 100644 --- a/core/rtw_iol.c +++ b/core/rtw_iol.c @@ -24,7 +24,7 @@ struct xmit_frame *rtw_IOL_accquire_xmit_frame(ADAPTER *adapter) struct xmit_priv *pxmitpriv = &(adapter->xmitpriv); #if 1 - xmit_frame = rtw_alloc_xmitframe(pxmitpriv); + xmit_frame = rtw_alloc_xmitframe(pxmitpriv, 0); if (xmit_frame == NULL) { RTW_INFO("%s rtw_alloc_xmitframe return null\n", __FUNCTION__); goto exit; diff --git a/core/rtw_mbo.c b/core/rtw_mbo.c new file mode 100644 index 0000000..44f93ad --- /dev/null +++ b/core/rtw_mbo.c @@ -0,0 +1,803 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#include +#include + +#ifdef CONFIG_RTW_MBO + +#ifndef RTW_MBO_DBG +#define RTW_MBO_DBG 0 +#endif +#if RTW_MBO_DBG + #define RTW_MBO_INFO(fmt, arg...) \ + RTW_INFO(fmt, arg) + #define RTW_MBO_DUMP(str, data, len) \ + RTW_INFO_DUMP(str, data, len) +#else + #define RTW_MBO_INFO(fmt, arg...) do {} while (0) + #define RTW_MBO_DUMP(str, data, len) do {} while (0) +#endif + +/* Cellular Data Connectivity field + * 1 : Cellular data connection available + * 2 : Cellular data connection not available + * 3 : Not Cellular data capable + * otherwise : Reserved +*/ +int rtw_mbo_cell_data_conn = 2; +module_param(rtw_mbo_cell_data_conn, int, 0644); + +static u8 wfa_mbo_oui[] = {0x50, 0x6F, 0x9A, 0x16}; + +#define rtw_mbo_get_oui(p) ((u8 *)(p) + 2) + +#define rtw_mbo_get_attr_id(p) ((u8 *)(p)) + +#define rtw_mbo_get_disallow_res(p) ((u8 *)(p) + 3) + +#define rtw_mbo_set_1byte_ie(p, v, l) \ + rtw_set_fixed_ie((p), 1, (v), (l)) + +#define rtw_mbo_set_4byte_ie(p, v, l) \ + rtw_set_fixed_ie((p), 4, (v), (l)) + +#define rtw_mbo_set_nbyte_ie(p, sz, v, l) \ + rtw_set_fixed_ie((p), (sz), (v), (l)) + +#define rtw_mbo_subfield_set(p, offset, val) (*(p + offset) = val) + +#define rtw_mbo_subfields_set(p, offset, buf, len) \ + do { \ + u32 _offset = 0; \ + u8 *_p = p + offset; \ + while(_offset < len) { \ + *(_p + _offset) = *(buf + _offset); \ + _offset++; \ + } \ + } while(0) + +static u8 *rtw_mbo_ie_get(u8 *pie, u32 *plen, u32 limit) +{ + const u8 *p = pie; + u32 tmp, i; + + if (limit <= 1) + return NULL; + + i = 0; + *plen = 0; + while (1) { + if ((*p == _VENDOR_SPECIFIC_IE_) && + (_rtw_memcmp(rtw_mbo_get_oui(p), wfa_mbo_oui, 4))) { + *plen = *(p + 1); + RTW_MBO_DUMP("VENDOR_SPECIFIC_IE MBO: ", p, *(p + 1)); + return (u8 *)p; + } else { + tmp = *(p + 1); + p += (tmp + 2); + i += (tmp + 2); + } + + if (i >= limit) + break; + } + + return NULL; +} + +static u8 *rtw_mbo_attrs_get(u8 *pie, u32 limit, u8 attr_id, u32 *attr_len) +{ + u8 *p = NULL; + u32 offset, plen = 0; + + if ((pie == NULL) || (limit <= 1)) + goto exit; + + if ((p = rtw_mbo_ie_get(pie, &plen, limit)) == NULL) + goto exit; + + /* shift 2 + OUI size and move to attributes content */ + p = p + 2 + sizeof(wfa_mbo_oui); + plen = plen - 4; + RTW_MBO_DUMP("Attributes contents: ", p, plen); + + if ((p = rtw_get_ie(p, attr_id, attr_len, plen)) == NULL) + goto exit; + + RTW_MBO_INFO("%s : id=%u(len=%u)\n", __func__, attr_id, *attr_len); + RTW_MBO_DUMP("contents : ", p, *attr_len); + +exit: + return p; + +} + +static u32 rtw_mbo_attr_sz_get( + _adapter *padapter, u8 id) +{ + u32 len = 0; + + switch (id) { + case RTW_MBO_ATTR_NPREF_CH_RPT_ID: + { + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct npref_ch_rtp *prpt = &(prfctl->ch_rtp); + struct npref_ch* pch; + u32 i, attr_len, offset; + + for (i=0; i < prpt->nm_of_rpt; i++) { + pch = &prpt->ch_rpt[i]; + /*attr_len = ch list + op class + preference + reason */ + attr_len = pch->nm_of_ch + 3; + /* offset = id + len field + attr_len */ + offset = attr_len + 2; + len += offset; + } + } + break; + case RTW_MBO_ATTR_CELL_DATA_CAP_ID: + case RTW_MBO_ATTR_TRANS_REJ_ID: + len = 3; + break; + default: + break; + } + + return len; +} + +static void rtw_mbo_build_mbo_ie_hdr( + u8 **pframe, struct pkt_attrib *pattrib, u8 payload_len) +{ + u8 eid = RTW_MBO_EID; + u8 len = payload_len + 4; + + *pframe = rtw_mbo_set_1byte_ie(*pframe, &eid, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &len, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_4byte_ie(*pframe, wfa_mbo_oui, &(pattrib->pktlen)); +} + +void rtw_mbo_build_cell_data_cap_attr( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 attr_id = RTW_MBO_ATTR_CELL_DATA_CAP_ID; + u8 attr_len = 1; + u8 cell_data_con = rtw_mbo_cell_data_conn; + + /* used Cellular Data Capabilities from supplicant */ + if (!rtw_mbo_wifi_logo_test(padapter) && + pmlmepriv->pcell_data_cap_ie && pmlmepriv->cell_data_cap_len == 1) { + cell_data_con = *pmlmepriv->pcell_data_cap_ie; + RTW_MBO_INFO("%s : used Cellular Data Capabilities(%u) from supplicant!\n", + __func__, *pmlmepriv->pcell_data_cap_ie); + } + + *pframe = rtw_mbo_set_1byte_ie(*pframe, &attr_id, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &attr_len, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &cell_data_con, &(pattrib->pktlen)); +} + +static void rtw_mbo_update_cell_data_cap( + _adapter *padapter, u8 *pie, u32 ie_len) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 *mbo_attr; + u32 mbo_attrlen; + + if ((pie == NULL) || (ie_len == 0)) + return; + + mbo_attr = rtw_mbo_attrs_get(pie, ie_len, + RTW_MBO_ATTR_CELL_DATA_CAP_ID, &mbo_attrlen); + + if ((mbo_attr == NULL) || (mbo_attrlen == 0) ) { + RTW_INFO("MBO : Cellular Data Capabilities not found!\n"); + return; + } + + rtw_buf_update(&pmlmepriv->pcell_data_cap_ie, + &pmlmepriv->cell_data_cap_len, (mbo_attr + 2), mbo_attrlen); + RTW_MBO_DUMP("rtw_mbo_update_cell_data_cap : ", + pmlmepriv->pcell_data_cap_ie, pmlmepriv->cell_data_cap_len); +} + +void rtw_mbo_update_ie_data( + _adapter *padapter, u8 *pie, u32 ie_len) +{ + rtw_mbo_update_cell_data_cap(padapter, pie, ie_len); +} + +static u8 rtw_mbo_current_op_class_get(_adapter *padapter) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct p2p_channels *pch_list = &(prfctl->channel_list); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct p2p_reg_class *preg_class; + int class_idx, ch_idx; + u8 cur_op_class = 0; + + for(class_idx =0; class_idx < pch_list->reg_classes; class_idx++) { + preg_class = &pch_list->reg_class[class_idx]; + for (ch_idx = 0; ch_idx <= preg_class->channels; ch_idx++) { + if (pmlmeext->cur_channel == preg_class->channel[ch_idx]) { + cur_op_class = preg_class->reg_class; + RTW_MBO_INFO("%s : current ch : %d, op class : %d\n", + __func__, pmlmeext->cur_channel, cur_op_class); + break; + } + } + } + + return cur_op_class; +} + +static void rtw_mbo_supp_op_classes_get(_adapter *padapter, u8 *pclasses) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct p2p_channels *pch_list = &(prfctl->channel_list); + int class_idx; + + if (pclasses == NULL) + return; + + RTW_MBO_INFO("%s : support op class \n", __func__); + for(class_idx = 0; class_idx < pch_list->reg_classes; class_idx++) { + *(pclasses + class_idx) = pch_list->reg_class[class_idx].reg_class; + RTW_MBO_INFO("%u ,", *(pclasses + class_idx)); + } + + RTW_MBO_INFO("%s : \n", __func__); +} + +void rtw_mbo_build_supp_op_class_elem( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + u8 payload[32] = {0}; + u8 delimiter_130 = 130; /*0x82*/ + u8 reg_class_nm, len; + + if ((reg_class_nm = prfctl->channel_list.reg_classes) == 0) + return; + + payload[0] = rtw_mbo_current_op_class_get(padapter); + rtw_mbo_supp_op_classes_get(padapter, &payload[1]); + + /* IEEE 802.11 Std Current Operating Class Extension Sequence */ + payload[reg_class_nm + 1] = delimiter_130; + payload[reg_class_nm + 2] = 0x00; + + RTW_MBO_DUMP("op class :", payload, reg_class_nm); + + /* Current Operating Class field + Operating Class field + + OneHundredAndThirty Delimiter field */ + len = reg_class_nm + 3; + *pframe = rtw_set_ie(*pframe, EID_SupRegulatory, len , + payload, &(pattrib->pktlen)); +} + +static u8 rtw_mbo_construct_npref_ch_rpt_attr( + _adapter *padapter, u8 *pbuf, u32 buf_len, u32 *plen) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct npref_ch_rtp *prpt = &(prfctl->ch_rtp); + struct npref_ch* pch; + u32 attr_len, offset; + int i; + u8 *p = pbuf; + + if (prpt->nm_of_rpt == 0) { + *plen = 0; + return _FALSE; + } + + for (i=0; i < prpt->nm_of_rpt; i++) { + pch = &prpt->ch_rpt[i]; + /* attr_len = ch list + op class + preference + reason */ + attr_len = pch->nm_of_ch + 3; + /* offset = id + len field + attr_len */ + offset = attr_len + 2; + rtw_mbo_subfield_set(p, 0, RTW_MBO_ATTR_NPREF_CH_RPT_ID); + rtw_mbo_subfield_set(p, 1, attr_len); + rtw_mbo_subfield_set(p, 2, pch->op_class); + rtw_mbo_subfields_set(p, 3, pch->chs, pch->nm_of_ch); + rtw_mbo_subfield_set(p, (offset - 2), pch->preference); + rtw_mbo_subfield_set(p, (offset - 1), pch->reason); + p += offset; + *plen += offset; + + if (*plen >= buf_len) { + RTW_ERR("MBO : construct non-preferred channel report fail!\n"); + return _FALSE; + } + } + + return _TRUE; +} + +void rtw_mbo_build_npref_ch_rpt_attr( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct npref_ch_rtp *prpt = &(prfctl->ch_rtp); + u32 tmp_sz = 0, body_len = 0; + u8 *ptmp; + + tmp_sz = prpt->nm_of_rpt * sizeof(struct npref_ch); + ptmp = rtw_zmalloc(tmp_sz); + if (ptmp == NULL) + return; + + if (rtw_mbo_construct_npref_ch_rpt_attr(padapter, ptmp, tmp_sz, &body_len) == _FALSE) { + rtw_mfree(ptmp, tmp_sz); + return; + } + + RTW_MBO_DUMP("Non-preferred Channel Report :", ptmp, body_len); + *pframe = rtw_mbo_set_nbyte_ie(*pframe, body_len, ptmp, &(pattrib->pktlen)); + + rtw_mfree(ptmp, tmp_sz); +} + +void rtw_mbo_build_trans_reject_reason_attr( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib, u8 *pres) +{ + u8 attr_id = RTW_MBO_ATTR_TRANS_REJ_ID; + u8 attr_len = 1; + u32 len = 0; + + len = rtw_mbo_attr_sz_get(padapter, RTW_MBO_ATTR_TRANS_REJ_ID); + if ((len == 0) || (len > 3)) { + RTW_ERR("MBO : build Transition Rejection Reason attribute fail(len=%u)\n", len); + return; + } + + rtw_mbo_build_mbo_ie_hdr(pframe, pattrib, len); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &attr_id, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &attr_len, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, pres, &(pattrib->pktlen)); +} + +u8 rtw_mbo_disallowed_network(struct wlan_network *pnetwork) +{ + u8 *p, *attr_id, *res; + u32 attr_len = 0; + u8 disallow = _FALSE; + + if (pnetwork == NULL) + goto exit; + + p = rtw_mbo_attrs_get(pnetwork->network.IEs, + pnetwork->network.IELength, + RTW_MBO_ATTR_ASSOC_DISABLED_ID, + &attr_len); + + if (p == NULL) { + RTW_MBO_INFO("%s :Assoc Disallowed attribute not found!\n",__func__); + goto exit; + } + + RTW_MBO_DUMP("Association Disallowed attribute :",p , attr_len + 2); + RTW_INFO("MBO : block "MAC_FMT" assoc disallowed reason %d\n", + MAC_ARG(pnetwork->network.MacAddress), *(rtw_mbo_get_disallow_res(p))); + + disallow = _TRUE; +exit: + return disallow; +} + +void rtw_mbo_build_exented_cap( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib) +{ + u8 content[8] = { 0 }; + + rtw_wnm_set_ext_cap_btm(content, 1); + rtw_mbo_set_ext_cap_internw(content, 1); + *pframe = rtw_set_ie(*pframe, + EID_EXTCapability, + 8, + content, + &(pattrib->pktlen)); +} + +static void rtw_mbo_non_pref_chans_dump(struct npref_ch* pch) +{ + int i; + u8 buf[128] = {0}; + + for (i=0; i < pch->nm_of_ch; i++) + rtw_sprintf(buf, 128, "%s,%d", buf, pch->chs[i]); + + RTW_MBO_INFO("%s : op_class=%01x, ch=%s, preference=%d, reason=%d\n", + __func__, pch->op_class, buf, pch->preference, pch->reason); +} + +static u8 rtw_mbo_non_pref_chan_exist(struct npref_ch* pch, u8 ch) +{ + u32 i; + u8 found = _FALSE; + + for (i=0; i < pch->nm_of_ch; i++) { + if (pch->chs[i] == ch) { + found = _TRUE; + break; + } + } + + return found; +} + +static struct npref_ch* rtw_mbo_non_pref_chan_get( + _adapter *padapter, u8 op_class, u8 prefe, u8 res) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct npref_ch_rtp *prpt = &(prfctl->ch_rtp); + struct npref_ch* pch = NULL; + int i; + + if (prpt->nm_of_rpt == 0) + return pch; + + for (i=0; i < prpt->nm_of_rpt; i++) { + if ((prpt->ch_rpt[i].op_class == op_class) && + (prpt->ch_rpt[i].preference == prefe) && + (prpt->ch_rpt[i].reason == res)) { + pch = &prpt->ch_rpt[i]; + break; + } + } + + return pch; +} + +static void rtw_mbo_non_pref_chan_set( + struct npref_ch* pch, u8 op_class, u8 ch, u8 prefe, u8 res, u8 update) +{ + u32 offset = pch->nm_of_ch; + + if (update) { + if (rtw_mbo_non_pref_chan_exist(pch, ch) == _FALSE) { + pch->chs[offset] = ch; + pch->nm_of_ch++; + } + } else { + pch->op_class = op_class; + pch->chs[0] = ch; + pch->preference = prefe; + pch->reason = res; + pch->nm_of_ch = 1; + } +} + +static void rtw_mbo_non_pref_chans_update( + _adapter *padapter, u8 op_class, u8 ch, u8 prefe, u8 res) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct npref_ch_rtp *pch_rpt = &(prfctl->ch_rtp); + struct npref_ch* pch; + + if (pch_rpt->nm_of_rpt >= RTW_MBO_MAX_CH_RPT_NUM) { + RTW_ERR("MBO : %d non_pref_chan entries supported!", + RTW_MBO_MAX_CH_RPT_NUM); + return; + } + + if (pch_rpt->nm_of_rpt == 0) { + pch = &pch_rpt->ch_rpt[0]; + rtw_mbo_non_pref_chan_set(pch, op_class, ch, prefe, res, _FALSE); + pch_rpt->nm_of_rpt = 1; + return; + } + + pch = rtw_mbo_non_pref_chan_get(padapter, op_class, prefe, res); + if (pch == NULL) { + pch = &pch_rpt->ch_rpt[pch_rpt->nm_of_rpt]; + rtw_mbo_non_pref_chan_set(pch, op_class, ch, prefe, res, _FALSE); + pch_rpt->nm_of_rpt++; + } else + rtw_mbo_non_pref_chan_set(pch, op_class, ch, prefe, res, _TRUE); + + rtw_mbo_non_pref_chans_dump(pch); +} + +static void rtw_mbo_non_pref_chans_set( + _adapter *padapter, char *param, ssize_t sz) +{ + char *pnext; + u32 op_class, ch, prefe, res; + int i = 0; + + do { + pnext = strsep(¶m, " "); + if (pnext == NULL) + break; + + sscanf(pnext, "%d:%d:%d:%d", &op_class, &ch, &prefe, &res); + rtw_mbo_non_pref_chans_update(padapter, op_class, ch, prefe, res); + + if ((i++) > 10) { + RTW_ERR("MBO : overflow %d \n", i); + break; + } + + } while(param != '\0'); + +} + +static void rtw_mbo_non_pref_chans_del( + _adapter *padapter, char *param, ssize_t sz) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct npref_ch_rtp *prpt = &(prfctl->ch_rtp); + + RTW_INFO("%s : delete non_pref_chan %s\n", __func__, param); + _rtw_memset(prpt, 0, sizeof(struct npref_ch_rtp)); +} + +ssize_t rtw_mbo_proc_non_pref_chans_set( + struct file *pfile, const char __user *buffer, + size_t count, loff_t *pos, void *pdata) +{ + struct net_device *dev = pdata; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 tmp[128] = {0}; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + if (strncmp(tmp, "add", 3) == 0) + rtw_mbo_non_pref_chans_set(padapter, &tmp[4], (count - 4)); + else if (strncmp(tmp, "delete", 6) == 0) + rtw_mbo_non_pref_chans_del(padapter, &tmp[7], (count - 7)); + else { + RTW_ERR("MBO : Invalid format : echo [add|delete] :::\n"); + return -EFAULT; + } + } + +#ifdef CONFIG_RTW_WNM + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) && + check_fwstate(pmlmepriv, WIFI_STATION_STATE)) + rtw_wnm_issue_action(padapter, RTW_WLAN_ACTION_WNM_NOTIF_REQ, 0, 0); +#endif + + return count; +} + +int rtw_mbo_proc_non_pref_chans_get( + struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct npref_ch_rtp *prpt = &(prfctl->ch_rtp); + struct npref_ch* pch; + int i,j; + u8 buf[32] = {0}; + + RTW_PRINT_SEL(m, "op_class ch preference reason \n"); + RTW_PRINT_SEL(m, "=======================================================\n"); + + + if (prpt->nm_of_rpt == 0) { + RTW_PRINT_SEL(m, " empty table \n"); + return 0; + } + + for (i=0; i < prpt->nm_of_rpt; i++) { + pch = &prpt->ch_rpt[i]; + buf[0]='\0'; + for (j=0; j < pch->nm_of_ch; j++) { + if (j == 0) + rtw_sprintf(buf, 32, "%02u", pch->chs[j]); + else + rtw_sprintf(buf, 32, "%s,%02u", buf, pch->chs[j]); + } + + RTW_PRINT_SEL(m, " %04u %20s %02u %02u\n", + pch->op_class, buf, pch->preference, pch->reason); + } + + return 0; +} + +ssize_t rtw_mbo_proc_cell_data_set( + struct file *pfile, const char __user *buffer, + size_t count, loff_t *pos, void *pdata) +{ + struct net_device *dev = pdata; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + int mbo_cell_data = 0; + u8 tmp[8] = {0}; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) + return -EFAULT; + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%d", &mbo_cell_data); + if (num == 1) { + rtw_mbo_cell_data_conn = mbo_cell_data; + #ifdef CONFIG_RTW_WNM + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) && + check_fwstate(pmlmepriv, WIFI_STATION_STATE)) + rtw_wnm_issue_action(padapter, RTW_WLAN_ACTION_WNM_NOTIF_REQ, 0, 0); + #endif + } + } + + + return count; +} + +int rtw_mbo_proc_cell_data_get( + struct seq_file *m, void *v) +{ +#if 0 + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); +#endif + + RTW_PRINT_SEL(m, "Cellular Data Connectivity : %d\n", rtw_mbo_cell_data_conn); + return 0; +} + +static void rtw_mbo_non_pref_chan_subelem_parsing( + _adapter *padapter, u8 *subelem, size_t subelem_len) +{ + u8 *pnon_pref_chans; + u32 non_pref_chan_offset, op_subelem_len; + u32 oui_offset = 3; + /* wpa_supplicant don't apped OUI Type */ + u32 oui_type_offset = 0; + + RTW_MBO_DUMP("Non-preferred Channel subelem : ", subelem , subelem_len); + + /* Subelem : + Vendor Specific | Length | WFA OUI | OUI Type | MBO Attributes */ + non_pref_chan_offset = 2 + oui_offset + oui_type_offset; + pnon_pref_chans = subelem + non_pref_chan_offset; + op_subelem_len = subelem_len - non_pref_chan_offset; + + /* wpa_supplicant don't indicate non_pref_chan length, + so we cannot get how many non_pref_chan in a wnm notification */ + RTW_MBO_DUMP("Non-preferred Channel : ", pnon_pref_chans, op_subelem_len); +} + +void rtw_mbo_wnm_notification_parsing( + _adapter *padapter, const u8 *pdata, size_t data_len) +{ + u8 *paction; + u8 category, action, dialog, type; + u32 len; + + if ((pdata == NULL) || (data_len == 0)) + return; + + RTW_MBO_DUMP("WNM notification data : ", pdata, data_len); + paction = (u8 *)pdata + sizeof(struct rtw_ieee80211_hdr_3addr); + category = paction[0]; + action = paction[1]; + dialog = paction[2]; + type = paction[3]; + + if ((action == RTW_WLAN_ACTION_WNM_NOTIF_REQ) && + (type == WLAN_EID_VENDOR_SPECIFIC)) { + rtw_mbo_non_pref_chan_subelem_parsing(padapter, &paction[4], + (data_len - sizeof(struct rtw_ieee80211_hdr_3addr))); + } + +} + +void rtw_mbo_build_wnm_notification( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct npref_ch_rtp *prpt = &(prfctl->ch_rtp); + struct npref_ch* pch; + u8 subelem_id = WLAN_EID_VENDOR_SPECIFIC; + u8 non_pref_ch_oui[] = {0x50, 0x6F, 0x9A, 0x2}; + u8 cell_data_cap_oui[] = {0x50, 0x6F, 0x9A, 0x3}; + u8 cell_data_con = rtw_mbo_cell_data_conn; + u8 len, cell_data_con_len = 0, *pcont = *pframe; + int i; + + if (rtw_mbo_cell_data_conn > 0) { + len = 0x5; + *pframe = rtw_mbo_set_1byte_ie(*pframe, &subelem_id, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &len, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_4byte_ie(*pframe, cell_data_cap_oui, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &cell_data_con, &(pattrib->pktlen)); + RTW_MBO_INFO("%s : Cellular Data Capabilities subelemen\n", __func__); + RTW_MBO_DUMP(":", pcont, len + 2); + pcont += len + 2 ; + } + + if (prpt->nm_of_rpt == 0) { + len = 0x4; + *pframe = rtw_mbo_set_1byte_ie(*pframe, &subelem_id, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &len, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_4byte_ie(*pframe, non_pref_ch_oui, &(pattrib->pktlen)); + RTW_MBO_INFO("%s :Non-preferred Channel Report subelement without data\n", __func__); + return; + } + + for (i=0; i < prpt->nm_of_rpt; i++) { + pch = &prpt->ch_rpt[i]; + /* OUI(3B) + OUT-type(1B) + op-class(1B) + ch list(nB) + + Preference(1B) + reason(1B) */ + len = pch->nm_of_ch + 7; + *pframe = rtw_mbo_set_1byte_ie(*pframe, &subelem_id, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &len, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_4byte_ie(*pframe, non_pref_ch_oui, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &pch->op_class, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_nbyte_ie(*pframe, pch->nm_of_ch, pch->chs, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &pch->preference, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &pch->reason, &(pattrib->pktlen)); + RTW_MBO_INFO("%s :Non-preferred Channel Report subelement\n", __func__); + RTW_MBO_DUMP(":", pcont, len); + pcont = *pframe; + } +} + +void rtw_mbo_build_probe_req_ies( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib) +{ + u32 len =0; + + rtw_mbo_build_exented_cap(padapter, pframe, pattrib); + + len = rtw_mbo_attr_sz_get(padapter, RTW_MBO_ATTR_CELL_DATA_CAP_ID); + if ((len == 0) || (len > 3)) { + RTW_ERR("MBO : build Cellular Data Capabilities attribute fail(len=%u)\n", len); + return; + } + + rtw_mbo_build_mbo_ie_hdr(pframe, pattrib, len); + rtw_mbo_build_cell_data_cap_attr(padapter, pframe, pattrib); +} + +void rtw_mbo_build_assoc_req_ies( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib) +{ + u32 len = 0; + + rtw_mbo_build_supp_op_class_elem(padapter, pframe, pattrib); + + len += rtw_mbo_attr_sz_get(padapter, RTW_MBO_ATTR_CELL_DATA_CAP_ID); + len += rtw_mbo_attr_sz_get(padapter, RTW_MBO_ATTR_NPREF_CH_RPT_ID); + if ((len == 0)|| (len < 3)) { + RTW_ERR("MBO : build assoc MBO IE fail(len=%u)\n", len); + return; + } + + rtw_mbo_build_mbo_ie_hdr(pframe, pattrib, len); + rtw_mbo_build_cell_data_cap_attr(padapter, pframe, pattrib); + rtw_mbo_build_npref_ch_rpt_attr(padapter, pframe, pattrib); +} + +#endif /* CONFIG_RTW_MBO */ diff --git a/core/rtw_mem.c b/core/rtw_mem.c index d9f5652..d42a4fb 100644 --- a/core/rtw_mem.c +++ b/core/rtw_mem.c @@ -21,6 +21,49 @@ MODULE_DESCRIPTION("Realtek Wireless Lan Driver"); MODULE_AUTHOR("Realtek Semiconductor Corp."); MODULE_VERSION("DRIVERVERSION"); +/* for MAX_RECVBUF_SZ */ +#if defined(CONFIG_RTL8188E) +#include +#elif defined(CONFIG_RTL8188F) +#include +#elif defined(CONFIG_RTL8188GTV) +#include +#elif defined(CONFIG_RTL8710B) +#include +#elif defined(CONFIG_RTL8192E) +#include +#elif defined(CONFIG_RTL8192F) +#include +#elif defined(CONFIG_RTL8723B) +#include +#elif defined(CONFIG_RTL8703B) +#include +#elif defined(CONFIG_RTL8723D) +#include +#elif defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) +#include +#elif defined(CONFIG_RTL8822B) +#include +#elif defined(CONFIG_RTL8822C) +#include +#elif defined(CONFIG_RTL8814A) +#include +#elif defined(CONFIG_RTL8814B) +#include +#endif + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +#define MAX_RTKM_RECVBUF_SZ MAX_RECVBUF_SZ +#define MAX_RTKM_NR_PREALLOC_RECV_SKB NR_RECVBUFF +#else /* !CONFIG_SDIO_HCI */ +#ifdef CONFIG_PLATFORM_MSTAR_HIGH + #define MAX_RTKM_RECVBUF_SZ (31744) /* 31k */ +#else + #define MAX_RTKM_RECVBUF_SZ (15360) /* 15k */ +#endif /* CONFIG_PLATFORM_MSTAR_HIGH */ +#define MAX_RTKM_NR_PREALLOC_RECV_SKB 16 +#endif /* !CONFIG_SDIO_HCI */ + struct sk_buff_head rtk_skb_mem_q; struct u8 *rtk_buf_mem[NR_RECVBUFF]; diff --git a/core/rtw_mi.c b/core/rtw_mi.c index 0f35a9f..099cd36 100644 --- a/core/rtw_mi.c +++ b/core/rtw_mi.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2017 Realtek Corporation. + * Copyright(c) 2007 - 2019 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -20,11 +20,15 @@ void rtw_mi_update_union_chan_inf(_adapter *adapter, u8 ch, u8 offset , u8 bw) { struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); - struct mi_state *iface_state = &dvobj->iface_state; - iface_state->union_ch = ch; - iface_state->union_bw = bw; - iface_state->union_offset = offset; + if (!ch) { + dvobj->union_ch_bak = dvobj->union_ch; + dvobj->union_bw_bak = dvobj->union_bw; + dvobj->union_offset_bak = dvobj->union_offset; + } + dvobj->union_ch = ch; + dvobj->union_bw = bw; + dvobj->union_offset = offset; } #ifdef DBG_IFACE_STATUS @@ -131,7 +135,7 @@ int rtw_mi_get_ch_setting_union_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp, u8 mlmeext = &iface->mlmeextpriv; - if (!check_fwstate(&iface->mlmepriv, _FW_LINKED | _FW_UNDER_LINKING)) + if (!check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE | WIFI_UNDER_LINKING)) continue; if (check_fwstate(&iface->mlmepriv, WIFI_OP_CH_SWITCHING)) @@ -183,7 +187,6 @@ inline int rtw_mi_get_ch_setting_union_no_self(_adapter *adapter, u8 *ch, u8 *bw return rtw_mi_get_ch_setting_union_by_ifbmp(adapter_to_dvobj(adapter), 0xFF & ~BIT(adapter->iface_id), ch, bw, offset); } -/* For now, not return union_ch/bw/offset */ void rtw_mi_status_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp, struct mi_state *mstate) { _adapter *iface; @@ -198,7 +201,7 @@ void rtw_mi_status_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp, struct mi_state if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) { MSTATE_STA_NUM(mstate)++; - if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) { + if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) { MSTATE_STA_LD_NUM(mstate)++; #ifdef CONFIG_TDLS @@ -210,12 +213,12 @@ void rtw_mi_status_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp, struct mi_state MSTATE_P2P_GC_NUM(mstate)++; #endif } - if (check_fwstate(&iface->mlmepriv, _FW_UNDER_LINKING) == _TRUE) + if (check_fwstate(&iface->mlmepriv, WIFI_UNDER_LINKING) == _TRUE) MSTATE_STA_LG_NUM(mstate)++; #ifdef CONFIG_AP_MODE } else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) { - if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) { + if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) { MSTATE_AP_NUM(mstate)++; if (iface->stapriv.asoc_sta_count > 2) MSTATE_AP_LD_NUM(mstate)++; @@ -228,7 +231,7 @@ void rtw_mi_status_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp, struct mi_state #endif } else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE - && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE + && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE ) { MSTATE_ADHOC_NUM(mstate)++; if (iface->stapriv.asoc_sta_count > 2) @@ -236,7 +239,7 @@ void rtw_mi_status_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp, struct mi_state #ifdef CONFIG_RTW_MESH } else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE - && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE + && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE ) { MSTATE_MESH_NUM(mstate)++; if (iface->stapriv.asoc_sta_count > 2) @@ -248,7 +251,7 @@ void rtw_mi_status_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp, struct mi_state if (check_fwstate(&iface->mlmepriv, WIFI_UNDER_WPS) == _TRUE) MSTATE_WPS_NUM(mstate)++; - if (check_fwstate(&iface->mlmepriv, WIFI_SITE_MONITOR) == _TRUE) { + if (check_fwstate(&iface->mlmepriv, WIFI_UNDER_SURVEY) == _TRUE) { MSTATE_SCAN_NUM(mstate)++; if (mlmeext_scan_state(&iface->mlmeextpriv) != SCAN_DISABLE @@ -259,10 +262,10 @@ void rtw_mi_status_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp, struct mi_state #ifdef CONFIG_IOCTL_CFG80211 if (rtw_cfg80211_get_is_mgmt_tx(iface)) MSTATE_MGMT_TX_NUM(mstate)++; - #ifdef CONFIG_P2P + if (rtw_cfg80211_get_is_roch(iface) == _TRUE) MSTATE_ROCH_NUM(mstate)++; - #endif + #endif /* CONFIG_IOCTL_CFG80211 */ #ifdef CONFIG_P2P if (MLME_IS_PD(iface)) @@ -286,7 +289,6 @@ inline void rtw_mi_status_no_others(_adapter *adapter, struct mi_state *mstate) return rtw_mi_status_by_ifbmp(adapter_to_dvobj(adapter), BIT(adapter->iface_id), mstate); } -/* For now, not handle union_ch/bw/offset */ inline void rtw_mi_status_merge(struct mi_state *d, struct mi_state *a) { d->sta_num += a->sta_num; @@ -367,7 +369,6 @@ inline void rtw_mi_update_iface_status(struct mlme_priv *pmlmepriv, sint state) struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct mi_state *iface_state = &dvobj->iface_state; struct mi_state tmp_mstate; - u8 u_ch, u_offset, u_bw; if (state == WIFI_MONITOR_STATE || state == 0xFFFFFFFF @@ -380,16 +381,6 @@ inline void rtw_mi_update_iface_status(struct mlme_priv *pmlmepriv, sint state) rtw_mi_status(adapter, &tmp_mstate); _rtw_memcpy(iface_state, &tmp_mstate, sizeof(struct mi_state)); - if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset)) - rtw_mi_update_union_chan_inf(adapter , u_ch, u_offset , u_bw); - else { - if (0) { - dump_adapters_status(RTW_DBGDUMP , dvobj); - RTW_INFO("%s-[ERROR] cannot get union channel\n", __func__); - rtw_warn_on(1); - } - } - #ifdef DBG_IFACE_STATUS DBG_IFACE_STATUS_DUMP(adapter); #endif @@ -407,7 +398,7 @@ u8 rtw_mi_check_status(_adapter *adapter, u8 type) switch (type) { case MI_LINKED: - if (MSTATE_STA_LD_NUM(iface_state) || MSTATE_AP_NUM(iface_state) || MSTATE_ADHOC_NUM(iface_state) || MSTATE_MESH_NUM(iface_state)) /*check_fwstate(&iface->mlmepriv, _FW_LINKED)*/ + if (MSTATE_STA_LD_NUM(iface_state) || MSTATE_AP_NUM(iface_state) || MSTATE_ADHOC_NUM(iface_state) || MSTATE_MESH_NUM(iface_state)) /*check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE)*/ ret = _TRUE; break; case MI_ASSOC: @@ -821,10 +812,11 @@ void rtw_mi_buddy_set_scan_deny(_adapter *adapter, u32 ms) } #endif /*CONFIG_SET_SCAN_DENY_TIMER*/ +#ifdef CONFIG_AP_MODE static u8 _rtw_mi_beacon_update(_adapter *padapter, void *data) { if (!MLME_IS_STA(padapter) - && check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _TRUE) { + && check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE) { RTW_INFO(ADPT_FMT" - update_beacon\n", ADPT_ARG(padapter)); update_beacon(padapter, 0xFF, NULL, _TRUE, 0); } @@ -840,23 +832,28 @@ void rtw_mi_buddy_beacon_update(_adapter *padapter) { _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_beacon_update); } +#endif /* CONFIG_AP_MODE */ -static u8 _rtw_mi_hal_dump_macaddr(_adapter *padapter, void *data) +#ifndef CONFIG_MI_WITH_MBSSID_CAM +static u8 _rtw_mi_hal_dump_macaddr(_adapter *padapter, void *sel) { u8 mac_addr[ETH_ALEN] = {0}; rtw_hal_get_hwreg(padapter, HW_VAR_MAC_ADDR, mac_addr); - RTW_INFO(ADPT_FMT"MAC Address ="MAC_FMT"\n", ADPT_ARG(padapter), MAC_ARG(mac_addr)); + RTW_PRINT_SEL(sel, ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", + ADPT_ARG(padapter), padapter->hw_port, MAC_ARG(mac_addr)); + return _TRUE; } -void rtw_mi_hal_dump_macaddr(_adapter *padapter) +void rtw_mi_hal_dump_macaddr(void *sel, _adapter *padapter) { - _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_hal_dump_macaddr); + _rtw_mi_process(padapter, _FALSE, sel, _rtw_mi_hal_dump_macaddr); } -void rtw_mi_buddy_hal_dump_macaddr(_adapter *padapter) +void rtw_mi_buddy_hal_dump_macaddr(void *sel, _adapter *padapter) { - _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_hal_dump_macaddr); + _rtw_mi_process(padapter, _TRUE, sel, _rtw_mi_hal_dump_macaddr); } +#endif #ifdef CONFIG_PCI_HCI static u8 _rtw_mi_xmit_tasklet_schedule(_adapter *padapter, void *data) @@ -879,36 +876,16 @@ void rtw_mi_buddy_xmit_tasklet_schedule(_adapter *padapter) u8 _rtw_mi_busy_traffic_check(_adapter *padapter, void *data) { - u32 passtime; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - bool check_sc_interval = *(bool *)data; - - if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE) { - if (check_sc_interval) { - /* Miracast can't do AP scan*/ - passtime = rtw_get_passing_time_ms(pmlmepriv->lastscantime); - if (passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD) { - RTW_INFO(ADPT_FMT" bBusyTraffic == _TRUE\n", ADPT_ARG(padapter)); - return _TRUE; - } - } else - return _TRUE; - } - - return _FALSE; + return padapter->mlmepriv.LinkDetectInfo.bBusyTraffic; } -u8 rtw_mi_busy_traffic_check(_adapter *padapter, bool check_sc_interval) +u8 rtw_mi_busy_traffic_check(_adapter *padapter) { - bool in_data = check_sc_interval; - - return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_busy_traffic_check); + return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_busy_traffic_check); } -u8 rtw_mi_buddy_busy_traffic_check(_adapter *padapter, bool check_sc_interval) +u8 rtw_mi_buddy_busy_traffic_check(_adapter *padapter) { - bool in_data = check_sc_interval; - - return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_busy_traffic_check); + return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_busy_traffic_check); } static u8 _rtw_mi_check_mlmeinfo_state(_adapter *padapter, void *data) { @@ -948,21 +925,21 @@ static void rtw_dbg_dump_fwstate(_adapter *padapter, sint state) RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf); } - if (state & _FW_LINKED) { + if (state & WIFI_ASOC_STATE) { _rtw_memset(buf, 0, 32); - sprintf(buf, "_FW_LINKED"); + sprintf(buf, "WIFI_ASOC_STATE"); RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf); } - if (state & _FW_UNDER_LINKING) { + if (state & WIFI_UNDER_LINKING) { _rtw_memset(buf, 0, 32); - sprintf(buf, "_FW_UNDER_LINKING"); + sprintf(buf, "WIFI_UNDER_LINKING"); RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf); } - if (state & _FW_UNDER_SURVEY) { + if (state & WIFI_UNDER_SURVEY) { _rtw_memset(buf, 0, 32); - sprintf(buf, "_FW_UNDER_SURVEY"); + sprintf(buf, "WIFI_UNDER_SURVEY"); RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf); } } @@ -1172,7 +1149,7 @@ u8 rtw_mi_sreset_adapter_hdl(_adapter *padapter, u8 bstart) return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_sreset_adapter_hdl); } -#if defined(DBG_CONFIG_ERROR_RESET) && defined(CONFIG_CONCURRENT_MODE) +#if defined(CONFIG_AP_MODE) && defined(DBG_CONFIG_ERROR_RESET) && defined(CONFIG_CONCURRENT_MODE) void rtw_mi_ap_info_restore(_adapter *adapter) { int i; @@ -1200,6 +1177,8 @@ u8 rtw_mi_buddy_sreset_adapter_hdl(_adapter *padapter, u8 bstart) return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_sreset_adapter_hdl); } + +#ifdef CONFIG_AP_MODE static u8 _rtw_mi_tx_beacon_hdl(_adapter *adapter, void *data) { if ((MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) @@ -1241,6 +1220,7 @@ u8 rtw_mi_buddy_set_tx_beacon_cmd(_adapter *padapter) { return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_set_tx_beacon_cmd); } +#endif /* CONFIG_AP_MODE */ #ifdef CONFIG_P2P static u8 _rtw_mi_p2p_chk_state(_adapter *adapter, void *data) diff --git a/core/rtw_mlme.c b/core/rtw_mlme.c index ec0c68a..024c144 100644 --- a/core/rtw_mlme.c +++ b/core/rtw_mlme.c @@ -15,6 +15,9 @@ #define _RTW_MLME_C_ #include +#ifdef CONFIG_PLATFORM_CMAP_INTFS +#include "../os_dep/linux/custom_multiap_intfs/custom_multiap_intfs.h" +#endif extern void indicate_wx_scan_complete_event(_adapter *padapter); extern u8 rtw_do_join(_adapter *padapter); @@ -45,6 +48,9 @@ sint _rtw_init_mlme_priv(_adapter *padapter) struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); sint res = _SUCCESS; +#ifdef CONFIG_RTW_MULTI_AP + struct unassoc_sta_info *unassoc_sta; +#endif /* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */ @@ -100,6 +106,35 @@ sint _rtw_init_mlme_priv(_adapter *padapter) pnetwork++; } +#ifdef CONFIG_RTW_MULTI_AP + if (is_primary_adapter(padapter)) { + _rtw_init_queue(&(pmlmepriv->free_unassoc_sta_queue)); + _rtw_init_queue(&(pmlmepriv->unassoc_sta_queue)); + for (i = 0; i < UNASOC_STA_SRC_NUM; i++) + pmlmepriv->unassoc_sta_mode_of_stype[i] = padapter->registrypriv.unassoc_sta_mode_of_stype[i]; + if (padapter->registrypriv.max_unassoc_sta_cnt != 0) + pmlmepriv->max_unassoc_sta_cnt = padapter->registrypriv.max_unassoc_sta_cnt; + else if (rfctl->max_chan_nums <= MAX_CHANNEL_NUM_2G) + pmlmepriv->max_unassoc_sta_cnt = MAX_UNASSOC_STA_CNT; + else + pmlmepriv->max_unassoc_sta_cnt = MAX_UNASSOC_STA_CNT * 2; + pbuf = rtw_zvmalloc(pmlmepriv->max_unassoc_sta_cnt * (sizeof(struct unassoc_sta_info))); + if (pbuf == NULL) { + res = _FAIL; + goto exit; + } + pmlmepriv->free_unassoc_sta_buf = pbuf; + unassoc_sta = (struct unassoc_sta_info *) pbuf; + for (i = 0; i < pmlmepriv->max_unassoc_sta_cnt; i++) { + _rtw_init_listhead(&(unassoc_sta->list)); + rtw_list_insert_tail(&(unassoc_sta->list), &(pmlmepriv->free_unassoc_sta_queue.queue)); + unassoc_sta++; + } + } +#ifdef CONFIG_PLATFORM_CMAP_INTFS + rtw_init_timer(&pmlmepriv->cmap_unassoc_sta_timer, padapter, cmap_unassoc_sta_report_info_timer, padapter); +#endif +#endif /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ rtw_clear_scan_deny(padapter); @@ -113,16 +148,8 @@ sint _rtw_init_mlme_priv(_adapter *padapter) #define RTW_ROAM_RSSI_DIFF_TH 10 #define RTW_ROAM_SCAN_INTERVAL (5) /* 5*(2 second)*/ #define RTW_ROAM_RSSI_THRESHOLD 70 - - pmlmepriv->roam_flags = 0 - | RTW_ROAM_ON_EXPIRED -#ifdef CONFIG_LAYER2_ROAMING_RESUME - | RTW_ROAM_ON_RESUME -#endif -#ifdef CONFIG_LAYER2_ROAMING_ACTIVE - | RTW_ROAM_ACTIVE -#endif - ; +#define RTW_ROAM_DICONNECT_DELAY 20 + pmlmepriv->roam_flags = CONFIG_ROAMING_FLAG; pmlmepriv->roam_scanr_exp_ms = RTW_ROAM_SCAN_RESULT_EXP_MS; pmlmepriv->roam_rssi_diff_th = RTW_ROAM_RSSI_DIFF_TH; @@ -141,6 +168,10 @@ sint _rtw_init_mlme_priv(_adapter *padapter) pmlmepriv->ch_cnt = 0; #endif #endif + + pmlmepriv->defs_lmt_sta = 2; + pmlmepriv->defs_lmt_time = 5; + rtw_init_mlme_timer(padapter); exit: @@ -155,46 +186,46 @@ void rtw_mfree_mlme_priv_lock(struct mlme_priv *pmlmepriv) _rtw_spinlock_free(&pmlmepriv->lock); _rtw_spinlock_free(&(pmlmepriv->free_bss_pool.lock)); _rtw_spinlock_free(&(pmlmepriv->scanned_queue.lock)); -} - -static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen) -{ - if (*ppie) { - rtw_mfree(*ppie, *plen); - *plen = 0; - *ppie = NULL; +#ifdef CONFIG_RTW_MULTI_AP + if (is_primary_adapter(mlme_to_adapter(pmlmepriv))) { + _rtw_spinlock_free(&(pmlmepriv->unassoc_sta_queue.lock)); + _rtw_spinlock_free(&(pmlmepriv->free_unassoc_sta_queue.lock)); } +#endif } void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv) { -#if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len); rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len); - rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len); +#if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + rtw_buf_free(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len); + rtw_buf_free(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len); + rtw_buf_free(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len); + rtw_buf_free(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_resp_ie, &pmlmepriv->p2p_assoc_resp_ie_len); + rtw_buf_free(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len); + rtw_buf_free(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len); + rtw_buf_free(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len); + rtw_buf_free(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len); + rtw_buf_free(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len); + rtw_buf_free(&pmlmepriv->p2p_assoc_resp_ie, &pmlmepriv->p2p_assoc_resp_ie_len); #endif #if defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211) - rtw_free_mlme_ie_data(&pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->wfd_go_probe_resp_ie, &pmlmepriv->wfd_go_probe_resp_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->wfd_assoc_resp_ie, &pmlmepriv->wfd_assoc_resp_ie_len); + rtw_buf_free(&pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len); + rtw_buf_free(&pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len); + rtw_buf_free(&pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len); + rtw_buf_free(&pmlmepriv->wfd_go_probe_resp_ie, &pmlmepriv->wfd_go_probe_resp_ie_len); + rtw_buf_free(&pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len); + rtw_buf_free(&pmlmepriv->wfd_assoc_resp_ie, &pmlmepriv->wfd_assoc_resp_ie_len); #endif #ifdef CONFIG_RTW_80211R - rtw_free_mlme_ie_data(&pmlmepriv->auth_rsp, &pmlmepriv->auth_rsp_len); + rtw_buf_free(&pmlmepriv->auth_rsp, &pmlmepriv->auth_rsp_len); +#endif +#ifdef CONFIG_RTW_MBO + rtw_buf_free(&pmlmepriv->pcell_data_cap_ie, &pmlmepriv->cell_data_cap_len); #endif } @@ -309,6 +340,15 @@ void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) if (pmlmepriv->free_bss_buf) rtw_vmfree(pmlmepriv->free_bss_buf, pmlmepriv->max_bss_cnt * sizeof(struct wlan_network)); +#ifdef CONFIG_RTW_MULTI_AP + if (is_primary_adapter(adapter)) { + if (pmlmepriv->free_unassoc_sta_buf) + rtw_vmfree(pmlmepriv->free_unassoc_sta_buf, pmlmepriv->max_unassoc_sta_cnt * sizeof(struct unassoc_sta_info)); + } +#ifdef CONFIG_PLATFORM_CMAP_INTFS + _cancel_timer_ex(&pmlmepriv->cmap_unassoc_sta_timer); +#endif +#endif } exit: return; @@ -509,7 +549,7 @@ sint rtw_if_up(_adapter *padapter) sint res; if (RTW_CANNOT_RUN(padapter) || - (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _FALSE)) { + (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _FALSE)) { res = _FALSE; } else res = _TRUE; @@ -831,7 +871,7 @@ void update_network(WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src, #endif /* The rule below is 1/5 for sample value, 4/5 for history value */ - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src, 0)) { + if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) && is_same_network(&(padapter->mlmepriv.cur_network.network), src, 0)) { /* Take the recvpriv's value for the connected AP*/ ss_final = padapter->recvpriv.signal_strength; sq_final = padapter->recvpriv.signal_qual; @@ -859,7 +899,9 @@ void update_network(WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src, dst->Reserved[1] = src->Reserved[1]; _rtw_memcpy((u8 *)dst, (u8 *)src, get_WLAN_BSSID_EX_sz(src)); } - +#ifdef CONFIG_LAYER2_ROAMING + dst->tsf = src->tsf; +#endif dst->PhyInfo.SignalStrength = ss_final; dst->PhyInfo.SignalQuality = sq_final; dst->Rssi = rssi_final; @@ -874,7 +916,7 @@ void update_network(WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src, #if 0 /* old codes, may be useful one day... * RTW_INFO("update_network: rssi=0x%lx dst->Rssi=%d ,dst->Rssi=0x%lx , src->Rssi=0x%lx",(dst->Rssi+src->Rssi)/2,dst->Rssi,dst->Rssi,src->Rssi); */ - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src)) { + if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) && is_same_network(&(padapter->mlmepriv.cur_network.network), src)) { /* RTW_INFO("b:ssid=%s update_network: src->rssi=0x%d padapter->recvpriv.ui_rssi=%d\n",src->Ssid.Ssid,src->Rssi,padapter->recvpriv.signal); */ if (padapter->recvpriv.signal_qual_data.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX) { @@ -916,7 +958,7 @@ static void update_current_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork) &(pmlmepriv->cur_network.network), &(pmlmepriv->cur_network.network)); - if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) && (is_same_network(&(pmlmepriv->cur_network.network), pnetwork, 0))) { + if ((check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) && (is_same_network(&(pmlmepriv->cur_network.network), pnetwork, 0))) { /* if(pmlmepriv->cur_network.network.IELength<= pnetwork->IELength) */ { @@ -1049,7 +1091,9 @@ bool rtw_update_scanned_network(_adapter *adapter, WLAN_BSSID_EX *target) pnetwork->acnode_stime = 0; pnetwork->acnode_notify_etime = 0; #endif - +#ifdef CONFIG_LAYER2_ROAMING + pnetwork->network.tsf = target->tsf; +#endif pnetwork->network_type = 0; pnetwork->aid = 0; pnetwork->join_res = 0; @@ -1151,7 +1195,7 @@ unlock_scan_queue: #ifdef CONFIG_RTW_MESH if (pnetwork && MLME_IS_MESH(adapter) && check_fwstate(pmlmepriv, WIFI_ASOC_STATE) - && !check_fwstate(pmlmepriv, WIFI_SITE_MONITOR) + && !check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) ) rtw_chk_candidate_peer_notify(adapter, pnetwork); #endif @@ -1171,10 +1215,8 @@ void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork) if (adapter->registrypriv.wifi_spec == 0) rtw_bss_ex_del_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO); #endif - if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST)) rtw_bss_ex_del_wfd_ie(pnetwork); - /* Wi-Fi driver will update the current network if the scan result of the connected AP be updated by scan. */ update_ie = rtw_update_scanned_network(adapter, pnetwork); @@ -1185,6 +1227,455 @@ void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork) } +#ifdef CONFIG_RTW_MULTI_AP +void rtw_unassoc_sta_set_mode(_adapter *adapter, u8 stype, u8 mode) +{ + if (stype >= UNASOC_STA_SRC_NUM + || mode >= UNASOC_STA_MODE_NUM) + return; + + adapter = GET_PRIMARY_ADAPTER(adapter); + + if (adapter->mlmepriv.unassoc_sta_mode_of_stype[stype] == mode) + return; + + adapter->mlmepriv.unassoc_sta_mode_of_stype[stype] = mode; + + rtw_run_in_thread_cmd_wait(adapter, ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), adapter, 2000); +} + +bool rtw_unassoc_sta_src_chk(_adapter *adapter, u8 stype) +{ + if (stype >= UNASOC_STA_SRC_NUM) + return 0; + + adapter = GET_PRIMARY_ADAPTER(adapter); + + return adapter->mlmepriv.unassoc_sta_mode_of_stype[stype] == UNASOC_STA_MODE_ALL + || (adapter->mlmepriv.unassoc_sta_mode_of_stype[stype] == UNASOC_STA_MODE_INTERESTED + && adapter->mlmepriv.interested_unassoc_sta_cnt) + ; +} + +const char *unasoc_sta_src_str[] = { + "BMC", + "NMY_UC", +}; + +const char *unasoc_sta_mode_str[] = { + "DISABLED", + "INTERESTED", + "ALL", +}; + +void dump_unassoc_sta(void *sel, _adapter *adapter) +{ + struct mlme_priv *mlmepriv; + _queue *queue; + _list *list, *head; + struct unassoc_sta_info **unassoc_sta_arr; + struct unassoc_sta_info *unassoc_sta; + u16 i, unassoc_sta_cnt = 0; + + adapter = GET_PRIMARY_ADAPTER(adapter); + mlmepriv = &(adapter->mlmepriv); + queue = &(mlmepriv->unassoc_sta_queue); + + for (i = 0; i < UNASOC_STA_SRC_NUM; i++) { + RTW_PRINT_SEL(sel, "[%u]%-6s:%u(%s)\n", i, unasoc_sta_src_str[i] + , mlmepriv->unassoc_sta_mode_of_stype[i], unasoc_sta_mode_str[mlmepriv->unassoc_sta_mode_of_stype[i]]); + } + RTW_PRINT_SEL(sel, "interested_unassoc_sta_cnt:%u\n", mlmepriv->interested_unassoc_sta_cnt); + + unassoc_sta_arr = rtw_zvmalloc(mlmepriv->max_unassoc_sta_cnt * sizeof(struct unassoc_sta_info *)); + if (!unassoc_sta_arr) + return; + + enter_critical_bh(&queue->lock); + head = get_list_head(queue); + list = get_next(head); + + while (rtw_end_of_queue_search(head, list) == _FALSE) { + unassoc_sta = LIST_CONTAINOR(list, struct unassoc_sta_info, list); + list = get_next(list); + + unassoc_sta_arr[unassoc_sta_cnt++] = unassoc_sta; + } + + exit_critical_bh(&queue->lock); + + RTW_PRINT_SEL(sel, " %17s %18s %6s\n", "mac_addr", "measure_delta_time", "rssi"); + + for (i = 0; i < unassoc_sta_cnt; i++) { + u8 rcpi; + s8 rx_power; + u32 measure_delta_time; + + unassoc_sta = unassoc_sta_arr[i]; + + measure_delta_time = rtw_systime_to_ms(rtw_get_current_time() - unassoc_sta->time); + + RTW_PRINT_SEL(sel, "%c "MAC_FMT" %18u %6d\n" + , unassoc_sta->interested ? '*' : ' ' + , MAC_ARG(unassoc_sta->addr), measure_delta_time, unassoc_sta->recv_signal_power); + } + + rtw_vmfree(unassoc_sta_arr, mlmepriv->max_unassoc_sta_cnt * sizeof(struct unassoc_sta_info *)); +} + +static void del_unassoc_sta(struct mlme_priv *mlmepriv, struct unassoc_sta_info *unassoc_sta) +{ + _irqL irqL; + _queue *free_queue = &(mlmepriv->free_unassoc_sta_queue); + + if (unassoc_sta->interested) + mlmepriv->interested_unassoc_sta_cnt--; + if (mlmepriv->interested_unassoc_sta_cnt == 0) { + rtw_run_in_thread_cmd(mlme_to_adapter(mlmepriv) + , ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), mlme_to_adapter(mlmepriv)); + } + + _enter_critical_bh(&free_queue->lock, &irqL); + rtw_list_delete(&(unassoc_sta->list)); + rtw_list_insert_tail(&(unassoc_sta->list), &(free_queue->queue)); + _exit_critical_bh(&free_queue->lock, &irqL); +} + +static u8 del_unassoc_sta_chk(struct mlme_priv *mlmepriv, struct unassoc_sta_info *unassoc_sta) +{ + systime cur, lifetime; + + if (unassoc_sta == NULL) + return UNASOC_STA_DEL_CHK_SKIP; + + if (unassoc_sta->interested) + return UNASOC_STA_DEL_CHK_SKIP; + + cur = rtw_get_current_time(); + lifetime = unassoc_sta->time + rtw_ms_to_systime(UNASSOC_STA_LIFETIME_MS); + if (rtw_time_before(cur, lifetime)) + return UNASOC_STA_DEL_CHK_ALIVE; + + del_unassoc_sta(mlmepriv, unassoc_sta); + + return UNASOC_STA_DEL_CHK_DELETED; +} + +static struct unassoc_sta_info *alloc_unassoc_sta(struct mlme_priv *mlmepriv) +{ + _irqL irqL; + struct unassoc_sta_info *unassoc_sta; + _queue *free_queue = &mlmepriv->free_unassoc_sta_queue; + _list *list = NULL; + + + _enter_critical_bh(&free_queue->lock, &irqL); + + if (_rtw_queue_empty(free_queue) == _TRUE) { + unassoc_sta = NULL; + goto exit; + } + list = get_next(&(free_queue->queue)); + + unassoc_sta = LIST_CONTAINOR(list, struct unassoc_sta_info, list); + + rtw_list_delete(&unassoc_sta->list); + + _rtw_memset(unassoc_sta->addr, 0, ETH_ALEN); + unassoc_sta->recv_signal_power = 0; + unassoc_sta->time = 0; + unassoc_sta->interested = 0; +exit: + _exit_critical_bh(&free_queue->lock, &irqL); + + return unassoc_sta; + +} + +void rtw_del_unassoc_sta_queue(_adapter *adapter) +{ + struct unassoc_sta_info *unassoc_sta; + struct mlme_priv *mlmepriv; + _queue *queue; + _irqL irqL; + _list *head, *list; + + adapter = GET_PRIMARY_ADAPTER(adapter); + mlmepriv = &(adapter->mlmepriv); + queue = &(mlmepriv->unassoc_sta_queue); + + _enter_critical_bh(&queue->lock, &irqL); + head = get_list_head(queue); + list = get_next(head); + + while ((rtw_end_of_queue_search(head, list)) == _FALSE) { + unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list); + list = get_next(list); + + del_unassoc_sta(mlmepriv, unassoc_sta); + } + + _exit_critical_bh(&queue->lock, &irqL); + +} + +void rtw_del_unassoc_sta(_adapter *adapter, u8 *addr) +{ + struct unassoc_sta_info *unassoc_sta; + struct mlme_priv *mlmepriv; + _queue *queue; + _irqL irqL; + _list *head, *list; + + adapter = GET_PRIMARY_ADAPTER(adapter); + mlmepriv = &(adapter->mlmepriv); + queue = &(mlmepriv->unassoc_sta_queue); + + _enter_critical_bh(&queue->lock, &irqL); + head = get_list_head(queue); + list = get_next(head); + + while ((rtw_end_of_queue_search(head, list)) == _FALSE) { + unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list); + list = get_next(list); + + if (_rtw_memcmp(addr, unassoc_sta->addr, ETH_ALEN) == _TRUE) { + del_unassoc_sta(mlmepriv, unassoc_sta); + goto unlock_unassoc_sta_queue; + } + } + +unlock_unassoc_sta_queue: + _exit_critical_bh(&queue->lock, &irqL); +} + +void rtw_rx_add_unassoc_sta(_adapter *adapter, u8 stype, u8 *addr, s8 recv_signal_power) +{ + struct unassoc_sta_info *unassoc_sta; + struct unassoc_sta_info *oldest_unassoc_sta = NULL; + struct mlme_priv *mlmepriv; + _queue *queue; + _irqL irqL; + _list *head, *list; + + adapter = GET_PRIMARY_ADAPTER(adapter); + mlmepriv = &(adapter->mlmepriv); + queue = &(mlmepriv->unassoc_sta_queue); + + _enter_critical_bh(&queue->lock, &irqL); + head = get_list_head(queue); + list = get_next(head); + + while ((rtw_end_of_queue_search(head, list)) == _FALSE) { + unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list); + list = get_next(list); + + if (_rtw_memcmp(addr, unassoc_sta->addr, ETH_ALEN) == _TRUE) { + if (unassoc_sta->interested + || mlmepriv->unassoc_sta_mode_of_stype[stype] >= UNASOC_STA_MODE_ALL + ) { + unassoc_sta->recv_signal_power = recv_signal_power; + unassoc_sta->time = rtw_get_current_time(); + goto unlock_unassoc_sta_queue; + } + } + + if (del_unassoc_sta_chk(mlmepriv, unassoc_sta) == UNASOC_STA_DEL_CHK_ALIVE) { + if (oldest_unassoc_sta == NULL) + oldest_unassoc_sta = unassoc_sta; + else if (rtw_time_before(unassoc_sta->time, oldest_unassoc_sta->time)) + oldest_unassoc_sta = unassoc_sta; + } + } + + if (mlmepriv->unassoc_sta_mode_of_stype[stype] <= UNASOC_STA_MODE_INTERESTED) + goto unlock_unassoc_sta_queue; + + unassoc_sta = alloc_unassoc_sta(mlmepriv); + if (unassoc_sta == NULL) { + if (oldest_unassoc_sta) { + del_unassoc_sta(mlmepriv, oldest_unassoc_sta); + unassoc_sta = alloc_unassoc_sta(mlmepriv); + } else + goto unlock_unassoc_sta_queue; + } + _rtw_memcpy(unassoc_sta->addr, addr, ETH_ALEN); + unassoc_sta->recv_signal_power = recv_signal_power; + unassoc_sta->time = rtw_get_current_time(); + rtw_list_insert_tail(&(unassoc_sta->list), &(queue->queue)); + +unlock_unassoc_sta_queue: + _exit_critical_bh(&queue->lock, &irqL); +} + +void rtw_add_interested_unassoc_sta(_adapter *adapter, u8 *addr) +{ + struct unassoc_sta_info *unassoc_sta; + struct unassoc_sta_info *oldest_unassoc_sta = NULL; + struct mlme_priv *mlmepriv; + _queue *queue; + _irqL irqL; + _list *head, *list; + + adapter = GET_PRIMARY_ADAPTER(adapter); + mlmepriv = &(adapter->mlmepriv); + queue = &(mlmepriv->unassoc_sta_queue); + + _enter_critical_bh(&queue->lock, &irqL); + head = get_list_head(queue); + list = get_next(head); + + while ((rtw_end_of_queue_search(head, list)) == _FALSE) { + unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list); + list = get_next(list); + + if (_rtw_memcmp(addr, unassoc_sta->addr, ETH_ALEN) == _TRUE) { + if (!unassoc_sta->interested) { + unassoc_sta->interested = 1; + mlmepriv->interested_unassoc_sta_cnt++; + if (mlmepriv->interested_unassoc_sta_cnt == 1) { + rtw_run_in_thread_cmd(mlme_to_adapter(mlmepriv) + , ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), mlme_to_adapter(mlmepriv)); + } + } + goto unlock_unassoc_sta_queue; + } + + if (del_unassoc_sta_chk(mlmepriv, unassoc_sta) == UNASOC_STA_DEL_CHK_ALIVE) { + if (oldest_unassoc_sta == NULL) + oldest_unassoc_sta = unassoc_sta; + else if (rtw_time_after(unassoc_sta->time, oldest_unassoc_sta->time)) + oldest_unassoc_sta = unassoc_sta; + } + } + unassoc_sta = alloc_unassoc_sta(mlmepriv); + if (unassoc_sta == NULL) { + RTW_INFO(FUNC_ADPT_FMT": Allocate fail\n", FUNC_ADPT_ARG(adapter)); + if (oldest_unassoc_sta) { + RTW_INFO(FUNC_ADPT_FMT": Delete oldest entry and try again.\n", FUNC_ADPT_ARG(adapter)); + del_unassoc_sta(mlmepriv, oldest_unassoc_sta); + unassoc_sta = alloc_unassoc_sta(mlmepriv); + } else + goto unlock_unassoc_sta_queue; + } + _rtw_memcpy(unassoc_sta->addr, addr, ETH_ALEN); + unassoc_sta->interested = 1; + unassoc_sta->recv_signal_power = 0; + unassoc_sta->time = rtw_get_current_time() - rtw_ms_to_systime(UNASSOC_STA_LIFETIME_MS); + rtw_list_insert_tail(&(unassoc_sta->list), &(queue->queue)); + mlmepriv->interested_unassoc_sta_cnt++; + if (mlmepriv->interested_unassoc_sta_cnt == 1) { + rtw_run_in_thread_cmd(mlme_to_adapter(mlmepriv) + , ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), mlme_to_adapter(mlmepriv)); + } + +unlock_unassoc_sta_queue: + _exit_critical_bh(&queue->lock, &irqL); +} + +void rtw_undo_interested_unassoc_sta(_adapter *adapter, u8 *addr) +{ + struct unassoc_sta_info *unassoc_sta; + struct mlme_priv *mlmepriv; + _queue *queue; + _irqL irqL; + _list *head, *list; + + adapter = GET_PRIMARY_ADAPTER(adapter); + mlmepriv = &(adapter->mlmepriv); + queue = &(mlmepriv->unassoc_sta_queue); + + _enter_critical_bh(&queue->lock, &irqL); + head = get_list_head(queue); + list = get_next(head); + + while ((rtw_end_of_queue_search(head, list)) == _FALSE) { + unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list); + list = get_next(list); + + if (_rtw_memcmp(addr, unassoc_sta->addr, ETH_ALEN) == _TRUE) { + if (unassoc_sta->interested) { + unassoc_sta->interested = 0; + mlmepriv->interested_unassoc_sta_cnt--; + if (mlmepriv->interested_unassoc_sta_cnt == 0) { + rtw_run_in_thread_cmd(mlme_to_adapter(mlmepriv) + , ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), mlme_to_adapter(mlmepriv)); + } + } + goto unlock_unassoc_sta_queue; + } + } +unlock_unassoc_sta_queue: + _exit_critical_bh(&queue->lock, &irqL); +} + +void rtw_undo_all_interested_unassoc_sta(_adapter *adapter) +{ + struct unassoc_sta_info *unassoc_sta; + struct mlme_priv *mlmepriv; + _queue *queue; + _irqL irqL; + _list *head, *list; + + adapter = GET_PRIMARY_ADAPTER(adapter); + mlmepriv = &(adapter->mlmepriv); + queue = &(mlmepriv->unassoc_sta_queue); + + _enter_critical_bh(&queue->lock, &irqL); + head = get_list_head(queue); + list = get_next(head); + + while ((rtw_end_of_queue_search(head, list)) == _FALSE) { + unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list); + list = get_next(list); + + if (unassoc_sta->interested) { + unassoc_sta->interested = 0; + mlmepriv->interested_unassoc_sta_cnt--; + if (mlmepriv->interested_unassoc_sta_cnt == 0) { + rtw_run_in_thread_cmd(mlme_to_adapter(mlmepriv) + , ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), mlme_to_adapter(mlmepriv)); + goto unlock_unassoc_sta_queue; + } + } + } +unlock_unassoc_sta_queue: + _exit_critical_bh(&queue->lock, &irqL); +} + +u8 rtw_search_unassoc_sta(_adapter *adapter, u8 *addr, struct unassoc_sta_info *ret_sta) +{ + struct unassoc_sta_info *unassoc_sta = NULL; + struct mlme_priv *mlmepriv; + _queue *queue; + _irqL irqL; + _list *head, *list; + u8 searched = 0; + + adapter = GET_PRIMARY_ADAPTER(adapter); + mlmepriv = &(adapter->mlmepriv); + queue = &(mlmepriv->unassoc_sta_queue); + + _enter_critical_bh(&queue->lock, &irqL); + head = get_list_head(queue); + list = get_next(head); + + while ((rtw_end_of_queue_search(head, list)) == _FALSE) { + unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list); + list = get_next(list); + + if (_rtw_memcmp(addr, unassoc_sta->addr, ETH_ALEN) == _TRUE) { + memcpy(ret_sta, unassoc_sta, sizeof(struct unassoc_sta_info)); + searched = 1; + break; + } + } + _exit_critical_bh(&queue->lock, &irqL); + + return searched; +} +#endif /* CONFIG_RTW_MULTI_AP */ + /* select the desired network based on the capability of the (i)bss. * check items: (1) security * (2) network_type @@ -1240,18 +1731,14 @@ int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork) bselected = _FALSE; } +#ifdef CONFIG_RTW_MBO + if (rtw_mbo_disallowed_network(pnetwork) == _TRUE) + bselected = _FALSE; +#endif return bselected; } -/* TODO: Perry : For Power Management */ -void rtw_atimdone_event_callback(_adapter *adapter , u8 *pbuf) -{ - - return; -} - - #ifdef CONFIG_80211D static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid) { @@ -1329,7 +1816,7 @@ static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid) i = 0; RTW_INFO("%s: STA channel plan {", __FUNCTION__); while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) { - _RTW_INFO("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType == SCAN_PASSIVE ? 'p' : 'a'); + _RTW_INFO("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].flags & RTW_CHF_NO_IR ? 'p' : 'a'); i++; } _RTW_INFO("}\n"); @@ -1351,22 +1838,21 @@ static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid) if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) { chplan_new[k].ChannelNum = chplan_ap.Channel[j]; - chplan_new[k].ScanType = SCAN_ACTIVE; i++; j++; k++; } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) { chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; #if 0 - chplan_new[k].ScanType = chplan_sta[i].ScanType; + if (chplan_sta[i].flags & RTW_CHF_NO_IR) + chplan_new[k].flags |= RTW_CHF_NO_IR; #else - chplan_new[k].ScanType = SCAN_PASSIVE; + chplan_new[k].flags |= RTW_CHF_NO_IR; #endif i++; k++; } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) { chplan_new[k].ChannelNum = chplan_ap.Channel[j]; - chplan_new[k].ScanType = SCAN_ACTIVE; j++; k++; } @@ -1378,9 +1864,10 @@ static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid) && (chplan_sta[i].ChannelNum <= 14)) { chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; #if 0 - chplan_new[k].ScanType = chplan_sta[i].ScanType; + if (chplan_sta[i].flags & RTW_CHF_NO_IR) + chplan_new[k].flags |= RTW_CHF_NO_IR; #else - chplan_new[k].ScanType = SCAN_PASSIVE; + chplan_new[k].flags |= RTW_CHF_NO_IR; #endif i++; k++; @@ -1389,7 +1876,6 @@ static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid) /* add channel AP supported */ while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) { chplan_new[k].ChannelNum = chplan_ap.Channel[j]; - chplan_new[k].ScanType = SCAN_ACTIVE; j++; k++; } @@ -1399,7 +1885,8 @@ static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid) && (chplan_sta[i].ChannelNum != 0) && (chplan_sta[i].ChannelNum <= 14)) { chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; - chplan_new[k].ScanType = chplan_sta[i].ScanType; + if (chplan_sta[i].flags & RTW_CHF_NO_IR) + chplan_new[k].flags |= RTW_CHF_NO_IR; i++; k++; } @@ -1420,22 +1907,21 @@ static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid) if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) { chplan_new[k].ChannelNum = chplan_ap.Channel[j]; - chplan_new[k].ScanType = SCAN_ACTIVE; i++; j++; k++; } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) { chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; #if 0 - chplan_new[k].ScanType = chplan_sta[i].ScanType; + if (chplan_sta[i].flags & RTW_CHF_NO_IR) + chplan_new[k].flags |= RTW_CHF_NO_IR; #else - chplan_new[k].ScanType = SCAN_PASSIVE; + chplan_new[k].flags |= RTW_CHF_NO_IR; #endif i++; k++; } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) { chplan_new[k].ChannelNum = chplan_ap.Channel[j]; - chplan_new[k].ScanType = SCAN_ACTIVE; j++; k++; } @@ -1445,9 +1931,10 @@ static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid) while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) { chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; #if 0 - chplan_new[k].ScanType = chplan_sta[i].ScanType; + if (chplan_sta[i].flags & RTW_CHF_NO_IR) + chplan_new[k].flags |= RTW_CHF_NO_IR; #else - chplan_new[k].ScanType = SCAN_PASSIVE; + chplan_new[k].flags |= RTW_CHF_NO_IR; #endif i++; k++; @@ -1456,7 +1943,6 @@ static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid) /* add channel AP supported */ while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0)) { chplan_new[k].ChannelNum = chplan_ap.Channel[j]; - chplan_new[k].ScanType = SCAN_ACTIVE; j++; k++; } @@ -1464,19 +1950,21 @@ static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid) /* keep original STA 5G channel plan */ while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) { chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; - chplan_new[k].ScanType = chplan_sta[i].ScanType; + if (chplan_sta[i].flags & RTW_CHF_NO_IR) + chplan_new[k].flags |= RTW_CHF_NO_IR; i++; k++; } } pmlmeext->update_channel_plan_by_ap_done = 1; + rtw_nlrtw_reg_change_event(padapter); #ifdef CONFIG_RTW_DEBUG k = 0; RTW_INFO("%s: new STA channel plan {", __FUNCTION__); while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) { - _RTW_INFO("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType == SCAN_PASSIVE ? 'p' : 'c'); + _RTW_INFO("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].flags & RTW_CHF_NO_IR ? 'p' : 'c'); k++; } _RTW_INFO("}\n"); @@ -1508,6 +1996,7 @@ void rtw_survey_event_callback(_adapter *adapter, u8 *pbuf) { _irqL irqL; u32 len; + u8 val8; WLAN_BSSID_EX *pnetwork; struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); @@ -1518,11 +2007,24 @@ void rtw_survey_event_callback(_adapter *adapter, u8 *pbuf) return; } +#ifdef CONFIG_RTW_80211K + val8 = 0; + rtw_hal_get_hwreg(adapter, HW_VAR_FREECNT, &val8); + + /* use TSF if no free run counter */ + if (val8==0) + pnetwork->PhyInfo.free_cnt = (u32)rtw_hal_get_tsftr_by_port( + adapter, rtw_hal_get_port(adapter)); +#endif + if (pnetwork->InfrastructureMode == Ndis802_11Infrastructure) { #ifdef CONFIG_80211D process_80211d(adapter, pnetwork); #endif - rtw_process_beacon_hint(adapter, pnetwork); + if (MLME_IS_SCAN(adapter)) { + adapter->mlmeextpriv.sitesurvey_res.activate_ch_cnt + += rtw_process_beacon_hint(adapter, pnetwork); + } } _enter_critical_bh(&pmlmepriv->lock, &irqL); @@ -1546,7 +2048,7 @@ void rtw_survey_event_callback(_adapter *adapter, u8 *pbuf) } /* lock pmlmepriv->lock when you accessing network_q */ - if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == _FALSE) { + if ((check_fwstate(pmlmepriv, WIFI_UNDER_LINKING)) == _FALSE) { if (pnetwork->Ssid.Ssid[0] == 0) pnetwork->Ssid.SsidLength = 0; rtw_add_network(adapter, pnetwork); @@ -1565,9 +2067,7 @@ void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf) _irqL irqL; struct surveydone_event *parm = (struct surveydone_event *)pbuf; struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); -#ifdef CONFIG_RTW_80211R struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; -#endif #ifdef CONFIG_MLME_EXT mlmeext_surveydone_event_callback(adapter); @@ -1583,12 +2083,15 @@ void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf) } - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _FALSE) { + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _FALSE) { RTW_INFO(FUNC_ADPT_FMT" fw_state:0x%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv)); /* rtw_warn_on(1); */ } - _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); + if (pmlmeext->scan_abort == _TRUE) + pmlmeext->scan_abort = _FALSE; + + _clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY); _exit_critical_bh(&pmlmepriv->lock, &irqL); _cancel_timer_ex(&pmlmepriv->scan_to_timer); @@ -1601,17 +2104,18 @@ void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf) if (pmlmepriv->to_join == _TRUE) { if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) { - if (check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) { - set_fwstate(pmlmepriv, _FW_UNDER_LINKING); + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE) { + set_fwstate(pmlmepriv, WIFI_UNDER_LINKING); if (rtw_select_and_join_from_scanned_queue(pmlmepriv) == _SUCCESS) _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); + #ifdef CONFIG_AP_MODE else { WLAN_BSSID_EX *pdev_network = &(adapter->registrypriv.dev_network); u8 *pibss = adapter->registrypriv.dev_network.MacAddress; - /* pmlmepriv->fw_state ^= _FW_UNDER_SURVEY; */ /* because don't set assoc_timer */ - _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); + /* pmlmepriv->fw_state ^= WIFI_UNDER_SURVEY; */ /* because don't set assoc_timer */ + _clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY); _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID)); @@ -1628,16 +2132,17 @@ void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf) pmlmepriv->to_join = _FALSE; } + #endif /* CONFIG_AP_MODE */ } } else { int s_ret; - set_fwstate(pmlmepriv, _FW_UNDER_LINKING); + set_fwstate(pmlmepriv, WIFI_UNDER_LINKING); pmlmepriv->to_join = _FALSE; s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv); if (_SUCCESS == s_ret) _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); else if (s_ret == 2) { /* there is no need to wait for join */ - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING); rtw_indicate_connect(adapter); } else { RTW_INFO("try_to_join, but select scanning queue fail, to_roam:%d\n", rtw_to_roam(adapter)); @@ -1661,21 +2166,25 @@ void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf) pmlmepriv->to_join = _TRUE; } else rtw_indicate_disconnect(adapter, 0, _FALSE); - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING); } } } else { - if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) { + if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE) + #if (defined(CONFIG_RTW_WNM) && defined(CONFIG_RTW_80211R)) + || rtw_wnm_btm_roam_triggered(adapter) + #endif + ) { if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) - && check_fwstate(pmlmepriv, _FW_LINKED)) { + && check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) { if (rtw_select_roaming_candidate(pmlmepriv) == _SUCCESS) { -#ifdef CONFIG_RTW_80211R + #ifdef CONFIG_RTW_80211R rtw_ft_start_roam(adapter, (u8 *)pmlmepriv->roam_network->network.MacAddress); -#else + #else receive_disconnect(adapter, pmlmepriv->cur_network.network.MacAddress , WLAN_REASON_ACTIVE_ROAM, _FALSE); -#endif + #endif } } } @@ -1686,7 +2195,7 @@ void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf) _exit_critical_bh(&pmlmepriv->lock, &irqL); #ifdef CONFIG_P2P_PS - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) p2p_ps_wk_cmd(adapter, P2P_PS_SCAN_DONE, 0); #endif /* CONFIG_P2P_PS */ @@ -1715,6 +2224,11 @@ void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf) rtw_cfg80211_indicate_scan_done_for_buddy(adapter, _FALSE); #endif + if (parm->activate_ch_cnt) { + op_class_pref_apply_regulatory(adapter, REG_BEACON_HINT); + rtw_nlrtw_reg_beacon_hint_event(adapter); + } + #ifdef CONFIG_RTW_MESH #if CONFIG_RTW_MESH_OFFCH_CAND if (rtw_mesh_offch_candidate_accepted(adapter)) { @@ -1812,24 +2326,24 @@ u8 _rtw_sitesurvey_condition_check(const char *caller, _adapter *adapter, bool c RTW_INFO("%s ("ADPT_FMT") : scan abort!! AP mode process WPS\n", caller, ADPT_ARG(adapter)); ss_condition = SS_DENY_SELF_AP_UNDER_WPS; goto _exit; - } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { + } else if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE) { RTW_INFO("%s ("ADPT_FMT") : scan abort!!AP mode under linking (fwstate=0x%x)\n", caller, ADPT_ARG(adapter), pmlmepriv->fw_state); ss_condition = SS_DENY_SELF_AP_UNDER_LINKING; goto _exit; - } else if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + } else if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE) { RTW_INFO("%s ("ADPT_FMT") : scan abort!!AP mode under survey (fwstate=0x%x)\n", caller, ADPT_ARG(adapter), pmlmepriv->fw_state); ss_condition = SS_DENY_SELF_AP_UNDER_SURVEY; goto _exit; } } else { - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE) { RTW_INFO("%s ("ADPT_FMT") : scan abort!!STA mode under linking (fwstate=0x%x)\n", caller, ADPT_ARG(adapter), pmlmepriv->fw_state); ss_condition = SS_DENY_SELF_STA_UNDER_LINKING; goto _exit; - } else if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + } else if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE) { RTW_INFO("%s ("ADPT_FMT") : scan abort!!STA mode under survey (fwstate=0x%x)\n", caller, ADPT_ARG(adapter), pmlmepriv->fw_state); ss_condition = SS_DENY_SELF_STA_UNDER_SURVEY; @@ -1838,52 +2352,41 @@ u8 _rtw_sitesurvey_condition_check(const char *caller, _adapter *adapter, bool c } #ifdef CONFIG_CONCURRENT_MODE - if (rtw_mi_buddy_check_fwstate(adapter, _FW_UNDER_LINKING | WIFI_UNDER_WPS)) { + if (rtw_mi_buddy_check_fwstate(adapter, WIFI_UNDER_LINKING | WIFI_UNDER_WPS)) { RTW_INFO("%s ("ADPT_FMT") : scan abort!! buddy_intf under linking or wps\n", caller, ADPT_ARG(adapter)); ss_condition = SS_DENY_BUDDY_UNDER_LINK_WPS; goto _exit; - } else if (rtw_mi_buddy_check_fwstate(adapter, _FW_UNDER_SURVEY)) { + } else if (rtw_mi_buddy_check_fwstate(adapter, WIFI_UNDER_SURVEY)) { RTW_INFO("%s ("ADPT_FMT") : scan abort!! buddy_intf under survey\n", caller, ADPT_ARG(adapter)); ss_condition = SS_DENY_BUDDY_UNDER_SURVEY; goto _exit; } #endif /* CONFIG_CONCURRENT_MODE */ - if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE) { - RTW_INFO("%s ("ADPT_FMT") : scan abort!! BusyTraffic\n", - caller, ADPT_ARG(adapter)); - ss_condition = SS_DENY_BUSY_TRAFFIC; - goto _exit; - } +#ifdef RTW_BUSY_DENY_SCAN /* - * Rule for Android. - * If scan interval > BUSY_TRAFFIC_SCAN_DENY_PERIOD, - * it is a periodical background scan. - * Skip background scan when other interface is busy. + * busy traffic check + * Rules: + * 1. If (scan interval <= BUSY_TRAFFIC_SCAN_DENY_PERIOD) always allow + * scan, otherwise goto rule 2. + * 2. Deny scan if any interface is busy, otherwise allow scan. */ - if ((rtw_get_passing_time_ms(pmlmepriv->lastscantime) > BUSY_TRAFFIC_SCAN_DENY_PERIOD) - && rtw_mi_buddy_busy_traffic_check(adapter, _FALSE)) { - RTW_INFO("%s ("ADPT_FMT") : scan abort!! others BusyTraffic\n", + if (pmlmepriv->lastscantime + && (rtw_get_passing_time_ms(pmlmepriv->lastscantime) > + registry_par->scan_interval_thr) + && rtw_mi_busy_traffic_check(adapter)) { + RTW_WARN("%s ("ADPT_FMT") : scan abort!! BusyTraffic\n", caller, ADPT_ARG(adapter)); ss_condition = SS_DENY_BUSY_TRAFFIC; goto _exit; } +#endif /* RTW_BUSY_DENY_SCAN */ -_exit : +_exit: return ss_condition; } -void rtw_dummy_event_callback(_adapter *adapter , u8 *pbuf) -{ - -} - -void rtw_fwdbg_event_callback(_adapter *adapter , u8 *pbuf) -{ - -} - static void free_scanqueue(struct mlme_priv *pmlmepriv) { _irqL irqL, irqL0; @@ -2018,28 +2521,31 @@ void rtw_free_assoc_resources(_adapter *adapter, u8 lock_scanned_queue) /* *rtw_indicate_connect: the caller has to lock pmlmepriv->lock */ -int rtw_indicate_connect(_adapter *padapter) +void rtw_indicate_connect(_adapter *padapter) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - int err = 0; - pmlmepriv->to_join = _FALSE; - if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { + if (!check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) { - set_fwstate(pmlmepriv, _FW_LINKED); + set_fwstate(pmlmepriv, WIFI_ASOC_STATE); rtw_led_control(padapter, LED_CTL_LINK); - err = rtw_os_indicate_connect(padapter); + rtw_os_indicate_connect(padapter); + + #ifdef CONFIG_RTW_WDS + if (MLME_IS_STA(padapter)) + rtw_wds_gptr_tbl_init(padapter); + #endif } rtw_set_to_roam(padapter, 0); if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter)) rtw_mi_set_scan_deny(padapter, 3000); - return err; + } @@ -2062,7 +2568,7 @@ void rtw_indicate_disconnect(_adapter *padapter, u16 reason, u8 locally_generate if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) pmlmepriv->wpa_phase = _TRUE; - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING | WIFI_UNDER_WPS | WIFI_OP_CH_SWITCHING | WIFI_UNDER_KEY_HANDSHAKE); + _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS | WIFI_OP_CH_SWITCHING | WIFI_UNDER_KEY_HANDSHAKE); /* force to clear cur_network_scanned's SELECTED REGISTRAR */ if (pmlmepriv->cur_network_scanned) { @@ -2083,7 +2589,7 @@ void rtw_indicate_disconnect(_adapter *padapter, u16 reason, u8 locally_generate /* RTW_INFO("clear wps when %s\n", __func__); */ if (rtw_to_roam(padapter) > 0) - _clr_fwstate_(pmlmepriv, _FW_LINKED); + _clr_fwstate_(pmlmepriv, WIFI_ASOC_STATE); #ifdef CONFIG_WAPI_SUPPORT psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress); @@ -2094,16 +2600,30 @@ void rtw_indicate_disconnect(_adapter *padapter, u16 reason, u8 locally_generate rtw_wapi_return_all_sta_info(padapter); #endif - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) + if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) || (rtw_to_roam(padapter) <= 0) ) { + #ifdef CONFIG_RTW_WDS + adapter_set_use_wds(padapter, 0); + rtw_wds_gptr_tbl_unregister(padapter); + #endif + #ifdef CONFIG_RTW_MULTI_AP + padapter->multi_ap = 0; + #endif + +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (ATOMIC_READ(&padapter->tbtx_tx_pause) == _TRUE) { + ATOMIC_SET(&padapter->tbtx_tx_pause, _FALSE); + rtw_tx_control_cmd(padapter); + } +#endif rtw_os_indicate_disconnect(padapter, reason, locally_generated); /* set ips_deny_time to avoid enter IPS before LPS leave */ rtw_set_ips_deny(padapter, 3000); - _clr_fwstate_(pmlmepriv, _FW_LINKED); + _clr_fwstate_(pmlmepriv, WIFI_ASOC_STATE); rtw_led_control(padapter, LED_CTL_NO_LINK); @@ -2158,22 +2678,22 @@ static u32 _rtw_wait_scan_done(_adapter *adapter, u8 abort, u32 timeout_ms) pmlmeext->scan_abort = abort; - while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) + while (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) && rtw_get_passing_time_ms(start) <= timeout_ms) { if (RTW_CANNOT_RUN(adapter)) break; - RTW_INFO(FUNC_NDEV_FMT"fw_state=_FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter->pnetdev)); - rtw_msleep_os(SURVEY_TO); + RTW_INFO(FUNC_NDEV_FMT"fw_state=WIFI_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter->pnetdev)); + rtw_msleep_os(20); } if (_TRUE == abort) { - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)) { if (!RTW_CANNOT_RUN(adapter)) RTW_INFO(FUNC_NDEV_FMT"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter->pnetdev)); #ifdef CONFIG_PLATFORM_MSTAR - /*_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);*/ + /*_clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY);*/ set_survey_timer(pmlmeext, 0); mlme_set_scan_to_timer(pmlmepriv, 50); #endif @@ -2206,13 +2726,13 @@ void rtw_scan_abort_no_wait(_adapter *adapter) struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv); - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)) pmlmeext->scan_abort = _TRUE; } void rtw_scan_abort(_adapter *adapter) { - rtw_scan_abort_timeout(adapter, 3000); + rtw_scan_abort_timeout(adapter, 200); } static u32 _rtw_wait_join_done(_adapter *adapter, u8 abort, u32 timeout_ms) @@ -2229,7 +2749,7 @@ static u32 _rtw_wait_join_done(_adapter *adapter, u8 abort, u32 timeout_ms) set_link_timer(pmlmeext, 1); while (rtw_get_passing_time_ms(start) <= timeout_ms - && (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) + && (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) #ifdef CONFIG_IOCTL_CFG80211 || rtw_cfg80211_is_connect_requested(adapter) #endif @@ -2243,7 +2763,7 @@ static u32 _rtw_wait_join_done(_adapter *adapter, u8 abort, u32 timeout_ms) } if (abort) { - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) + if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) #ifdef CONFIG_IOCTL_CFG80211 || rtw_cfg80211_is_connect_requested(adapter) #endif @@ -2308,6 +2828,7 @@ static struct sta_info *rtw_joinbss_update_stainfo(_adapter *padapter, struct wl u8 *ie; sint ie_len; u8 mfp_opt = MFP_NO; + u8 spp_opt = 0; padapter->securitypriv.binstallGrpkey = _FALSE; padapter->securitypriv.busetkipkey = _FALSE; @@ -2316,12 +2837,17 @@ static struct sta_info *rtw_joinbss_update_stainfo(_adapter *padapter, struct wl ie = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, WLAN_EID_RSN , &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_)); if (ie && ie_len > 0 - && rtw_parse_wpa2_ie(ie, ie_len + 2, NULL, NULL, NULL, &mfp_opt) == _SUCCESS + && rtw_parse_wpa2_ie(ie, ie_len + 2, NULL, NULL, NULL, NULL, &mfp_opt, &spp_opt) == _SUCCESS ) { if (padapter->securitypriv.mfp_opt >= MFP_OPTIONAL && mfp_opt >= MFP_OPTIONAL) psta->flags |= WLAN_STA_MFP; } + if (padapter->securitypriv.dot11PrivacyAlgrthm != _NO_PRIVACY_ ) { + /*check if amsdu is allowed */ + if (rtw_check_amsdu_disable(padapter->registrypriv.amsdu_mode, spp_opt) == _TRUE) + psta->flags |= WLAN_STA_AMSDU_DISABLE; + } psta->ieee8021x_blocked = _TRUE; psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; @@ -2365,6 +2891,17 @@ static struct sta_info *rtw_joinbss_update_stainfo(_adapter *padapter, struct wl #ifdef CONFIG_RTW_80211K _rtw_memcpy(&psta->rm_en_cap, pnetwork->network.PhyInfo.rm_en_cap, 5); #endif +#ifdef CONFIG_RTW_MULTI_AP + if (padapter->multi_ap & MULTI_AP_BACKHAUL_STA) { + u8 multi_ap = rtw_get_multi_ap_ie_ext(pmlmepriv->assoc_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6 + , pmlmepriv->assoc_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6); + + if (multi_ap & MULTI_AP_BACKHAUL_BSS) /* backhaul bss, enable WDS */ + psta->flags |= WLAN_STA_MULTI_AP | WLAN_STA_WDS; + else if (multi_ap & MULTI_AP_FRONTHAUL_BSS) /* fronthaul bss only */ + psta->flags |= WLAN_STA_MULTI_AP; + } +#endif #ifdef CONFIG_RTS_FULL_BW rtw_parse_sta_vendor_ie_8812(padapter, psta, BSS_EX_TLV_IES(&cur_network->network), BSS_EX_TLV_IES_LEN(&cur_network->network)); #endif @@ -2412,7 +2949,7 @@ static void rtw_joinbss_update_network(_adapter *padapter, struct wlan_network * rtw_set_signal_stat_timer(&padapter->recvpriv); #endif - /* update fw_state */ /* will clr _FW_UNDER_LINKING here indirectly */ + /* update fw_state */ /* will clr WIFI_UNDER_LINKING here indirectly */ switch (pnetwork->network.InfrastructureMode) { case Ndis802_11Infrastructure: @@ -2450,12 +2987,9 @@ static void rtw_joinbss_update_network(_adapter *padapter, struct wlan_network * * if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if "ptarget_sta" & "ptarget_wlan" exist. * if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist. * if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan !=NULL). - * - * Return - * -1 indicate connect fail */ /* #define REJOIN */ -int rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf, u16 status) +void rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf, u16 status) { _irqL irqL; static u8 retry = 0; @@ -2466,7 +3000,6 @@ int rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf, u16 status) struct wlan_network *cur_network = &(pmlmepriv->cur_network); struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL; unsigned int the_same_macaddr = _FALSE; - int err = 0; rtw_get_encrypt_decrypt_from_registrypriv(adapter); @@ -2485,9 +3018,9 @@ int rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf, u16 status) if (pnetwork->join_res > 0) { _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); retry = 0; - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { + if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING)) { /* s1. find ptarget_wlan */ - if (check_fwstate(pmlmepriv, _FW_LINKED)) { + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) { if (the_same_macaddr == _TRUE) ptarget_wlan = _rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); else { @@ -2518,17 +3051,9 @@ int rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf, u16 status) } /* s2. update cur_network */ - if (ptarget_wlan) { - /* - * Set scan deny to protect 4-way handshake or DHCP, - * because driver will leave under linking state in - * rtw_joinbss_update_network() - */ - if (!MLME_IS_AP(adapter) && !MLME_IS_MESH(adapter)) - rtw_mi_set_scan_deny(adapter, 3000); - + if (ptarget_wlan) rtw_joinbss_update_network(adapter, ptarget_wlan, pnetwork); - } else { + else { RTW_PRINT("Can't find ptarget_wlan when joinbss_event callback\n"); _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); goto ignore_joinbss_callback; @@ -2552,12 +3077,7 @@ int rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf, u16 status) /* s4. indicate connect */ if (MLME_IS_STA(adapter) || MLME_IS_ADHOC(adapter)) { pmlmepriv->cur_network_scanned = ptarget_wlan; - err = rtw_indicate_connect(adapter); - if (err) { - RTW_ERR(FUNC_ADPT_FMT ": Fail to indicate connect! err=%d\n", - FUNC_ADPT_ARG(adapter), err); - err = -1; - } + rtw_indicate_connect(adapter); } /* s5. Cancle assoc_timer */ @@ -2578,8 +3098,8 @@ int rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf, u16 status) /* rtw_free_assoc_resources(adapter, _TRUE); */ - if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == _TRUE) { - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + if ((check_fwstate(pmlmepriv, WIFI_UNDER_LINKING)) == _TRUE) { + _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING); } } else { /* if join_res < 0 (join fails), then try again */ @@ -2595,14 +3115,14 @@ int rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf, u16 status) _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); retry++; } else if (res == 2) { /* there is no need to wait for join */ - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING); rtw_indicate_connect(adapter); } else { #endif pmlmepriv->join_status = status; _set_timer(&pmlmepriv->assoc_timer, 1); /* rtw_free_assoc_resources(adapter, _TRUE); */ - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING); #ifdef REJOIN retry = 0; @@ -2614,7 +3134,7 @@ ignore_joinbss_callback: _exit_critical_bh(&pmlmepriv->lock, &irqL); exit: - return err; + return; } void rtw_joinbss_event_callback(_adapter *adapter, u8 *pbuf) @@ -2738,7 +3258,7 @@ u8 rtw_sta_media_status_rpt_cmd(_adapter *adapter, struct sta_info *sta, bool co cmd_parm->type = 0; cmd_parm->size = sizeof(struct sta_media_status_rpt_cmd_parm); cmd_parm->pbuf = (u8 *)rpt_parm; - init_h2fwcmd_w_parm_no_rsp(cmdobj, cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(cmdpriv, cmdobj); @@ -2792,10 +3312,6 @@ void rtw_stassoc_event_callback(_adapter *adapter, u8 *pbuf) if (passoc_req) { assoc_req_len = psta->assoc_req_len; _rtw_memcpy(passoc_req, psta->passoc_req, assoc_req_len); - - rtw_mfree(psta->passoc_req , psta->assoc_req_len); - psta->passoc_req = NULL; - psta->assoc_req_len = 0; } } _exit_critical_bh(&psta->lock, &irqL); @@ -2815,6 +3331,13 @@ void rtw_stassoc_event_callback(_adapter *adapter, u8 *pbuf) #endif/*CONFIG_BEAMFORMING*/ if (is_wep_enc(adapter->securitypriv.dot11PrivacyAlgrthm)) rtw_ap_wep_pk_setting(adapter, psta); + + #ifdef CONFIG_PLATFORM_CMAP_INTFS + if (MLME_IS_AP(adapter)) { + cmap_intfs_nl_sta_event(psta->cmn.mac_addr, adapter_mac_addr(adapter), 1 + , psta->passoc_req + IEEE80211_3ADDR_LEN, psta->assoc_req_len - IEEE80211_3ADDR_LEN); + } + #endif } goto exit; } @@ -2873,12 +3396,12 @@ exit: #ifdef CONFIG_IEEE80211W void rtw_sta_timeout_event_callback(_adapter *adapter, u8 *pbuf) { +#ifdef CONFIG_AP_MODE _irqL irqL; struct sta_info *psta; struct stadel_event *pstadel = (struct stadel_event *)pbuf; struct sta_priv *pstapriv = &adapter->stapriv; - psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr); if (psta) { @@ -2888,195 +3411,20 @@ void rtw_sta_timeout_event_callback(_adapter *adapter, u8 *pbuf) if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) { rtw_list_delete(&psta->asoc_list); pstapriv->asoc_list_cnt--; + #ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (psta->tbtx_enable) + pstapriv->tbtx_asoc_list_cnt--; + #endif updated = ap_free_sta(adapter, psta, _TRUE, WLAN_REASON_PREV_AUTH_NOT_VALID, _TRUE); } _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); associated_clients_update(adapter, updated, STA_INFO_UPDATE_ALL); } - - - +#endif /* CONFIG_AP_MODE */ } #endif /* CONFIG_IEEE80211W */ -#ifdef CONFIG_RTW_80211R -void rtw_ft_info_init(struct ft_roam_info *pft) -{ - _rtw_memset(pft, 0, sizeof(struct ft_roam_info)); - pft->ft_flags = 0 - | RTW_FT_EN - | RTW_FT_OTD_EN -#ifdef CONFIG_RTW_BTM_ROAM - | RTW_FT_BTM_ROAM -#endif - ; - pft->ft_updated_bcn = _FALSE; -} - -u8 rtw_ft_chk_roaming_candidate( - _adapter *padapter, struct wlan_network *competitor) -{ - u8 *pmdie; - u32 mdie_len = 0; - struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); - - if (!(pmdie = rtw_get_ie(&competitor->network.IEs[12], - _MDIE_, &mdie_len, competitor->network.IELength-12))) - return _FALSE; - - if (!_rtw_memcmp(&pft_roam->mdid, (pmdie+2), 2)) - return _FALSE; - - /*The candidate don't support over-the-DS*/ - if (rtw_ft_valid_otd_candidate(padapter, pmdie)) { - RTW_INFO("FT: ignore the candidate(" - MAC_FMT ") for over-the-DS\n", - MAC_ARG(competitor->network.MacAddress)); - rtw_ft_clr_flags(padapter, RTW_FT_PEER_OTD_EN); - return _FALSE; - } - - return _TRUE; -} - -void rtw_ft_update_stainfo(_adapter *padapter, WLAN_BSSID_EX *pnetwork) -{ - struct sta_priv *pstapriv = &padapter->stapriv; - struct sta_info *psta = NULL; - - psta = rtw_get_stainfo(pstapriv, pnetwork->MacAddress); - if (psta == NULL) - psta = rtw_alloc_stainfo(pstapriv, pnetwork->MacAddress); - - if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { - - padapter->securitypriv.binstallGrpkey = _FALSE; - padapter->securitypriv.busetkipkey = _FALSE; - padapter->securitypriv.bgrpkey_handshake = _FALSE; - - psta->ieee8021x_blocked = _TRUE; - psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; - - _rtw_memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype)); - _rtw_memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype)); - _rtw_memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype)); - } - -} - -void rtw_ft_reassoc_event_callback(_adapter *padapter, u8 *pbuf) -{ - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf; - struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&(pmlmeinfo->network); - struct cfg80211_ft_event_params ft_evt_parms; - _irqL irqL; - - _rtw_memset(&ft_evt_parms, 0, sizeof(ft_evt_parms)); - rtw_ft_update_stainfo(padapter, pnetwork); - ft_evt_parms.ies_len = pft_roam->ft_event.ies_len; - ft_evt_parms.ies = rtw_zmalloc(ft_evt_parms.ies_len); - if (ft_evt_parms.ies) - _rtw_memcpy((void *)ft_evt_parms.ies, pft_roam->ft_event.ies, ft_evt_parms.ies_len); - else - goto err_2; - - ft_evt_parms.target_ap = rtw_zmalloc(ETH_ALEN); - if (ft_evt_parms.target_ap) - _rtw_memcpy((void *)ft_evt_parms.target_ap, pstassoc->macaddr, ETH_ALEN); - else - goto err_1; - - ft_evt_parms.ric_ies = pft_roam->ft_event.ric_ies; - ft_evt_parms.ric_ies_len = pft_roam->ft_event.ric_ies_len; - - rtw_ft_lock_set_status(padapter, RTW_FT_AUTHENTICATED_STA, &irqL); - rtw_cfg80211_ft_event(padapter, &ft_evt_parms); - RTW_INFO("%s: to "MAC_FMT"\n", __func__, MAC_ARG(ft_evt_parms.target_ap)); - - rtw_mfree((u8 *)pft_roam->ft_event.target_ap, ETH_ALEN); -err_1: - rtw_mfree((u8 *)ft_evt_parms.ies, ft_evt_parms.ies_len); -err_2: - return; -} -#endif - -#if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) -void rtw_roam_nb_info_init(_adapter *padapter) -{ - struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); - - _rtw_memset(&pnb->nb_rpt, 0, sizeof(pnb->nb_rpt)); - _rtw_memset(&pnb->nb_rpt_ch_list, 0, sizeof(pnb->nb_rpt_ch_list)); - _rtw_memset(&pnb->roam_target_addr, 0, ETH_ALEN); - pnb->nb_rpt_valid = _FALSE; - pnb->nb_rpt_ch_list_num = 0; - pnb->preference_en = _FALSE; - pnb->nb_rpt_is_same = _TRUE; - pnb->last_nb_rpt_entries = 0; -#ifdef CONFIG_RTW_WNM - rtw_init_timer(&pnb->roam_scan_timer, - padapter, rtw_wnm_roam_scan_hdl, - padapter); -#endif -} - -u8 rtw_roam_nb_scan_list_set( - _adapter *padapter, struct sitesurvey_parm *pparm) -{ - u8 ret = _FALSE; - u32 i; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct roam_nb_info *pnb = &(pmlmepriv->nb_info); - - if (!rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE)) - return ret; - - if (!pmlmepriv->need_to_roam) - return ret; - - if ((!pmlmepriv->nb_info.nb_rpt_valid) || (!pnb->nb_rpt_ch_list_num)) - return ret; - - if (!pparm) - return ret; - - rtw_init_sitesurvey_parm(padapter, pparm); - if (rtw_roam_busy_scan(padapter, pnb)) { - pparm->ch_num = 1; - pparm->ch[pmlmepriv->ch_cnt].hw_value = - pnb->nb_rpt_ch_list[pmlmepriv->ch_cnt].hw_value; - pmlmepriv->ch_cnt++; - ret = _TRUE; - if (pmlmepriv->ch_cnt == pnb->nb_rpt_ch_list_num) { - pmlmepriv->nb_info.nb_rpt_valid = _FALSE; - pmlmepriv->ch_cnt = 0; - } - goto set_bssid_list; - } - - pparm->ch_num = (pnb->nb_rpt_ch_list_num > RTW_CHANNEL_SCAN_AMOUNT)? - (RTW_CHANNEL_SCAN_AMOUNT):(pnb->nb_rpt_ch_list_num); - for (i=0; ich_num; i++) { - pparm->ch[i].hw_value = pnb->nb_rpt_ch_list[i].hw_value; - pparm->ch[i].flags = RTW_IEEE80211_CHAN_PASSIVE_SCAN; - } - - pmlmepriv->nb_info.nb_rpt_valid = _FALSE; - pmlmepriv->ch_cnt = 0; - ret = _TRUE; - -set_bssid_list: - rtw_set_802_11_bssid_list_scan(padapter, pparm); - return ret; -} -#endif - void rtw_sta_mstatus_disc_rpt(_adapter *adapter, u8 mac_id) { struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl; @@ -3136,6 +3484,10 @@ void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf) struct wlan_network *tgt_network = &(pmlmepriv->cur_network); RTW_INFO("%s(mac_id=%d)=" MAC_FMT "\n", __func__, pstadel->mac_id, MAC_ARG(pstadel->macaddr)); +#ifdef CONFIG_LAYER2_ROAMING + if (pmlmepriv->roam_network) + rtw_msleep_os(RTW_ROAM_DICONNECT_DELAY); +#endif rtw_sta_mstatus_disc_rpt(adapter, pstadel->mac_id); #ifdef CONFIG_MCC_MODE @@ -3157,6 +3509,7 @@ void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf) goto exit; } +#ifdef CONFIG_AP_MODE if (MLME_IS_AP(adapter)) { #ifdef CONFIG_IOCTL_CFG80211 #ifdef COMPAT_KERNEL_RELEASE @@ -3166,10 +3519,15 @@ void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf) #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) */ #endif /* CONFIG_IOCTL_CFG80211 */ + #ifdef CONFIG_PLATFORM_CMAP_INTFS + cmap_intfs_nl_sta_event(pstadel->macaddr, adapter_mac_addr(adapter), 0, NULL, 0); + #endif + rtw_free_stainfo(adapter, psta); goto exit; } +#endif /* CONFIG_AP_MODE */ mlmeext_sta_del_event_callback(adapter); @@ -3195,6 +3553,14 @@ void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf) roam = _TRUE; roam_target = pmlmepriv->roam_network; } + +#ifdef CONFIG_RTW_80211R + if (reason == WLAN_REASON_ACTIVE_ROAM && rtw_ft_chk_flags(adapter, RTW_FT_BTM_ROAM)) { + roam = _TRUE; + roam_target = pmlmepriv->roam_network; + } +#endif + if (roam == _TRUE) { if (rtw_to_roam(adapter) > 0) rtw_dec_to_roam(adapter); /* this stadel_event is caused by roaming, decrease to_roam */ @@ -3211,9 +3577,12 @@ void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf) rtw_indicate_disconnect(adapter, *(u16 *)pstadel->rsvd, pstadel->locally_generated); +#ifdef CONFIG_LAYER2_ROAMING _rtw_roaming(adapter, roam_target); +#endif } +#ifdef CONFIG_AP_MODE if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { @@ -3256,7 +3625,7 @@ void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf) } } - +#endif /* CONFIG_AP_MODE */ _exit_critical_bh(&pmlmepriv->lock, &irqL2); exit: #ifdef CONFIG_RTS_FULL_BW @@ -3265,24 +3634,6 @@ exit: return; } - -void rtw_cpwm_event_callback(PADAPTER padapter, u8 *pbuf) -{ -#ifdef CONFIG_LPS_LCLK - struct reportpwrstate_parm *preportpwrstate; -#endif - - -#ifdef CONFIG_LPS_LCLK - preportpwrstate = (struct reportpwrstate_parm *)pbuf; - preportpwrstate->state |= (u8)(adapter_to_pwrctl(padapter)->cpwm_tog + 0x80); - cpwm_int_hdl(padapter, preportpwrstate); -#endif - - -} - - void rtw_wmm_event_callback(PADAPTER padapter, u8 *pbuf) { @@ -3380,7 +3731,7 @@ void rtw_scan_timeout_handler(void *ctx) _enter_critical_bh(&pmlmepriv->lock, &irqL); - _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); + _clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY); _exit_critical_bh(&pmlmepriv->lock, &irqL); @@ -3454,8 +3805,10 @@ void rtw_drv_scan_by_self(_adapter *padapter, u8 reason) RTW_INFO(FUNC_ADPT_FMT" need to roam, don't care BusyTraffic\n", FUNC_ADPT_ARG(padapter)); else #endif + { RTW_INFO(FUNC_ADPT_FMT" exit BusyTraffic\n", FUNC_ADPT_ARG(padapter)); goto exit; + } } else if (ssc_chk != SS_ALLOW) goto exit; @@ -3469,7 +3822,7 @@ void rtw_drv_scan_by_self(_adapter *padapter, u8 reason) if (!rtw_is_adapter_up(padapter)) goto exit; - if (rtw_mi_busy_traffic_check(padapter, _FALSE)) { + if (rtw_mi_busy_traffic_check(padapter)) { #ifdef CONFIG_LAYER2_ROAMING if (rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE) && pmlmepriv->need_to_roam == _TRUE) { RTW_INFO("need to roam, don't care BusyTraffic\n"); @@ -3484,13 +3837,13 @@ void rtw_drv_scan_by_self(_adapter *padapter, u8 reason) RTW_INFO(FUNC_ADPT_FMT" WIFI_AP_STATE && WIFI_UNDER_WPS\n", FUNC_ADPT_ARG(padapter)); goto exit; } - if (check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING)) == _TRUE) { - RTW_INFO(FUNC_ADPT_FMT" _FW_UNDER_SURVEY|_FW_UNDER_LINKING\n", FUNC_ADPT_ARG(padapter)); + if (check_fwstate(pmlmepriv, (WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING)) == _TRUE) { + RTW_INFO(FUNC_ADPT_FMT" WIFI_UNDER_SURVEY|WIFI_UNDER_LINKING\n", FUNC_ADPT_ARG(padapter)); goto exit; } #ifdef CONFIG_CONCURRENT_MODE - if (rtw_mi_buddy_check_fwstate(padapter, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING | WIFI_UNDER_WPS))) { + if (rtw_mi_buddy_check_fwstate(padapter, (WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING | WIFI_UNDER_WPS))) { RTW_INFO(FUNC_ADPT_FMT", but buddy_intf is under scanning or linking or wps_phase\n", FUNC_ADPT_ARG(padapter)); goto exit; } @@ -3517,7 +3870,9 @@ void rtw_drv_scan_by_self(_adapter *padapter, u8 reason) goto exit; #endif - rtw_set_802_11_bssid_list_scan(padapter, NULL); + rtw_init_sitesurvey_parm(padapter, &parm); + parm.reason = reason; + rtw_set_802_11_bssid_list_scan(padapter, &parm); exit: return; } @@ -3564,9 +3919,7 @@ static u8 is_drv_in_lps(_adapter *adapter) } void rtw_iface_dynamic_check_timer_handlder(_adapter *adapter) { -#ifdef CONFIG_AP_MODE struct mlme_priv *pmlmepriv = &adapter->mlmepriv; -#endif /* CONFIG_AP_MODE */ if (adapter->net_closed == _TRUE) return; @@ -3603,7 +3956,7 @@ void rtw_iface_dynamic_check_timer_handlder(_adapter *adapter) #ifdef CONFIG_BR_EXT - +if (!adapter_use_wds(adapter)) { #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) rcu_read_lock(); #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) */ @@ -3628,7 +3981,7 @@ void rtw_iface_dynamic_check_timer_handlder(_adapter *adapter) #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) rcu_read_unlock(); #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) */ - +} #endif /* CONFIG_BR_EXT */ } @@ -3843,19 +4196,17 @@ static int rtw_check_roaming_candidate(struct mlme_priv *mlme if (rtw_is_desired_network(adapter, competitor) == _FALSE) goto exit; +#ifdef CONFIG_RTW_ROAM_QUICKSCAN + if (competitor->network.PhyInfo.SignalStrength > CONFIG_RTW_ROAM_QUICKSCAN_TH) + adapter->mlmeextpriv.quickscan_next = _TRUE; +#endif + #ifdef CONFIG_LAYER2_ROAMING if (mlme->need_to_roam == _FALSE) goto exit; #endif -#ifdef CONFIG_RTW_80211R - if (rtw_ft_chk_flags(adapter, RTW_FT_PEER_EN)) { - if (rtw_ft_chk_roaming_candidate(adapter, competitor) == _FALSE) - goto exit; - } -#endif - - RTW_INFO("roam candidate:%s %s("MAC_FMT", ch%3u) rssi:%d, age:%5d\n", + RTW_INFO("roam candidate:%s %s("MAC_FMT", ch%3u) rssi:%d dBm, age:%5d\n", (competitor == mlme->cur_network_scanned) ? "*" : " " , competitor->network.Ssid.Ssid, MAC_ARG(competitor->network.MacAddress), @@ -3871,16 +4222,24 @@ static int rtw_check_roaming_candidate(struct mlme_priv *mlme else goto exit; } -#if 1 - if (rtw_get_passing_time_ms(competitor->last_scanned) >= mlme->roam_scanr_exp_ms) - goto exit; -#if defined(CONFIG_RTW_80211R) && defined(CONFIG_RTW_WNM) +#ifdef CONFIG_RTW_80211R + if (rtw_ft_chk_flags(adapter, RTW_FT_PEER_EN)) { + if (rtw_ft_chk_roaming_candidate(adapter, competitor) == _FALSE) + goto exit; + } + +#ifdef CONFIG_RTW_WNM if (rtw_wnm_btm_diff_bss(adapter) && rtw_wnm_btm_roam_candidate(adapter, competitor)) { goto update; } #endif +#endif + +#if 1 + if (rtw_get_passing_time_ms(competitor->last_scanned) >= mlme->roam_scanr_exp_ms) + goto exit; if (competitor->network.Rssi - mlme->cur_network_scanned->network.Rssi < mlme->roam_rssi_diff_th) goto exit; @@ -3949,7 +4308,7 @@ int rtw_select_roaming_candidate(struct mlme_priv *mlme) rtw_get_rson_struct(&(mlme->cur_network_scanned->network), &rson_curr); rson_score = rtw_cal_rson_score(&rson_curr, mlme->cur_network_scanned->network.Rssi); - if (check_fwstate(mlme, _FW_LINKED) + if (check_fwstate(mlme, WIFI_ASOC_STATE) && ((rson_score == RTW_RSON_SCORE_NOTCNNT) || (rson_score == RTW_RSON_SCORE_NOTSUP))) receive_disconnect(adapter, mlme->cur_network_scanned->network.MacAddress @@ -4060,7 +4419,7 @@ static int rtw_check_join_candidate(struct mlme_priv *mlme if (updated) { RTW_INFO("[by_bssid:%u][assoc_ssid:%s][to_roam:%u] " - "new candidate: %s("MAC_FMT", ch%u) rssi:%d\n", + "new candidate: %s("MAC_FMT", ch%u) rssi:%d dBm\n", mlme->assoc_by_bssid, mlme->assoc_ssid.Ssid, rtw_to_roam(adapter), @@ -4106,7 +4465,6 @@ int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv) #ifdef CONFIG_LAYER2_ROAMING if (pmlmepriv->roam_network) { candidate = pmlmepriv->roam_network; - pmlmepriv->roam_network = NULL; goto candidate_exist; } #endif @@ -4138,7 +4496,7 @@ int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv) if (candidate == NULL) { RTW_INFO("%s: return _FAIL(candidate == NULL)\n", __FUNCTION__); #ifdef CONFIG_WOWLAN - _clr_fwstate_(pmlmepriv, _FW_LINKED | _FW_UNDER_LINKING); + _clr_fwstate_(pmlmepriv, WIFI_ASOC_STATE | WIFI_UNDER_LINKING); #endif ret = _FAIL; goto exit; @@ -4151,13 +4509,13 @@ int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv) candidate_exist: - /* check for situation of _FW_LINKED */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { - RTW_INFO("%s: _FW_LINKED while ask_for_joinbss!!!\n", __FUNCTION__); + /* check for situation of WIFI_ASOC_STATE */ + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { + RTW_INFO("%s: WIFI_ASOC_STATE while ask_for_joinbss!!!\n", __FUNCTION__); #if 0 /* for WPA/WPA2 authentication, wpa_supplicant will expect authentication from AP, it is needed to reconnect AP... */ if (is_same_network(&pmlmepriv->cur_network.network, &candidate->network)) { - RTW_INFO("%s: _FW_LINKED and is same network, it needn't join again\n", __FUNCTION__); + RTW_INFO("%s: WIFI_ASOC_STATE and is same network, it needn't join again\n", __FUNCTION__); rtw_indicate_connect(adapter);/* rtw_indicate_connect again */ @@ -4183,7 +4541,7 @@ candidate_exist: ); } #endif - set_fwstate(pmlmepriv, _FW_UNDER_LINKING); + set_fwstate(pmlmepriv, WIFI_UNDER_LINKING); ret = rtw_joinbss_cmd(adapter, candidate); exit: @@ -4217,7 +4575,7 @@ sint rtw_set_auth(_adapter *adapter, struct security_priv *psecuritypriv) _rtw_memset(psetauthparm, 0, sizeof(struct setauth_parm)); psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm; - pcmd->cmdcode = _SetAuth_CMD_; + pcmd->cmdcode = CMD_SET_AUTH; pcmd->parmbuf = (unsigned char *)psetauthparm; pcmd->cmdsz = (sizeof(struct setauth_parm)); pcmd->rsp = NULL; @@ -4281,9 +4639,15 @@ sint rtw_set_key(_adapter *adapter, struct security_priv *psecuritypriv, sint ke _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen); break; case _AES_: + case _GCMP_: keylen = 16; _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen); break; + case _GCMP_256_: + case _CCMP_256_: + keylen = 32; + _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen); + break; default: res = _FAIL; rtw_mfree((unsigned char *)psetkeyparm, sizeof(struct setkey_parm)); @@ -4299,7 +4663,7 @@ sint rtw_set_key(_adapter *adapter, struct security_priv *psecuritypriv, sint ke goto exit; } - pcmd->cmdcode = _SetKey_CMD_; + pcmd->cmdcode =CMD_SET_KEY; pcmd->parmbuf = (u8 *)psetkeyparm; pcmd->cmdsz = (sizeof(struct setkey_parm)); pcmd->rsp = NULL; @@ -4554,6 +4918,9 @@ int rtw_rsn_sync_pmkid(_adapter *adapter, u8 *ie, uint ie_len, int i_ent) if (i_ent < 0 && info.pmkid_cnt == 0) goto exit; + if (info.pmkid_list == NULL) + goto exit; + if (i_ent >= 0 && info.pmkid_cnt == 1 && _rtw_memcmp(info.pmkid_list, sec->PMKIDList[i_ent].PMKID, 16)) { RTW_INFO(FUNC_ADPT_FMT" has carried the same PMKID:"KEY_FMT"\n" , FUNC_ADPT_ARG(adapter), KEY_ARG(&sec->PMKIDList[i_ent].PMKID)); @@ -4732,7 +5099,7 @@ void rtw_joinbss_reset(_adapter *padapter) phtpriv->ampdu_enable = _FALSE;/* reset to disabled */ -#ifdef CONFIG_USB_HCI +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) /* TH=1 => means that invalidate usb rx aggregation */ /* TH=0 => means that validate usb rx aggregation, use init value. */ if (phtpriv->ht_option) { @@ -4745,7 +5112,7 @@ void rtw_joinbss_reset(_adapter *padapter) threshold = 1; rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold)); } -#endif /* CONFIG_USB_HCI */ +#endif/* #if defined( CONFIG_USB_HCI) || defined (CONFIG_SDIO_HCI) */ #endif/* #ifdef CONFIG_80211N_HT */ @@ -4805,10 +5172,13 @@ void rtw_ht_use_default_setting(_adapter *padapter) CLEAR_FLAGS(phtpriv->beamform_cap); #ifdef CONFIG_BEAMFORMING #ifdef RTW_BEAMFORMING_VERSION_2 +#ifdef CONFIG_CONCURRENT_MODE /* only enable beamforming in STA client mode */ - if (MLME_IS_STA(padapter) && !MLME_IS_GC(padapter) - && !MLME_IS_ADHOC(padapter) - && !MLME_IS_MESH(padapter)) + if (MLME_IS_STA(padapter) && !MLME_IS_GC(padapter)) +#else + if ((MLME_IS_AP(padapter) && !MLME_IS_GO(padapter)) || + (MLME_IS_STA(padapter) && !MLME_IS_GC(padapter))) +#endif #endif { rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&bHwSupportBeamformer); @@ -5171,16 +5541,16 @@ void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel) (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) && (pmlmeinfo->HT_info.infos[0] & BIT(2))) { int i; - u8 tx_nss = 0; + u8 rx_nss = 0; - tx_nss = GET_HAL_TX_NSS(padapter); + rx_nss = GET_HAL_RX_NSS(padapter); /* update the MCS set */ for (i = 0; i < 16; i++) pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= pmlmeext->default_supported_mcs_set[i]; /* update the MCS rates */ - switch (tx_nss) { + switch (rx_nss) { case 1: set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R); break; @@ -5199,7 +5569,7 @@ void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel) set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_4R); break; default: - RTW_WARN("tx_nss:%u is not expected\n", tx_nss); + RTW_WARN("rx_nss:%u is not expected\n", rx_nss); } /* switch to the 40M Hz mode accoring to the AP */ @@ -5275,17 +5645,36 @@ void rtw_issue_addbareq_cmd_tdls(_adapter *padapter, struct xmit_frame *pxmitfra #endif /* CONFIG_TDLS */ #ifdef CONFIG_80211N_HT -void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe) +static u8 rtw_issue_addbareq_check(_adapter *padapter, struct xmit_frame *pxmitframe, u8 issue_when_busy) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct registry_priv *pregistry = &padapter->registrypriv; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + s32 bmcst = IS_MCAST(pattrib->ra); + + if (bmcst) + return _FALSE; + + if (pregistry->tx_quick_addba_req == 0) { + if ((issue_when_busy == _TRUE) && (pmlmepriv->LinkDetectInfo.bBusyTraffic == _FALSE)) + return _FALSE; + + if (pmlmepriv->LinkDetectInfo.NumTxOkInPeriod < 100) + return _FALSE; + } + + return _TRUE; +} + +void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe, u8 issue_when_busy) { u8 issued; int priority; struct sta_info *psta = NULL; struct ht_priv *phtpriv; struct pkt_attrib *pattrib = &pxmitframe->attrib; - s32 bmcst = IS_MCAST(pattrib->ra); - /* if(bmcst || (padapter->mlmepriv.LinkDetectInfo.bTxBusyTraffic == _FALSE)) */ - if (bmcst || (padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod < 100)) + if (rtw_issue_addbareq_check(padapter,pxmitframe, issue_when_busy) == _FALSE) return; priority = pattrib->priority; @@ -5305,8 +5694,8 @@ void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe) return; } - if (!(psta->state & _FW_LINKED)) { - RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + if (!(psta->state & WIFI_ASOC_STATE)) { + RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state); return; } @@ -5347,6 +5736,10 @@ void rtw_append_exented_cap(_adapter *padapter, u8 *out_ie, uint *pout_len) #ifdef CONFIG_RTW_WNM rtw_wnm_set_ext_cap_btm(cap_content, 1); #endif + +#ifdef CONFIG_RTW_MBO + rtw_mbo_set_ext_cap_internw(cap_content, 1); +#endif /* From 802.11 specification,if a STA does not support any of capabilities defined in the Extended Capabilities element, then the STA is not required to @@ -5465,7 +5858,7 @@ sint rtw_linked_check(_adapter *padapter) return _TRUE; } else { /* Station mode */ - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE) return _TRUE; } return _FALSE; diff --git a/core/rtw_mlme_ext.c b/core/rtw_mlme_ext.c old mode 100755 new mode 100644 index 49099ff..5ee17ea --- a/core/rtw_mlme_ext.c +++ b/core/rtw_mlme_ext.c @@ -88,6 +88,9 @@ struct action_handler OnAction_tbl[] = { {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm}, {RTW_WLAN_CATEGORY_VHT, "ACTION_VHT", &OnAction_vht}, {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p}, +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + {RTW_WLAN_CATEGORY_TBTX, "ACTION_TBTX_TOKEN", &OnAction_tbtx_token} +#endif }; @@ -102,6 +105,7 @@ unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04}; unsigned char P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09}; unsigned char WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A}; unsigned char DPP_OUI[] = {0x50, 0x6F, 0x9A, 0x1A}; +unsigned char MULTI_AP_OUI[] = {0x50, 0x6F, 0x9A, 0x1B}; unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; @@ -109,6 +113,9 @@ unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02}; unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02}; +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT +unsigned char REALTEK_TBTX_IE[] = {0x00, 0xe0, 0x4c, 0x01, 0x00, 0x00, 0x00, 0x00}; +#endif extern unsigned char REALTEK_96B_IE[]; static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set @@ -212,6 +219,40 @@ void rtw_txpwr_init_regd(struct rf_ctl_t *rfctl) goto release_lock; } +#ifdef CONFIG_REGD_SRC_FROM_OS + if (rfctl->regd_src == REGD_SRC_OS) { + if (IS_ALPHA2_WORLDWIDE(rfctl->country_ent->alpha2)) + rfctl->regd_name = regd_str(TXPWR_LMT_WW); + else { + char alpha2[3] = { + rfctl->country_ent->alpha2[0], rfctl->country_ent->alpha2[1], 0}; + + ent = _rtw_txpwr_lmt_get_by_name(rfctl, alpha2); + if (ent) + rfctl->regd_name = ent->regd_name; + } + + if (rfctl->regd_name) { + RTW_PRINT("mapping country:%c%c to regd_name:%s\n" + , rfctl->country_ent->alpha2[0] + , rfctl->country_ent->alpha2[1] + , rfctl->regd_name + ); + goto release_lock; + } + + if (rfctl->ChannelPlan == RTW_CHPLAN_UNSPECIFIED) { + rfctl->regd_name = regd_str(TXPWR_LMT_WW); + RTW_PRINT("mapping unsupported country:%c%c to regd_name:%s\n" + , rfctl->country_ent->alpha2[0] + , rfctl->country_ent->alpha2[1] + , rfctl->regd_name + ); + goto release_lock; + } + } +#endif + /* follow default channel plan mapping */ regd = rtw_chplan_get_default_regd(rfctl->ChannelPlan); if (regd == TXPWR_LMT_NONE) @@ -240,10 +281,11 @@ void rtw_txpwr_init_regd(struct rf_ctl_t *rfctl) */ case TXPWR_LMT_IC: case TXPWR_LMT_KCC: + case TXPWR_LMT_NCC: case TXPWR_LMT_ACMA: case TXPWR_LMT_CHILE: case TXPWR_LMT_MEXICO: - if (regd == TXPWR_LMT_IC || regd == TXPWR_LMT_CHILE || regd == TXPWR_LMT_MEXICO) + if (regd == TXPWR_LMT_IC || regd == TXPWR_LMT_NCC || regd == TXPWR_LMT_CHILE || regd == TXPWR_LMT_MEXICO) regd = TXPWR_LMT_FCC; else if (regd == TXPWR_LMT_KCC || regd == TXPWR_LMT_ACMA) regd = TXPWR_LMT_ETSI; @@ -268,10 +310,11 @@ release_lock: } #endif /* CONFIG_TXPWR_LIMIT */ -void rtw_rfctl_init(_adapter *adapter) +int rtw_rfctl_init(_adapter *adapter) { struct registry_priv *regsty = adapter_to_regsty(adapter); struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + int ret; _rtw_mutex_init(&rfctl->offch_mutex); @@ -292,8 +335,14 @@ void rtw_rfctl_init(_adapter *adapter) rfctl->dfs_slave_with_rd = 1; #endif - rfctl->max_chan_nums = init_channel_set(adapter, rfctl->ChannelPlan, rfctl->channel_set); - init_channel_list(adapter, rfctl->channel_set, &rfctl->channel_list); + if (regsty->antenna_gain != UNSPECIFIED_MBM) + rfctl->antenna_gain = regsty->antenna_gain; + + ret = op_class_pref_init(adapter); + if (ret != _SUCCESS) + op_class_pref_deinit(adapter); + + return ret; } void rtw_rfctl_deinit(_adapter *adapter) @@ -307,6 +356,113 @@ void rtw_rfctl_deinit(_adapter *adapter) rtw_txpwr_lmt_list_free(rfctl); _rtw_mutex_free(&rfctl->txpwr_lmt_mutex); #endif + +#ifdef CONFIG_REGD_SRC_FROM_OS + if (rfctl->regd_src == REGD_SRC_OS) + rtw_mfree((void *)rfctl->country_ent, sizeof(struct country_chplan)); +#endif + + op_class_pref_deinit(adapter); +} + +void rtw_rfctl_chplan_init(_adapter *adapter) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + rfctl->max_chan_nums = init_channel_set(adapter); + op_class_pref_apply_regulatory(adapter, REG_CHANGE); + init_channel_list(adapter, rfctl->channel_set, &rfctl->channel_list); +} + +void rtw_rfctl_update_op_mode(struct rf_ctl_t *rfctl, u8 ifbmp_mod, u8 if_op) +{ + struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl); + _adapter *iface; + struct mlme_ext_priv *mlmeext; + u8 op_class = 0; + u8 op_ch = 0; + s16 op_txpwr_max; + u8 if_op_class[CONFIG_IFACE_NUMBER] = {0}; + u8 if_op_ch[CONFIG_IFACE_NUMBER] = {0}; + u8 ch, bw, offset; + u8 u_ch = 0, u_bw, u_offset; + bool notify = 0; + int i; + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (!iface) + continue; + mlmeext = &iface->mlmeextpriv; + + if (ifbmp_mod & BIT(i)) { + if (!if_op) + continue; + } else if (!MLME_IS_ASOC(iface) || MLME_IS_OPCH_SW(iface)) + continue; + + ch = mlmeext->cur_channel; + bw = mlmeext->cur_bwmode; + offset = mlmeext->cur_ch_offset; + if_op_class[i] = rtw_get_op_class_by_chbw(ch, bw, offset); + if_op_ch[i] = if_op_class[i] ? ch : 0; + + if (!u_ch) { + u_ch = ch; + u_bw = bw; + u_offset = offset; + } else { + rtw_warn_on(!rtw_is_chbw_grouped(u_ch, u_bw, u_offset, ch, bw, offset)); + rtw_sync_chbw(&ch, &bw, &offset, &u_ch, &u_bw, &u_offset); + } + } + + op_class = rtw_get_op_class_by_chbw(u_ch, u_bw, u_offset); + op_ch = op_class ? u_ch : 0; + op_txpwr_max = rtw_rfctl_get_oper_txpwr_max_mbm(rfctl, u_ch, u_bw, u_offset, ifbmp_mod, if_op, 1); + + if (op_class != rfctl->op_class + || op_ch != rfctl->op_ch + || op_txpwr_max != rfctl->op_txpwr_max + || _rtw_memcmp(if_op_class, rfctl->if_op_class, sizeof(u8) * CONFIG_IFACE_NUMBER) == _FALSE + || _rtw_memcmp(if_op_ch, rfctl->if_op_ch, sizeof(u8) * CONFIG_IFACE_NUMBER) == _FALSE) + notify = 1; + + rfctl->op_class = op_class; + rfctl->op_ch = op_ch; + rfctl->op_txpwr_max = op_txpwr_max; + _rtw_memcpy(rfctl->if_op_class, if_op_class, sizeof(u8) * CONFIG_IFACE_NUMBER); + _rtw_memcpy(rfctl->if_op_ch, if_op_ch, sizeof(u8) * CONFIG_IFACE_NUMBER); + + if (0) + RTW_INFO("radio: %u,%u,%u %d notify:%d\n", u_ch, u_bw, u_offset, op_txpwr_max, notify); + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (!iface) + continue; + mlmeext = &iface->mlmeextpriv; + + if (ifbmp_mod & BIT(i)) { + if (!if_op) + continue; + } else if (!MLME_IS_ASOC(iface)) + continue; + if (0) + RTW_INFO(ADPT_FMT": %u,%u,%u\n", ADPT_ARG(iface) + , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset); + } + + if (notify) + rtw_nlrtw_radio_opmode_notify(rfctl); + +#ifdef CONFIG_PLATFORM_CMAP_INTFS + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (!iface) + continue; + cmap_intfs_nl_bss_status_event(iface, 0); + } +#endif } inline u8 rtw_rfctl_get_dfs_domain(struct rf_ctl_t *rfctl) @@ -314,14 +470,14 @@ inline u8 rtw_rfctl_get_dfs_domain(struct rf_ctl_t *rfctl) #ifdef CONFIG_DFS_MASTER return rfctl->dfs_region_domain; #else - return PHYDM_DFS_DOMAIN_UNKNOWN; + return RTW_DFS_REGD_NONE; #endif } inline u8 rtw_rfctl_dfs_domain_unknown(struct rf_ctl_t *rfctl) { #ifdef CONFIG_DFS_MASTER - return rtw_rfctl_get_dfs_domain(rfctl) == PHYDM_DFS_DOMAIN_UNKNOWN; + return rtw_rfctl_get_dfs_domain(rfctl) == RTW_DFS_REGD_NONE; #else return 1; #endif @@ -509,10 +665,11 @@ exit: * @offset: bandwidth offset on which radar is detected * @ms: ms to add from now to update non_ocp_end_time, ms < 0 means use NON_OCP_TIME_MS */ -static void _rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms) +static bool _rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms) { u32 hi = 0, lo = 0; int i; + bool updated = 0; if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) goto exit; @@ -530,21 +687,84 @@ static void _rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(ms); else ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(NON_OCP_TIME_MS); + ch_set[i].flags |= RTW_CHF_NON_OCP; + updated = 1; } } exit: - return; + return updated; } -inline void rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset) +inline bool rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset) { - _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, -1); + return _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, -1); } -inline void rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms) +inline bool rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms) { - _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, ms); + return _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, ms); +} + +static bool rtw_chset_chk_non_ocp_finish_for_chbw(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset) +{ + RT_CHANNEL_INFO *ch_set = rfctl->channel_set; + u8 cch; + u8 *op_chs; + u8 op_ch_num; + int i; + int ch_idx; + bool ret = 0; + + cch = rtw_get_center_ch(ch, bw, offset); + + if (!rtw_get_op_chs_by_cch_bw(cch, bw, &op_chs, &op_ch_num)) + goto exit; + + for (i = 0; i < op_ch_num; i++) { + if (0) + RTW_INFO("%u,%u,%u - cch:%u, bw:%u, op_ch:%u\n", ch, bw, offset, cch, bw, *(op_chs + i)); + ch_idx = rtw_chset_search_ch(ch_set, *(op_chs + i)); + if (ch_idx == -1) + break; + if (!(ch_set[ch_idx].flags & RTW_CHF_NON_OCP) || CH_IS_NON_OCP(&ch_set[ch_idx])) + break; + } + + if (op_ch_num != 0 && i == op_ch_num) { + ret = 1; + /* clear RTTW_CHF_NON_OCP flag */ + for (i = 0; i < op_ch_num; i++) { + ch_idx = rtw_chset_search_ch(ch_set, *(op_chs + i)); + ch_set[ch_idx].flags &= ~RTW_CHF_NON_OCP; + } + rtw_nlrtw_nop_finish_event(dvobj_get_primary_adapter(rfctl_to_dvobj(rfctl)), cch, bw); + } + +exit: + return ret; +} + +/* called by watchdog to clear RTW_CHF_NON_OCP and generate NON_OCP finish event */ +void rtw_chset_chk_non_ocp_finish(struct rf_ctl_t *rfctl) +{ + u8 ch, bw, offset; + int i; + + bw = CHANNEL_WIDTH_160; + while (1) { + for (i = 0; i < rfctl->max_chan_nums; i++) { + ch = rfctl->channel_set[i].ChannelNum; + if (!(rfctl->channel_set[i].flags & RTW_CHF_NON_OCP)) + continue; + if (!rtw_get_offset_by_chbw(ch, bw, &offset)) + continue; + + rtw_chset_chk_non_ocp_finish_for_chbw(rfctl, ch, bw, offset); + } + if (bw-- == CHANNEL_WIDTH_20) + break; + } } u32 rtw_get_ch_waiting_ms(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, u32 *r_non_ocp_ms, u32 *r_cac_ms) @@ -655,7 +875,7 @@ u32 rtw_force_stop_cac(struct rf_ctl_t *rfctl, u32 timeout_ms) /* choose channel with shortest waiting (non ocp + cac) time */ bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw , u8 *dec_ch, u8 *dec_bw, u8 *dec_offset - , u8 d_flags, u8 cur_ch, bool by_int_info, u8 mesh_only) + , u8 e_flags, u8 d_flags, u8 cur_ch, bool by_int_info, u8 mesh_only) { #ifndef DBG_CHOOSE_SHORTEST_WAITING_CH #define DBG_CHOOSE_SHORTEST_WAITING_CH 0 @@ -676,8 +896,8 @@ bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw return _FALSE; } - RTW_INFO("%s: sel_ch:%u max_bw:%u d_flags:0x%02x cur_ch:%u within_sb:%d%s%s\n" - , __func__, sel_ch, max_bw, d_flags, cur_ch, rfctl->ch_sel_within_same_band + RTW_INFO("%s: sel_ch:%u max_bw:%u e_flags:0x%02x d_flags:0x%02x cur_ch:%u within_sb:%d%s%s\n" + , __func__, sel_ch, max_bw, e_flags, d_flags, cur_ch, rfctl->ch_sel_within_same_band , by_int_info ? " int" : "", mesh_only ? " mesh_only" : ""); /* full search and narrow bw judegement first to avoid potetial judegement timing issue */ @@ -691,6 +911,8 @@ bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw u32 waiting_ms = 0; u16 int_factor = 0; bool dfs_ch; + bool non_ocp; + bool long_cac; ch = rfctl->channel_set[i].ChannelNum; if (sel_ch) { @@ -699,12 +921,6 @@ bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw } else if (rfctl->ch_sel_within_same_band && !rtw_is_same_band(cur_ch, ch)) continue; - if ((d_flags & RTW_CHF_2G) && ch <= 14) - continue; - - if ((d_flags & RTW_CHF_5G) && ch > 14) - continue; - if (ch > 14) { if (bw > REGSTY_BW_5G(regsty)) continue; @@ -722,21 +938,26 @@ bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw if (!rtw_chset_is_chbw_valid(rfctl->channel_set, ch, bw, offset, 0, 0)) continue; - if ((d_flags & RTW_CHF_NON_OCP) && rtw_chset_is_chbw_non_ocp(rfctl->channel_set, ch, bw, offset)) - continue; + if ((e_flags & RTW_CHF_DFS) || (d_flags & RTW_CHF_DFS)) { + dfs_ch = rtw_chset_is_dfs_chbw(rfctl->channel_set, ch, bw, offset); + if (((e_flags & RTW_CHF_DFS) && !dfs_ch) + || ((d_flags & RTW_CHF_DFS) && dfs_ch)) + continue; + } - dfs_ch = rtw_chset_is_dfs_chbw(rfctl->channel_set, ch, bw, offset); - if ((d_flags & RTW_CHF_DFS) && dfs_ch) - continue; + if ((e_flags & RTW_CHF_LONG_CAC) || (d_flags & RTW_CHF_LONG_CAC)) { + long_cac = rtw_is_long_cac_ch(ch, bw, offset, rtw_rfctl_get_dfs_domain(rfctl)); + if (((e_flags & RTW_CHF_LONG_CAC) && !long_cac) + || ((d_flags & RTW_CHF_LONG_CAC) && long_cac)) + continue; + } - if ((d_flags & RTW_CHF_LONG_CAC) && dfs_ch && rtw_is_long_cac_ch(ch, bw, offset, rtw_rfctl_get_dfs_domain(rfctl))) - continue; - - if ((d_flags & RTW_CHF_NON_DFS) && !dfs_ch) - continue; - - if ((d_flags & RTW_CHF_NON_LONG_CAC) && !(dfs_ch && rtw_is_long_cac_ch(ch, bw, offset, rtw_rfctl_get_dfs_domain(rfctl)))) - continue; + if ((e_flags & RTW_CHF_NON_OCP) || (d_flags & RTW_CHF_NON_OCP)) { + non_ocp = rtw_chset_is_chbw_non_ocp(rfctl->channel_set, ch, bw, offset); + if (((e_flags & RTW_CHF_NON_OCP) && !non_ocp) + || ((d_flags & RTW_CHF_NON_OCP) && non_ocp)) + continue; + } #ifdef CONFIG_DFS_MASTER waiting_ms = rtw_get_ch_waiting_ms(rfctl, ch, bw, offset, &non_ocp_ms, &cac_ms); @@ -791,29 +1012,43 @@ bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw return _FALSE; } -void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set) +#ifdef CONFIG_PROC_DEBUG +#define RTW_CHF_FMT "%s%s%s%s%s%s" + +#define RTW_CHF_ARG_NO_IR(flags) (flags & RTW_CHF_NO_IR) ? " NO_IR" : "" +#define RTW_CHF_ARG_DFS(flags) , (flags & RTW_CHF_DFS) ? " DFS" : "" +#define RTW_CHF_ARG_NO_HT40U(flags) , (flags & RTW_CHF_NO_HT40U) ? " NO_40M+" : "" +#define RTW_CHF_ARG_NO_HT40L(flags) , (flags & RTW_CHF_NO_HT40L) ? " NO_40M-" : "" +#define RTW_CHF_ARG_NO_80MHZ(flags) , (flags & RTW_CHF_NO_80MHZ) ? " NO_80M" : "" +#define RTW_CHF_ARG_NO_160MHZ(flags) , (flags & RTW_CHF_NO_160MHZ) ? " NO_160M" : "" + +#define RTW_CHF_ARG(flags) \ + RTW_CHF_ARG_NO_IR(flags) \ + RTW_CHF_ARG_DFS(flags) \ + RTW_CHF_ARG_NO_HT40U(flags) \ + RTW_CHF_ARG_NO_HT40L(flags) \ + RTW_CHF_ARG_NO_80MHZ(flags) \ + RTW_CHF_ARG_NO_160MHZ(flags) + +void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set, u8 chset_num) { - u8 i; + char buf[8]; + u8 i; - for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) { - RTW_PRINT_SEL(sel, "ch:%3u, freq:%u, scan_type:%d" - , ch_set[i].ChannelNum, rtw_ch2freq(ch_set[i].ChannelNum), ch_set[i].ScanType); + RTW_PRINT_SEL(sel, "%-3s %-4s %-4s flags\n", "ch", "freq", "nocp"); -#ifdef CONFIG_FIND_BEST_CHANNEL - _RTW_PRINT_SEL(sel, ", rx_count:%u", ch_set[i].rx_count); -#endif + for (i = 0; i < MAX_CHANNEL_NUM && i < chset_num && ch_set[i].ChannelNum != 0; i++) { + #ifdef CONFIG_DFS_MASTER + if ((ch_set[i].flags & RTW_CHF_DFS) && CH_IS_NON_OCP(&ch_set[i])) + snprintf(buf, 8, "%d", rtw_systime_to_ms(ch_set[i].non_ocp_end_time - rtw_get_current_time()) / 1000); + else + #endif + snprintf(buf, 8, "0"); -#ifdef CONFIG_DFS_MASTER - if (ch_set[i].dfs) { - if (CH_IS_NON_OCP(&ch_set[i])) - _RTW_PRINT_SEL(sel, ", non_ocp:%d" - , rtw_systime_to_ms(ch_set[i].non_ocp_end_time - rtw_get_current_time())); - else - _RTW_PRINT_SEL(sel, ", non_ocp:N/A"); - } -#endif - - _RTW_PRINT_SEL(sel, "\n"); + RTW_PRINT_SEL(sel, "%3u %4u %4s"RTW_CHF_FMT"\n" + , ch_set[i].ChannelNum, rtw_ch2freq(ch_set[i].ChannelNum), buf + , RTW_CHF_ARG(ch_set[i].flags) + ); } RTW_PRINT_SEL(sel, "total ch number:%d\n", i); @@ -823,19 +1058,25 @@ void dump_cur_chset(void *sel, struct rf_ctl_t *rfctl) { struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl); struct registry_priv *regsty = dvobj_to_regsty(dvobj); + struct get_chplan_resp *chplan; int i; - if (rfctl->country_ent) - dump_country_chplan(sel, rfctl->country_ent); + if (rtw_get_chplan_cmd(dvobj_get_primary_adapter(dvobj), RTW_CMDF_WAIT_ACK, &chplan) == _FAIL) + return; + + RTW_PRINT_SEL(sel, "regd_src:%s(%d)\n", regd_src_str(chplan->regd_src), chplan->regd_src); + + if (chplan->has_country) + dump_country_chplan(sel, &chplan->country_ent); else - RTW_PRINT_SEL(sel, "chplan:0x%02X\n", rfctl->ChannelPlan); + RTW_PRINT_SEL(sel, "chplan:0x%02X\n", chplan->channel_plan); #if CONFIG_TXPWR_LIMIT - RTW_PRINT_SEL(sel, "PLS regd:%s\n", rfctl->regd_name); + RTW_PRINT_SEL(sel, "PLS regd:%s\n", chplan->regd_name); #endif #ifdef CONFIG_DFS_MASTER - RTW_PRINT_SEL(sel, "dfs_domain:%u\n", rtw_rfctl_get_dfs_domain(rfctl)); + RTW_PRINT_SEL(sel, "dfs_domain:%s(%u)\n", rtw_dfs_regd_str(chplan->dfs_domain), chplan->dfs_domain); #endif for (i = 0; i < MAX_CHANNEL_NUM; i++) @@ -852,8 +1093,11 @@ void dump_cur_chset(void *sel, struct rf_ctl_t *rfctl) _RTW_PRINT_SEL(sel, "\n"); } - dump_chset(sel, rfctl->channel_set); + dump_chset(sel, chplan->chset, chplan->chset_num); + + rtw_vmfree(chplan, sizeof(struct get_chplan_resp) + sizeof(RT_CHANNEL_INFO) * chplan->chset_num); } +#endif /* * Search the @param ch in given @param ch_set @@ -907,11 +1151,21 @@ u8 rtw_chset_is_chbw_valid(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset ch_idx = rtw_chset_search_ch(ch_set, *(op_chs + i)); if (ch_idx == -1) break; - if (ch_set[ch_idx].ScanType == SCAN_PASSIVE) { + if (ch_set[ch_idx].flags & RTW_CHF_NO_IR) { if ((!allow_primary_passive && ch_set[ch_idx].ChannelNum == ch) || (!allow_passive && ch_set[ch_idx].ChannelNum != ch)) break; } + if (bw >= CHANNEL_WIDTH_40) { + if ((ch_set[ch_idx].flags & RTW_CHF_NO_HT40U) && i % 2 == 0) + break; + if ((ch_set[ch_idx].flags & RTW_CHF_NO_HT40L) && i % 2 == 1) + break; + } + if (bw >= CHANNEL_WIDTH_80 && (ch_set[ch_idx].flags & RTW_CHF_NO_80MHZ)) + break; + if (bw >= CHANNEL_WIDTH_160 && (ch_set[ch_idx].flags & RTW_CHF_NO_160MHZ)) + break; } if (op_ch_num != 0 && i == op_ch_num) @@ -1117,9 +1371,13 @@ static void init_mlme_ext_priv_value(_adapter *padapter) pmlmeext->sitesurvey_res.rx_ampdu_accept = RX_AMPDU_ACCEPT_INVALID; pmlmeext->sitesurvey_res.rx_ampdu_size = RX_AMPDU_SIZE_INVALID; #ifdef CONFIG_SCAN_BACKOP - mlmeext_assign_scan_backop_flags_sta(pmlmeext, /*SS_BACKOP_EN|*/SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME); + mlmeext_assign_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN | SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME); #ifdef CONFIG_AP_MODE - mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN | SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME); + #ifdef CONFIG_CUSTOMER_EZVIZ_CHIME2 + mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN | SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME | SS_BACKOP_EN_NL); + #else + mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN | SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME); + #endif #endif #ifdef CONFIG_RTW_MESH mlmeext_assign_scan_backop_flags_mesh(pmlmeext, /*SS_BACKOP_EN | */SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME); @@ -1159,6 +1417,9 @@ static void init_mlme_ext_priv_value(_adapter *padapter) _rtw_memset(pmlmeinfo->SupportedRates_infra_ap, 0, NDIS_802_11_LENGTH_RATES_EX); pmlmeinfo->ht_vht_received = 0; #endif /* ROKU_PRIVATE */ +#ifdef CONFIG_WRITE_BCN_LEN_TO_FW + pmlmeinfo->last_bcn_len = 0; +#endif } void init_mlme_ext_timer(_adapter *padapter) @@ -1175,6 +1436,13 @@ void init_mlme_ext_timer(_adapter *padapter) #ifdef CONFIG_RTW_REPEATER_SON rtw_init_timer(&pmlmeext->rson_scan_timer, padapter, rson_timer_hdl, padapter); #endif +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + rtw_init_timer(&pmlmeext->tbtx_xmit_timer, padapter, rtw_tbtx_xmit_timer_hdl, padapter); + rtw_init_timer(&pmlmeext->tbtx_token_dispatch_timer, padapter, rtw_tbtx_token_dispatch_timer_hdl, padapter); +#endif +#ifdef CONFIG_DFS + rtw_init_timer(&pmlmeext->csa_timer, padapter->pnetdev, csa_timer_hdl, padapter); +#endif } int init_mlme_ext_priv(_adapter *padapter) @@ -1246,6 +1514,9 @@ void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext) if (rtw_is_drv_stopped(padapter)) { _cancel_timer_ex(&pmlmeext->survey_timer); _cancel_timer_ex(&pmlmeext->link_timer); +#ifdef CONFIG_DFS + _cancel_timer_ex(&pmlmeext->csa_timer); +#endif /* CONFIG_DFS */ } } @@ -1278,14 +1549,14 @@ static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, uni /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */ if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) && !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) -#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI +#if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND) { struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) != _TRUE) return; - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE) return; if ( pwdev_priv->pno_mac_addr[0] == 0xFF) @@ -1332,14 +1603,14 @@ void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame) /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */ if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) && !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) -#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI +#if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND) { struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) != _TRUE) return; - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE) return; if ( pwdev_priv->pno_mac_addr[0] == 0xFF) @@ -1397,7 +1668,7 @@ void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame) ptable->func = &OnAuth; else ptable->func = &OnAuthClient; - /* fall through */ + /* fall through */ case WIFI_ASSOCREQ: case WIFI_REASSOCREQ: _mgt_dispatcher(padapter, ptable, precv_frame); @@ -1504,7 +1775,6 @@ unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame) struct sta_priv *pstapriv = &padapter->stapriv; #endif - #ifdef CONFIG_P2P struct wifidirect_info *pwdinfo = &(padapter->wdinfo); struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; @@ -1565,7 +1835,7 @@ _continue: if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) return _SUCCESS; - if (check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE && + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE && check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE | WIFI_MESH_STATE) == _FALSE) return _SUCCESS; @@ -1591,7 +1861,7 @@ _continue: #ifdef CONFIG_AUTO_AP_MODE - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE && pmlmepriv->cur_network.join_res == _TRUE) { _irqL irqL; struct sta_info *psta; @@ -1635,6 +1905,10 @@ _continue: psta->expire_to = pstapriv->expire_to; rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list); pstapriv->asoc_list_cnt++; + #ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (psta->tbtx_enable) + pstapriv->tbtx_asoc_list_cnt++; + #endif } _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); @@ -1678,7 +1952,7 @@ _continue: _rtw_memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats)); _enter_critical_bh(&psta->lock, &irqL); - psta->state |= _FW_LINKED; + psta->state |= WIFI_ASOC_STATE; _exit_critical_bh(&psta->lock, &irqL); report_add_sta_event(padapter, psta->cmn.mac_addr); @@ -1700,7 +1974,7 @@ _non_rc_device: #ifdef CONFIG_CONCURRENT_MODE if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) && - rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING | _FW_UNDER_SURVEY)) { + rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING | WIFI_UNDER_SURVEY)) { /* don't process probe req */ return _SUCCESS; } @@ -1732,7 +2006,7 @@ _non_rc_device: #endif _issue_probersp: - if (((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && + if (((check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE && pmlmepriv->cur_network.join_res == _TRUE)) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { /* RTW_INFO("+issue_probersp during ap mode\n"); */ issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq); @@ -1830,18 +2104,17 @@ unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame) } /* for 11n Logo 4.2.31/4.2.32 */ +#ifdef CONFIG_AP_MODE static void rtw_check_legacy_ap(_adapter *padapter, u8 *pframe, u32 len) { - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; if (!padapter->registrypriv.wifi_spec) return; - + if(!MLME_IS_AP(padapter)) return; - if (pmlmeext->bstart_bss == _TRUE) { int left; @@ -1869,9 +2142,9 @@ static void rtw_check_legacy_ap(_adapter *padapter, u8 *pframe, u32 len) ATOMIC_SET(&pmlmepriv->olbc, _TRUE); ATOMIC_SET(&pmlmepriv->olbc_ht, _TRUE); } - } } +#endif /* CONFIG_AP_MODE */ unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame) { @@ -1910,12 +2183,27 @@ unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame) rtw_mi_report_survey_event(padapter, precv_frame); return _SUCCESS; } + +#ifdef CONFIG_WRITE_BCN_LEN_TO_FW + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) + && (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) { + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; + + if (pmlmeinfo->last_bcn_len != pattrib->pkt_len) { + pmlmeinfo->last_bcn_len = pattrib->pkt_len; + rtw_write_bcnlen_to_fw_cmd(padapter, pattrib->pkt_len); + } + } +#endif + #ifdef CONFIG_RTW_REPEATER_SON if (padapter->rtw_rson_scanstage == RSON_SCAN_PROCESS) rtw_mi_report_survey_event(padapter, precv_frame); #endif +#ifdef CONFIG_AP_MODE rtw_check_legacy_ap(padapter, pframe, len); +#endif if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) { if ((pmlmeinfo->state & WIFI_FW_AUTH_NULL) @@ -2101,6 +2389,53 @@ _END_ONBEACON_: } +#ifdef CONFIG_AP_MODE +static u32 rtw_get_sta_num_by_state(_adapter *padapter, u32 state) +{ + _irqL irqL; + _list *plist, *phead; + u32 index, sta_num = 0; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &(padapter->stapriv); + + _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); + for (index = 0; index < NUM_STA; index++) { + phead = &(pstapriv->sta_hash[index]); + plist = get_next(phead); + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) { + psta = LIST_CONTAINOR(plist, struct sta_info , hash_list); + if ((psta->state & (state))) + sta_num++; + plist = get_next(plist); + } + } + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + /* RTW_INFO("%s : waiting for %u sta under linking \n", __func__, sta_num); */ + return sta_num; +} + +static u8 rtw_defs_attack_chk(_adapter *padapter) +{ + struct mlme_priv *mlme = &(padapter->mlmepriv); + u8 is_reject = _FALSE; + u32 sta_limit = 0; + u32 stime = rtw_systime_to_ms(rtw_get_current_time()); + static u32 ptime = 0; + + /* RTW_INFO("%s : ptime=%u, stime=%u, diff=%u\n", __func__, ptime, stime, (stime - ptime)); */ + if ((ptime > 0) && ((stime - ptime) < mlme->defs_lmt_time)) { + sta_limit = rtw_get_sta_num_by_state(padapter, WIFI_FW_LINKING_STATE); + if (sta_limit >= mlme->defs_lmt_sta) + is_reject = _TRUE; + } + + ptime = stime; + /* RTW_INFO("%s : current linking num=%u\n", __func__, sta_limit); */ + return is_reject; +} +#endif + unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame) { #ifdef CONFIG_AP_MODE @@ -2122,7 +2457,7 @@ unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame) #ifdef CONFIG_CONCURRENT_MODE if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) && - rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING | _FW_UNDER_SURVEY)) { + rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING | WIFI_UNDER_SURVEY)) { /* don't process auth request; */ return _SUCCESS; } @@ -2168,6 +2503,22 @@ unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame) RTW_INFO("auth alg=%x, seq=%X\n", algorithm, seq); + if (rtw_check_invalid_mac_address(sa, _FALSE)){ + RTW_INFO("%s : reject invalid AUTH-req "MAC_FMT"\n", + __func__, MAC_ARG(get_addr2_ptr(pframe))); + return _FAIL; + } + + if(rtw_defs_attack_chk(padapter)) { + struct sta_info *_psta; + _psta = rtw_get_stainfo(pstapriv, sa); + if ((_psta == NULL) || !(_psta->state & WIFI_FW_ASSOC_SUCCESS)) { + status = _STATS_REFUSED_TEMPORARILY_; + RTW_ERR("%s : refused temporarily for sa "MAC_FMT" !\n", __func__, MAC_ARG(sa)); + goto auth_fail; + } + } + if (rtw_ap_linking_test_force_auth_fail()) { status = rtw_ap_linking_test_force_auth_fail(); RTW_INFO(FUNC_ADPT_FMT" force auth fail with status:%u\n" @@ -2225,6 +2576,10 @@ unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame) if (rtw_is_list_empty(&pstat->asoc_list) == _FALSE) { rtw_list_delete(&pstat->asoc_list); pstapriv->asoc_list_cnt--; + #ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (pstat->tbtx_enable) + pstapriv->tbtx_asoc_list_cnt--; + #endif if (pstat->expire_to > 0) ;/* TODO: STA re_auth within expire_to */ } @@ -2371,7 +2726,7 @@ auth_fail: issue_auth(padapter, pstat, (unsigned short)status); #endif -#endif +#endif /* CONFIG_AP_MODE */ return _FAIL; } @@ -2390,7 +2745,7 @@ unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame) #ifdef CONFIG_IOCTL_CFG80211 if (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_AUTH) == _TRUE) { - if (rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE)) { + if (rtw_sec_chk_auth_type(padapter, MLME_AUTHTYPE_SAE)) { if (rtw_cached_pmkid(padapter, get_my_bssid(&pmlmeinfo->network)) != -1) { RTW_INFO("SAE: PMKSA cache entry found\n"); goto normal; @@ -2504,10 +2859,13 @@ unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame) u8 *p2pie; u32 p2pielen = 0; #endif /* CONFIG_P2P */ +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + u8 sta_tbtx_enable = _FALSE; +#endif #ifdef CONFIG_CONCURRENT_MODE if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) && - rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING | _FW_UNDER_SURVEY)) { + rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING | WIFI_UNDER_SURVEY)) { /* don't process assoc request; */ return _SUCCESS; } @@ -2516,6 +2874,12 @@ unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame) if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) return _FAIL; + if (rtw_check_invalid_mac_address(get_addr2_ptr(pframe), _FALSE)) { + RTW_INFO("%s : reject invalid ASSOC-req "MAC_FMT"\n", + __func__, MAC_ARG(get_addr2_ptr(pframe))); + return _FAIL; + } + frame_type = get_frame_sub_type(pframe); if (frame_type == WIFI_ASSOCREQ) { reassoc = 0; @@ -2638,6 +3002,15 @@ unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame) , pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset); #endif/*CONFIG_RTS_FULL_BW*/ +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (elems.tbtx_cap && elems.tbtx_cap_len != 0) { + if(rtw_is_tbtx_capabilty(elems.tbtx_cap, elems.tbtx_cap_len)) { + sta_tbtx_enable = _TRUE; + } + } + +#endif + rtw_ap_parse_sta_ht_ie(padapter, pstat, &elems); rtw_ap_parse_sta_vht_ie(padapter, pstat, &elems); @@ -2674,6 +3047,8 @@ unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame) pstat->p2p_status_code = p2p_status_code; #endif /* CONFIG_P2P */ + rtw_ap_parse_sta_multi_ap_ie(padapter, pstat, pos, left); + #ifdef CONFIG_RTW_REPEATER_SON if (rtw_rson_ap_check_sta(padapter, pframe, pkt_len, ie_offset)) goto OnAssocReqFail; @@ -2722,6 +3097,12 @@ unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame) pstat->expire_to = pstapriv->expire_to; rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list); pstapriv->asoc_list_cnt++; +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (sta_tbtx_enable) { + pstat->tbtx_enable = _TRUE; + pstapriv->tbtx_asoc_list_cnt++; + } +#endif } _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); } @@ -2794,7 +3175,7 @@ OnAssocReqFail: #ifdef CONFIG_NATIVEAP_MLME - pstat->cmn.aid = 0; + /* pstat->cmn.aid = 0; */ if (frame_type == WIFI_ASSOCREQ) issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP); else @@ -2818,7 +3199,7 @@ void rtw_roam_nb_discover(_adapter *padapter, u8 bfroce) struct sta_info *psta; u8 nb_req_issue = _FALSE; - if (!check_fwstate(pmlmepriv, _FW_LINKED)) + if (!check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) return; if (!rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE)) @@ -3044,6 +3425,10 @@ unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame) if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) { rtw_list_delete(&psta->asoc_list); pstapriv->asoc_list_cnt--; + #ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (psta->tbtx_enable) + pstapriv->tbtx_asoc_list_cnt--; + #endif updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE); } @@ -3077,13 +3462,6 @@ unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame) RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM, ignore=%d\n" , FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe), ignore_received_deauth); - if (pmlmeext->last_deauth_time && - (rtw_get_passing_time_ms(pmlmeext->last_deauth_time) < DEAUTH_DENY_TO)) { - RTW_PRINT(FUNC_ADPT_FMT ": ignore deauth triggered by self\n", - FUNC_ADPT_ARG(padapter)); - ignore_received_deauth = 1; - } - if (0 == ignore_received_deauth) receive_disconnect(padapter, get_addr2_ptr(pframe), reason, _FALSE); } @@ -3139,6 +3517,10 @@ unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame) if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) { rtw_list_delete(&psta->asoc_list); pstapriv->asoc_list_cnt--; + #ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (psta->tbtx_enable) + pstapriv->tbtx_asoc_list_cnt--; + #endif updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE); } @@ -3154,6 +3536,9 @@ unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame) RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM\n" , FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe)); + #ifdef CONFIG_RTW_WNM + if (rtw_wnm_try_btm_roam_imnt(padapter) > 0) + #endif receive_disconnect(padapter, get_addr2_ptr(pframe), reason, _FALSE); } pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE; @@ -3312,12 +3697,42 @@ unsigned int on_action_wnm(_adapter *adapter, union recv_frame *rframe) #ifdef CONFIG_RTW_80211R case RTW_WLAN_ACTION_WNM_BTM_REQ: if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) { - RTW_INFO("WNM: RTW_WLAN_ACTION_WNM_BTM_REQ recv.\n"); + RTW_INFO("WNM: BSS Transition Management Request recv.\n"); rtw_wnm_process_btm_req(adapter, frame_body, frame_body_len); } ret = _SUCCESS; break; -#endif +#endif + case RTW_WLAN_ACTION_WNM_BTM_RSP: + if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) && + (pmlmepriv->nb_info.features & RTW_WNM_FEATURE_BTM_REQ_EN)) { + struct btm_rsp_hdr rsp; + u32 sz; + + RTW_INFO("WNM: BSS Transition Management Response recv.\n"); + sz = rtw_wnm_btm_rsp_candidates_sz_get(adapter, + frame_body, frame_body_len); + _rtw_memset(&rsp, 0, sizeof(rsp)); + + if (sz > 0) + rsp.pcandidates = rtw_zmalloc(sz); + + rtw_wnm_process_btm_rsp(adapter, frame_body, frame_body_len, &rsp); + /* TODO : handle candidates info in rsp.pcandidates for upper-layer services */ + #ifdef CONFIG_PLATFORM_CMAP_INTFS + cmap_intfs_nl_btm_resp_event(adapter, sta->cmn.mac_addr, + adapter_mac_addr(adapter), + rsp.status, rsp.bssid, + rsp.pcandidates, + rsp.candidates_num); + #endif + if (0 && rsp.pcandidates && (rsp.candidates_num > 0)) + RTW_INFO_DUMP("pcandidates : ", rsp.pcandidates, sz); + + if ((sz > 0) && (rsp.pcandidates != NULL)) + rtw_mfree(rsp.pcandidates, sz); + } + /* fall through */ default: #ifdef CONFIG_IOCTL_CFG80211 cnt += sprintf((msg + cnt), "ACT_WNM %u", action); @@ -3621,7 +4036,7 @@ u16 rtw_rx_ampdu_apply(_adapter *adapter) adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, sta_size); } /* TODO: TDLS peer */ - +#ifdef CONFIG_AP_MODE } else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) { _irqL irqL; _list *phead, *plist; @@ -3658,6 +4073,7 @@ u16 rtw_rx_ampdu_apply(_adapter *adapter) adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, sta_size); } } +#endif /* CONFIG_AP_MODE */ } /* TODO: ADHOC */ @@ -3734,7 +4150,7 @@ unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame) status = RTW_GET_LE16(&frame_body[3]); tid = ((frame_body[5] >> 2) & 0x7); if (status == 0) { - /* successful */ + /* successful */ RTW_INFO("agg_enable for TID=%d\n", tid); psta->htpriv.agg_enable_bitmap |= 1 << tid; psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); @@ -3750,12 +4166,14 @@ unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame) } else psta->htpriv.agg_enable_bitmap &= ~BIT(tid); + #ifdef CONFIG_AP_MODE if (psta->state & WIFI_STA_ALIVE_CHK_STATE) { RTW_INFO("%s alive check - rx ADDBA response\n", __func__); psta->htpriv.agg_enable_bitmap &= ~BIT(tid); psta->expire_to = pstapriv->expire_to; psta->state ^= WIFI_STA_ALIVE_CHK_STATE; } + #endif /* RTW_INFO("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap); */ break; @@ -6241,6 +6659,9 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame) u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; u8 *merged_p2pie = NULL; u32 merged_p2p_ielen = 0; +#ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; +#endif #endif /* CONFIG_P2P */ frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); @@ -6276,8 +6697,8 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame) RTW_INFO("[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo)); } #ifdef CONFIG_CONCURRENT_MODE - if (rtw_mi_buddy_check_fwstate(padapter, _FW_LINKED)) - _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer); + if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE)) + _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer); #endif /* CONFIG_CONCURRENT_MODE */ /* Commented by Kurt 20110902 */ @@ -6641,8 +7062,9 @@ unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame) u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); u8 category, action; - /* check RA matches or not */ - if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN)) + /* check RA matches or broadcast */ + if (!(_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN) || + is_broadcast_mac_addr(GetAddr1Ptr(pframe)))) goto exit; category = frame_body[0]; @@ -6672,249 +7094,6 @@ exit: return ret; } -#if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) -static u8 rtw_wnm_nb_elem_parsing( - u8* pdata, u32 data_len, u8 from_btm, - u32 *nb_rpt_num, u8 *nb_rpt_is_same, - struct roam_nb_info *pnb, struct wnm_btm_cant *pcandidates) -{ - u8 bfound = _FALSE, ret = _SUCCESS; - u8 *ptr, *pend, *op; - u32 elem_len, subelem_len, op_len; - u32 i, nb_rpt_entries = 0; - struct nb_rpt_hdr *pie; - struct wnm_btm_cant *pcandidate; - - if ((!pdata) || (!pnb)) - return _FAIL; - - if ((from_btm) && (!pcandidates)) - return _FAIL; - - ptr = pdata; - pend = ptr + data_len; - elem_len = data_len; - subelem_len = (u32)*(pdata+1); - - for (i=0; i < RTW_MAX_NB_RPT_NUM; i++) { - if (((ptr + 7) > pend) || (elem_len < subelem_len)) - break; - - if (*ptr != 0x34) { - RTW_ERR("WNM: invalid data(0x%2x)!\n", *ptr); - ret = _FAIL; - break; - } - - pie = (struct nb_rpt_hdr *)ptr; - if (from_btm) { - op = rtw_get_ie((u8 *)(ptr+15), - WNM_BTM_CAND_PREF_SUBEID, - &op_len, (subelem_len - 15)); - } - - ptr = (u8 *)(ptr + subelem_len + 2); - elem_len -= (subelem_len +2); - subelem_len = *(ptr+1); - if (from_btm) { - pcandidate = (pcandidates + i); - _rtw_memcpy(&pcandidate->nb_rpt, pie, sizeof(struct nb_rpt_hdr)); - if (op && (op_len !=0)) { - pcandidate->preference = *(op + 2); - bfound = _TRUE; - } else - pcandidate->preference = 0; - - RTW_DBG("WNM: preference check bssid("MAC_FMT - ") ,bss_info(0x%04X), reg_class(0x%02X), ch(%d)," - " phy_type(0x%02X), preference(0x%02X)\n", - MAC_ARG(pcandidate->nb_rpt.bssid), pcandidate->nb_rpt.bss_info, - pcandidate->nb_rpt.reg_class, pcandidate->nb_rpt.ch_num, - pcandidate->nb_rpt.phy_type, pcandidate->preference); - } else { - if (_rtw_memcmp(&pnb->nb_rpt[i], pie, sizeof(struct nb_rpt_hdr)) == _FALSE) - *nb_rpt_is_same = _FALSE; - _rtw_memcpy(&pnb->nb_rpt[i], pie, sizeof(struct nb_rpt_hdr)); - } - nb_rpt_entries++; - } - - if (from_btm) - pnb->preference_en = (bfound)?_TRUE:_FALSE; - - *nb_rpt_num = nb_rpt_entries; - return ret; -} - -/* selection sorting based on preference value - * : nb_rpt_entries - candidate num - * / : pcandidates - candidate list - * return : TRUE - means pcandidates is updated. - */ -static u8 rtw_wnm_candidates_sorting( - u32 nb_rpt_entries, struct wnm_btm_cant *pcandidates) -{ - u8 updated = _FALSE; - u32 i, j, pos; - struct wnm_btm_cant swap; - struct wnm_btm_cant *pcant_1, *pcant_2; - - if ((!nb_rpt_entries) || (!pcandidates)) - return updated; - - for (i=0; i < (nb_rpt_entries - 1); i++) { - pos = i; - for (j=(i + 1); j < nb_rpt_entries; j++) { - pcant_1 = pcandidates+pos; - pcant_2 = pcandidates+j; - if ((pcant_1->preference) < (pcant_2->preference)) - pos = j; - } - - if (pos != i) { - updated = _TRUE; - _rtw_memcpy(&swap, (pcandidates+i), sizeof(struct wnm_btm_cant)); - _rtw_memcpy((pcandidates+i), (pcandidates+pos), sizeof(struct wnm_btm_cant)); - _rtw_memcpy((pcandidates+pos), &swap, sizeof(struct wnm_btm_cant)); - } - } - return updated; -} - -static void rtw_wnm_nb_info_update( - u32 nb_rpt_entries, u8 from_btm, - struct roam_nb_info *pnb, struct wnm_btm_cant *pcandidates, - u8 *nb_rpt_is_same) -{ - u8 is_found; - u32 i, j; - struct wnm_btm_cant *pcand; - - if (!pnb) - return; - - pnb->nb_rpt_ch_list_num = 0; - for (i=0; inb_rpt[i], &pcand->nb_rpt, - sizeof(struct nb_rpt_hdr)) == _FALSE) - *nb_rpt_is_same = _FALSE; - _rtw_memcpy(&pnb->nb_rpt[i], &pcand->nb_rpt, sizeof(struct nb_rpt_hdr)); - } - - RTW_DBG("WNM: bssid(" MAC_FMT - ") , bss_info(0x%04X), reg_class(0x%02X), ch_num(%d), phy_type(0x%02X)\n", - MAC_ARG(pnb->nb_rpt[i].bssid), pnb->nb_rpt[i].bss_info, - pnb->nb_rpt[i].reg_class, pnb->nb_rpt[i].ch_num, - pnb->nb_rpt[i].phy_type); - - if (pnb->nb_rpt[i].ch_num == 0) - continue; - - for (j=0; jnb_rpt[i].ch_num == pnb->nb_rpt_ch_list[j].hw_value) { - is_found = _TRUE; - break; - } - } - - if (!is_found) { - pnb->nb_rpt_ch_list[pnb->nb_rpt_ch_list_num].hw_value = pnb->nb_rpt[i].ch_num; - pnb->nb_rpt_ch_list_num++; - } - } -} - -static void rtw_wnm_btm_candidate_select(_adapter *padapter) -{ - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); - struct wlan_network *pnetwork; - u8 bfound = _FALSE; - u32 i; - - for (i = 0; i < pnb->last_nb_rpt_entries; i++) { - pnetwork = rtw_find_network( - &(pmlmepriv->scanned_queue), - pnb->nb_rpt[i].bssid); - - if (pnetwork) { - bfound = _TRUE; - break; - } - } - - if (bfound) { - _rtw_memcpy(pnb->roam_target_addr, pnb->nb_rpt[i].bssid, ETH_ALEN); - RTW_INFO("WNM : select btm entry(%d) - %s("MAC_FMT", ch%u) rssi:%d\n" - , i - , pnetwork->network.Ssid.Ssid - , MAC_ARG(pnetwork->network.MacAddress) - , pnetwork->network.Configuration.DSConfig - , (int)pnetwork->network.Rssi); - } else - _rtw_memset(pnb->roam_target_addr,0, ETH_ALEN); -} - -u32 rtw_wnm_btm_candidates_survey( - _adapter *padapter, u8* pframe, u32 elem_len, u8 from_btm) -{ - struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); - struct wnm_btm_cant *pcandidate_list = NULL; - u8 nb_rpt_is_same = _TRUE; - u32 ret = _FAIL; - u32 nb_rpt_entries = 0; - - if (from_btm) { - u32 mlen = sizeof(struct wnm_btm_cant) * RTW_MAX_NB_RPT_NUM; - pcandidate_list = (struct wnm_btm_cant *)rtw_malloc(mlen); - if (pcandidate_list == NULL) - goto exit; - } - - /*clean the status set last time*/ - _rtw_memset(&pnb->nb_rpt_ch_list, 0, sizeof(pnb->nb_rpt_ch_list)); - pnb->nb_rpt_valid = _FALSE; - if (!rtw_wnm_nb_elem_parsing( - pframe, elem_len, from_btm, - &nb_rpt_entries, &nb_rpt_is_same, - pnb, pcandidate_list)) - goto exit; - - if (nb_rpt_entries != 0) { - if ((from_btm) && (rtw_wnm_btm_preference_cap(padapter))) - rtw_wnm_candidates_sorting(nb_rpt_entries, pcandidate_list); - - rtw_wnm_nb_info_update( - nb_rpt_entries, from_btm, - pnb, pcandidate_list, &nb_rpt_is_same); - } - - RTW_INFO("nb_rpt_is_same = %d, nb_rpt_entries = %d, last_nb_rpt_entries = %d\n", - nb_rpt_is_same, nb_rpt_entries, pnb->last_nb_rpt_entries); - if ((nb_rpt_is_same == _TRUE) && (nb_rpt_entries == pnb->last_nb_rpt_entries)) - pnb->nb_rpt_is_same = _TRUE; - else { - pnb->nb_rpt_is_same = _FALSE; - pnb->last_nb_rpt_entries = nb_rpt_entries; - } - - if ((from_btm) && (nb_rpt_entries != 0)) - rtw_wnm_btm_candidate_select(padapter); - - pnb->nb_rpt_valid = _TRUE; - ret = _SUCCESS; - -exit: - if (from_btm && pcandidate_list) - rtw_mfree((u8 *)pcandidate_list, sizeof(struct wnm_btm_cant) * RTW_MAX_NB_RPT_NUM); - - return ret; -} -#endif - unsigned int OnAction_ft(_adapter *padapter, union recv_frame *precv_frame) { #ifdef CONFIG_RTW_80211R @@ -6924,7 +7103,7 @@ unsigned int OnAction_ft(_adapter *padapter, union recv_frame *precv_frame) u8 category = 0; u8 *pframe = NULL; u8 *pframe_body = NULL; - u8 sta_addr[ETH_ALEN] = {0}; + u8 tgt_addr[ETH_ALEN]; u8 *pie = NULL; u32 ft_ie_len = 0; u32 status_code = 0; @@ -6962,8 +7141,9 @@ unsigned int OnAction_ft(_adapter *padapter, union recv_frame *precv_frame) goto exit; } - if (is_zero_mac_addr(&pframe_body[8]) || is_broadcast_mac_addr(&pframe_body[8])) { - RTW_ERR("FT: Invalid Target MAC Address "MAC_FMT"\n", MAC_ARG(padapter->mlmepriv.roam_tgt_addr)); + _rtw_memcpy(tgt_addr, &pframe_body[8], ETH_ALEN); + if (is_zero_mac_addr(tgt_addr) || is_broadcast_mac_addr(tgt_addr)) { + RTW_ERR("FT: Invalid Target MAC Address "MAC_FMT"\n", MAC_ARG(tgt_addr)); goto exit; } @@ -7000,238 +7180,6 @@ exit: #endif } -#ifdef CONFIG_RTW_WNM -u8 rtw_wmn_btm_rsp_reason_decision(_adapter *padapter, u8* req_mode) -{ - struct recv_priv *precvpriv = &padapter->recvpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 reason = 0; - - if (!rtw_wnm_btm_diff_bss(padapter)) { - /* Reject - No suitable BSS transition candidates */ - reason = 7; - goto candidate_remove; - } - -#ifdef CONFIG_RTW_80211R - if (rtw_ft_chk_flags(padapter, RTW_FT_BTM_ROAM)) { - /* Accept */ - reason = 0; - goto under_survey; - } -#endif - - if (((*req_mode) & DISASSOC_IMMINENT) == 0) { - /* Reject - Unspecified reject reason */ - reason = 1; - goto candidate_remove; - } - - if (precvpriv->signal_strength_data.avg_val >= pmlmepriv->roam_rssi_threshold) { - reason = 1; - goto candidate_remove; - } - -under_survey: - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { - RTW_INFO("%s reject due to _FW_UNDER_SURVEY\n", __func__); - reason = 1; - } - -candidate_remove: - if (reason !=0) - rtw_wnm_reset_btm_candidate(&padapter->mlmepriv.nb_info); - - return reason; -} - -static u32 rtw_wnm_btm_candidates_offset_get(u8* pframe) -{ - u8 *pos = pframe; - u32 offset = 0; - - if (!pframe) - return 0; - - offset += 7; - pos += offset; - - /* BSS Termination Duration check */ - if (wnm_btm_bss_term_inc(pframe)) { - offset += 12; - pos += offset; - } - - /* Session Information URL check*/ - if (wnm_btm_ess_disassoc_im(pframe)) { - /*URL length field + URL variable length*/ - offset = 1 + *(pframe + offset); - pos += offset; - } - - offset = (pos - pframe); - return offset; -} - -static void rtw_wnm_btm_req_hdr_parsing(u8* pframe, struct btm_req_hdr *phdr) -{ - u8 *pos = pframe; - u32 offset = 0; - - if (!pframe || !phdr) - return; - - _rtw_memset(phdr, 0, sizeof(struct btm_req_hdr)); - phdr->req_mode = wnm_btm_req_mode(pframe); - phdr->disassoc_timer = wnm_btm_disassoc_timer(pframe); - phdr->validity_interval = wnm_btm_valid_interval(pframe); - if (wnm_btm_bss_term_inc(pframe)) { - _rtw_memcpy(&phdr->term_duration, - wnm_btm_term_duration_offset(pframe), - sizeof(struct btm_term_duration)); - } - - RTW_DBG("WNM: req_mode(%1x), disassoc_timer(%02x), interval(%x)\n", - phdr->req_mode, phdr->disassoc_timer, phdr->validity_interval); - if (wnm_btm_bss_term_inc(pframe)) - RTW_INFO("WNM: tsf(%llx), duration(%2x)\n", - phdr->term_duration.tsf, phdr->term_duration.duration); -} - -void rtw_wnm_roam_scan_hdl(void *ctx) -{ - _adapter *padapter = (_adapter *)ctx; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - - if (rtw_is_scan_deny(padapter)) - RTW_INFO("WNM: roam scan would abort by scan_deny!\n"); - - pmlmepriv->need_to_roam = _TRUE; - rtw_drv_scan_by_self(padapter, RTW_AUTO_SCAN_REASON_ROAM); -} - -static void rtw_wnm_roam_scan(_adapter *padapter) -{ - struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); - - if (rtw_is_scan_deny(padapter)) { - _cancel_timer_ex(&pnb->roam_scan_timer); - _set_timer(&pnb->roam_scan_timer, 1000); - } else - rtw_wnm_roam_scan_hdl((void *)padapter); -} - -void rtw_wnm_process_btm_req(_adapter *padapter, u8* pframe, u32 frame_len) -{ - struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); - struct btm_req_hdr req_hdr; - u8 *ptr, reason; - u32 elem_len, offset; - - rtw_wnm_btm_req_hdr_parsing(pframe, &req_hdr); - offset = rtw_wnm_btm_candidates_offset_get(pframe); - if ((offset == 0) || ((frame_len - offset) <= 15)) - return; - - ptr = (pframe + offset); - elem_len = (frame_len - offset); - rtw_wnm_btm_candidates_survey(padapter, ptr, elem_len, _TRUE); - reason = rtw_wmn_btm_rsp_reason_decision(padapter, &pframe[3]); - rtw_wnm_issue_action(padapter, - RTW_WLAN_ACTION_WNM_BTM_RSP, reason); - - if (reason == 0) - rtw_wnm_roam_scan(padapter); -} - -void rtw_wnm_reset_btm_candidate(struct roam_nb_info *pnb) -{ - pnb->preference_en = _FALSE; - _rtw_memset(pnb->roam_target_addr, 0, ETH_ALEN); -} - -void rtw_wnm_reset_btm_state(_adapter *padapter) -{ - struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); - - pnb->last_nb_rpt_entries = 0; - pnb->nb_rpt_is_same = _TRUE; - pnb->nb_rpt_valid = _FALSE; - pnb->nb_rpt_ch_list_num = 0; - rtw_wnm_reset_btm_candidate(pnb); - _rtw_memset(&pnb->nb_rpt, 0, sizeof(pnb->nb_rpt)); - _rtw_memset(&pnb->nb_rpt_ch_list, 0, sizeof(pnb->nb_rpt_ch_list)); -} - -void rtw_wnm_issue_action(_adapter *padapter, u8 action, u8 reason) -{ - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct xmit_frame *pmgntframe; - struct rtw_ieee80211_hdr *pwlanhdr; - struct pkt_attrib *pattrib; - u8 category, dialog_token, termination_delay, *pframe; - u16 *fctrl; - - if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) - return ; - - pattrib = &(pmgntframe->attrib); - update_mgntframe_attrib(padapter, pattrib); - _rtw_memset(pmgntframe->buf_addr, 0, (WLANHDR_OFFSET + TXDESC_OFFSET)); - - pframe = (u8 *)(pmgntframe->buf_addr + TXDESC_OFFSET); - pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; - - fctrl = &(pwlanhdr->frame_ctl); - *(fctrl) = 0; - - _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); - - SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); - pmlmeext->mgnt_seq++; - set_frame_sub_type(pframe, WIFI_ACTION); - - pframe += sizeof(struct rtw_ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); - - category = RTW_WLAN_CATEGORY_WNM; - pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); - pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); - - switch (action) { - case RTW_WLAN_ACTION_WNM_BTM_QUERY: - pframe = rtw_set_fixed_ie(pframe, 1, &(dialog_token), &(pattrib->pktlen)); - pframe = rtw_set_fixed_ie(pframe, 1, &(reason), &(pattrib->pktlen)); - RTW_INFO("WNM: RTW_WLAN_ACTION_WNM_BTM_QUERY sent.\n"); - break; - case RTW_WLAN_ACTION_WNM_BTM_RSP: - termination_delay = 0; - pframe = rtw_set_fixed_ie(pframe, 1, &(dialog_token), &(pattrib->pktlen)); - pframe = rtw_set_fixed_ie(pframe, 1, &(reason), &(pattrib->pktlen)); - pframe = rtw_set_fixed_ie(pframe, 1, &(termination_delay), &(pattrib->pktlen)); - if (!is_zero_mac_addr(pmlmepriv->nb_info.roam_target_addr)) { - pframe = rtw_set_fixed_ie(pframe, 6, - pmlmepriv->nb_info.roam_target_addr, &(pattrib->pktlen)); - } - RTW_INFO("WNM: RTW_WLAN_ACTION_WNM_BTM_RSP sent. reason = %d\n", reason); - break; - default: - goto exit; - } - - pattrib->last_txcmdsz = pattrib->pktlen; - dump_mgntframe(padapter, pmgntframe); - -exit: - return; -} -#endif - unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame) { u8 *pframe = precv_frame->u.hdr.rx_data; @@ -7444,6 +7392,149 @@ unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame) } +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT +unsigned int OnAction_tbtx_token(_adapter *padapter, union recv_frame *precv_frame) +{ +#define TOKEN_REQ 0x00 +#define TOKEN_REL 0x01 + + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta; + u32 xmit_time; + u8 *src=NULL, *pframe = precv_frame->u.hdr.rx_data; + u8 tbtx_action_code; + u8 i, nr_send; + uint tx_duration = 0; + + if (padapter->tbtx_capability == _FALSE) + goto exit; + + tbtx_action_code = *(pframe + WLAN_HDR_A3_LEN + 1); + + + switch (tbtx_action_code) + { + case TOKEN_REQ: + // parse duration + tx_duration = le32_to_cpu(*(uint *)(pframe + WLAN_HDR_A3_LEN + 2)); + padapter->tbtx_duration = tx_duration/1000; // Mirocsecond to Millisecond + ATOMIC_SET(&padapter->tbtx_tx_pause, _FALSE); + rtw_tx_control_cmd(padapter); + _set_timer(&pmlmeext->tbtx_xmit_timer, padapter->tbtx_duration); + ATOMIC_SET(&padapter->tbtx_remove_tx_pause, _FALSE); +#if defined(CONFIG_SDIO_HCI) && !defined(CONFIG_SDIO_TX_TASKLET) + _rtw_up_sema(&pxmitpriv->SdioXmitSema); +#else + tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); +#endif + break; +#ifdef CONFIG_AP_MODE + case TOKEN_REL: + src = get_addr2_ptr(pframe); + if (!src) + goto exit; + psta = rtw_get_stainfo(&padapter->stapriv, src); + if (!psta) + goto exit; + + if (ATOMIC_READ(&pstapriv->nr_token_keeper) < 1) + goto exit; + + for (i=0; i< NR_MAXSTA_INSLOT; i++) { + if (pstapriv->token_holder[i] == psta) { + pstapriv->token_holder[i] = NULL; + //RTW_INFO("macaddr1:" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr)); + ATOMIC_DEC(&pstapriv->nr_token_keeper); + break; + } + } + + if (ATOMIC_READ(&pstapriv->nr_token_keeper) == 0) + _set_timer(&pmlmeext->tbtx_token_dispatch_timer, 1); + + break; +#endif + default: + RTW_INFO("Undefined Action Code\n"); + goto exit; + break; + } + +exit: + return _SUCCESS; +} + +void rtw_issue_action_token_rel(_adapter *padapter) +{ + + // Todo: + // gen token + /* Token Release Format + Category code : 1 Byte + Action code : 1 Byte */ + int ret = _FAIL; + //u16 *fctrl; + u8 val = 0x01; + u8 category = RTW_WLAN_CATEGORY_TBTX; + u8 *pframe; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct rtw_ieee80211_hdr *pwlanhdr; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + //struct sta_info *psta; + //struct sta_priv *pstapriv = &padapter->stapriv; + //struct registry_priv *pregpriv = &padapter->registrypriv; + + if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter))) + return; + + pmgntframe = alloc_mgtxmitframe(pxmitpriv); + if (pmgntframe == NULL) + return; + + /*update attribute */ + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + pattrib->rate = MGN_24M; /* issue action release using OFDM rate? 20190716 Bruce add */ + + _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); + + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + //fctrl = &(pwlanhdr->frame_ctl); + //*(fctrl) = 0; + + _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + // SetSeqNum?? + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + set_frame_sub_type(pframe, WIFI_ACTION); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(val), &(pattrib->pktlen)); + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + //RTW_INFO("%s\n", __func__); + +} +#endif + unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame) { int i; @@ -7594,12 +7685,35 @@ void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib) } +#ifdef CONFIG_RTW_MGMT_QUEUE +void update_mgntframe_subtype(_adapter *padapter, struct xmit_frame *pmgntframe) +{ + struct pkt_attrib *pattrib = &pmgntframe->attrib; + u8 *pframe; + u8 subtype, category ,action; + + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + subtype = get_frame_sub_type(pframe); /* bit(7)~bit(2) */ + pattrib->subtype = subtype; + + rtw_action_frame_parse(pframe, pattrib->pktlen, &category, &action); + + if ((subtype == WIFI_ACTION && !(action == ACT_PUBLIC_FTM_REQ || action == ACT_PUBLIC_FTM)) || + subtype == WIFI_DISASSOC || subtype == WIFI_DEAUTH || + (subtype == WIFI_PROBERSP && MLME_IS_ADHOC(padapter))) + pattrib->ps_dontq = 0; + else + pattrib->ps_dontq = 1; +} +#endif void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib) { u8 wireless_mode; struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta; #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP struct wifidirect_info *pwdinfo = &(padapter->wdinfo); @@ -7627,8 +7741,6 @@ void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib) struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); - struct sta_priv *pstapriv = &padapter->stapriv; - struct sta_info *psta; psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress); if (psta) { @@ -7643,7 +7755,6 @@ void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib) } #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */ - pattrib->pktlen = 0; if (IS_CCK_RATE(pmlmeext->tx_rate)) @@ -7668,14 +7779,17 @@ void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib) pattrib->mbssid = 0; pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no; +#ifdef CONFIG_RTW_MGMT_QUEUE + pattrib->ps_dontq = 1; +#endif } void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe) { - u8 *pframe; - struct pkt_attrib *pattrib = &pmgntframe->attrib; -#if defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) - struct sta_info *sta = NULL; + u8 *pframe; + struct pkt_attrib *pattrib = &pmgntframe->attrib; +#if defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) || defined(CONFIG_RTW_MGMT_QUEUE) + struct sta_info *sta = NULL; #endif pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; @@ -7683,17 +7797,18 @@ void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntfr _rtw_memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN); _rtw_memcpy(pattrib->ta, get_addr2_ptr(pframe), ETH_ALEN); -#if defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) +#if defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) || defined(CONFIG_RTW_MGMT_QUEUE) sta = pattrib->psta; if (!sta) { sta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); pattrib->psta = sta; } + #ifdef CONFIG_BEAMFORMING if (sta) update_attrib_txbf_info(padapter, pattrib, sta); #endif -#endif /* defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) */ +#endif /* defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) || defined(CONFIG_RTW_MGMT_QUEUE) */ } void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe) @@ -7726,7 +7841,11 @@ s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, i ret = rtw_hal_mgnt_xmit(padapter, pmgntframe); - if (ret == _SUCCESS) + if (ret == _SUCCESS +#ifdef CONFIG_RTW_MGMT_QUEUE + || ret == RTW_QUEUE_MGMT +#endif + ) ret = rtw_sctx_wait(&sctx, __func__); _enter_critical(&pxmitpriv->lock_sctx, &irqL); @@ -7754,7 +7873,14 @@ s32 dump_mgntframe_and_wait_ack_timeout(_adapter *padapter, struct xmit_frame *p pxmitpriv->seq_no = seq_no++; pmgntframe->ack_report = 1; rtw_sctx_init(&(pxmitpriv->ack_tx_ops), timeout_ms); - if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) + + ret = rtw_hal_mgnt_xmit(padapter, pmgntframe); + + if (ret == _SUCCESS +#ifdef CONFIG_RTW_MGMT_QUEUE + || ret == RTW_QUEUE_MGMT +#endif + ) ret = rtw_sctx_wait(&(pxmitpriv->ack_tx_ops), __func__); pxmitpriv->ack_tx = _FALSE; @@ -7810,6 +7936,7 @@ int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode) return len_diff; } +#ifdef CONFIG_AP_MODE void issue_beacon(_adapter *padapter, int timeout_ms) { struct xmit_frame *pmgntframe; @@ -8007,12 +8134,6 @@ void issue_beacon(_adapter *padapter, int timeout_ms) _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS); } -#ifdef CONFIG_RTW_80211K - pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_, - sizeof(padapter->rmpriv.rm_en_cap_def), - padapter->rmpriv.rm_en_cap_def, &pattrib->pktlen); -#endif - #ifdef CONFIG_P2P if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { u32 len; @@ -8052,6 +8173,11 @@ void issue_beacon(_adapter *padapter, int timeout_ms) pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen ); #endif/*CONFIG_RTL8812A*/ +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (padapter->tbtx_capability == _TRUE) + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 8, REALTEK_TBTX_IE, &pattrib->pktlen); +#endif + goto _issue_bcn; } @@ -8131,6 +8257,7 @@ _issue_bcn: dump_mgntframe(padapter, pmgntframe); } +#endif /* CONFIG_AP_MODE */ void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq) { @@ -8331,12 +8458,6 @@ void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probe } -#ifdef CONFIG_RTW_80211K - pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_, - sizeof(padapter->rmpriv.rm_en_cap_def), - padapter->rmpriv.rm_en_cap_def, &pattrib->pktlen); -#endif - #ifdef CONFIG_P2P if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) /* IOT issue, When wifi_spec is not set, send probe_resp with P2P IE even if probe_req has no P2P IE */ @@ -8427,7 +8548,7 @@ int _issue_probereq(_adapter *padapter, const NDIS_802_11_SSID *pssid, const u8 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); int bssrate_len = 0; u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; -#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI +#if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND) struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); #endif @@ -8448,10 +8569,10 @@ int _issue_probereq(_adapter *padapter, const NDIS_802_11_SSID *pssid, const u8 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; -#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI +#if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND) if ((pwdev_priv->pno_mac_addr[0] != 0xFF) && (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) - && (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _FALSE)) + && (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _FALSE)) mac = pwdev_priv->pno_mac_addr; else #endif @@ -8472,10 +8593,10 @@ int _issue_probereq(_adapter *padapter, const NDIS_802_11_SSID *pssid, const u8 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN); -#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI +#if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND) if ((pwdev_priv->pno_mac_addr[0] != 0xFF) && (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) - && (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _FALSE)) { + && (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _FALSE)) { #ifdef CONFIG_RTW_DEBUG RTW_DBG("%s pno_scan_seq_num: %d\n", __func__, pwdev_priv->pno_scan_seq_num); @@ -8538,6 +8659,10 @@ int _issue_probereq(_adapter *padapter, const NDIS_802_11_SSID *pssid, const u8 #endif/*CONFIG_RTL8812A*/ +#ifdef CONFIG_RTW_MBO + rtw_mbo_build_probe_req_ies( padapter, &pframe, pattrib); +#endif + pattrib->last_txcmdsz = pattrib->pktlen; @@ -8774,7 +8899,7 @@ void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *p struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network); - u8 *ie = pnetwork->IEs; + u8 *ie = pnetwork->IEs, cap[5], i; #ifdef CONFIG_P2P struct wifidirect_info *pwdinfo = &(padapter->wdinfo); #ifdef CONFIG_WFD @@ -8823,7 +8948,9 @@ void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *p /* capability */ val = *(unsigned short *)rtw_get_capability_from_ie(ie); - +#ifdef CONFIG_RTW_80211K + val |= cap_RM; +#endif pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen)); ie_status = cpu_to_le16(status); @@ -8912,6 +9039,17 @@ void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *p } #endif /* CONFIG_80211AC_VHT */ +#ifdef CONFIG_RTW_80211K + /* FILL RM Enabled Capabilities with joint capabilities */ + for (i = 0; i < 5; i++) { + cap[i] = padapter->rmpriv.rm_en_cap_def[i] + & pstat->rm_en_cap[i]; + } + if (pstat->capability & cap_RM) + pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_, 5, + (u8 *)cap, &(pattrib->pktlen)); +#endif /* CONFIG_RTW_80211K */ + /* FILL WMM IE */ if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) { uint ie_len = 0; @@ -8970,6 +9108,12 @@ void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *p #endif #endif /* CONFIG_P2P */ + +#ifdef CONFIG_RTW_MULTI_AP + if (padapter->multi_ap && (pstat->flags & WLAN_STA_MULTI_AP)) + pframe = rtw_set_multi_ap_ie_ext(pframe, &pattrib->pktlen, padapter->multi_ap); +#endif + #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_ASSOCRESP_VENDOR_IE_BIT); #endif @@ -8979,6 +9123,11 @@ void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *p #endif/*CONFIG_RTL8812A*/ +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (padapter->tbtx_capability == _TRUE) + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 8, REALTEK_TBTX_IE, &pattrib->pktlen); +#endif + pattrib->last_txcmdsz = pattrib->pktlen; dump_mgntframe(padapter, pmgntframe); @@ -8994,7 +9143,7 @@ static u32 rtw_append_assoc_req_owe_ie(_adapter *adapter, u8 *pbuf) if (sec == NULL) goto exit; - if (&(sec->owe_ie) != NULL && sec->owe_ie_len > 0) { + if (sec->owe_ie_len > 0) { len = sec->owe_ie_len; _rtw_memcpy(pbuf, sec->owe_ie, len); } @@ -9045,7 +9194,6 @@ void _issue_assocreq(_adapter *padapter, u8 is_reassoc) pattrib = &pmgntframe->attrib; update_mgntframe_attrib(padapter, pattrib); - _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; @@ -9072,6 +9220,9 @@ void _issue_assocreq(_adapter *padapter, u8 is_reassoc) #if CONFIG_DFS _rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2); cap |= cap_SpecMgmt; +#ifdef CONFIG_RTW_80211K + cap |= cap_RM; +#endif _rtw_memcpy(pframe, &cap, 2); #else _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2); @@ -9205,14 +9356,16 @@ void _issue_assocreq(_adapter *padapter, u8 is_reassoc) else RTW_INFO("%s: Connect to AP without 11b and 11g data rate!\n", __FUNCTION__); +#ifdef CONFIG_RTW_MBO + rtw_mbo_build_assoc_req_ies(padapter, &pframe, pattrib); +#endif +#ifdef CONFIG_RTW_80211R + rtw_ft_build_assoc_req_ies(padapter, is_reassoc, pattrib, &pframe); +#endif #ifdef CONFIG_RTW_80211K - if (pmlmeinfo->network.PhyInfo.rm_en_cap[0] /* RM Enabled Capabilities */ - | pmlmeinfo->network.PhyInfo.rm_en_cap[1] - | pmlmeinfo->network.PhyInfo.rm_en_cap[2] - | pmlmeinfo->network.PhyInfo.rm_en_cap[3] - | pmlmeinfo->network.PhyInfo.rm_en_cap[4]) - pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_, 5, - (u8 *)padapter->rmpriv.rm_en_cap_def, &(pattrib->pktlen)); + pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_, 5, + (u8 *)padapter->rmpriv.rm_en_cap_def, + &(pattrib->pktlen)); #endif /* CONFIG_RTW_80211K */ /* vendor specific IE, such as WPA, WMM, WPS */ @@ -9246,7 +9399,7 @@ void _issue_assocreq(_adapter *padapter, u8 is_reassoc) { #ifdef CONFIG_IOCTL_CFG80211 if (rtw_sec_chk_auth_alg(padapter, WLAN_AUTH_OPEN) && - rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE)) { + rtw_sec_chk_auth_type(padapter, MLME_AUTHTYPE_SAE)) { s32 entry = rtw_cached_pmkid(padapter, pmlmepriv->assoc_bssid); rtw_rsn_sync_pmkid(padapter, (u8 *)pIE, (pIE->Length + 2), entry); @@ -9254,6 +9407,8 @@ void _issue_assocreq(_adapter *padapter, u8 is_reassoc) #endif /* CONFIG_IOCTL_CFG80211 */ pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen)); + /* tmp: update rsn's spp related opt. */ + /*rtw_set_spp_amsdu_mode(padapter->registrypriv.amsdu_mode, pframe - (pIE->Length + 2), pIE->Length +2);*/ } break; #ifdef CONFIG_80211N_HT @@ -9291,6 +9446,10 @@ void _issue_assocreq(_adapter *padapter, u8 is_reassoc) i += (pIE->Length + 2); } +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (padapter->tbtx_capability == _TRUE) + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 8 , REALTEK_TBTX_IE, &(pattrib->pktlen)); +#endif if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen)); @@ -9448,6 +9607,11 @@ void _issue_assocreq(_adapter *padapter, u8 is_reassoc) #endif #endif /* CONFIG_P2P */ +#ifdef CONFIG_RTW_MULTI_AP + if (padapter->multi_ap) + pframe = rtw_set_multi_ap_ie_ext(pframe, &pattrib->pktlen, padapter->multi_ap); +#endif + /* OWE */ { u32 owe_ie_len; @@ -9468,19 +9632,19 @@ void _issue_assocreq(_adapter *padapter, u8 is_reassoc) pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen ); #endif/*CONFIG_RTL8812A*/ -#ifdef CONFIG_RTW_80211R - rtw_ft_build_assoc_req_ies(padapter, is_reassoc, pattrib, &pframe); -#endif - pattrib->last_txcmdsz = pattrib->pktlen; dump_mgntframe(padapter, pmgntframe); ret = _SUCCESS; exit: - if (ret == _SUCCESS) + if (ret == _SUCCESS) { rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen); - else + #ifdef CONFIG_RTW_WNM + if (is_reassoc == _TRUE) + rtw_wnm_update_reassoc_req_ie(padapter); + #endif + } else rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len); return; @@ -9855,7 +10019,7 @@ static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short r pattrib->last_txcmdsz = pattrib->pktlen; - pmlmeext->last_deauth_time = rtw_get_current_time(); + if (wait_ack) ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); else { @@ -9869,7 +10033,7 @@ exit: int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason) { - RTW_INFO("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); + RTW_INFO("%s reason(%u) to "MAC_FMT"\n", __func__, reason, MAC_ARG(da)); return _issue_deauth(padapter, da, reason, _FALSE, IEEE80211W_RIGHT_KEY); } @@ -10172,6 +10336,12 @@ static int issue_action_ba(_adapter *padapter, unsigned char *raddr, unsigned ch else /* TX AMSDU disabled */ BA_para_set &= ~BIT(0); #endif + + psta = rtw_get_stainfo(pstapriv, raddr); + if (psta != NULL) { + if (psta->flags & WLAN_STA_AMSDU_DISABLE) + BA_para_set &= ~BIT(0); + } BA_para_set = cpu_to_le16(BA_para_set); pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen)); @@ -10191,9 +10361,6 @@ static int issue_action_ba(_adapter *padapter, unsigned char *raddr, unsigned ch BA_starting_seqctrl = start_seq << 4; } - else { - break; - } BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl); pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen)); @@ -10219,6 +10386,12 @@ static int issue_action_ba(_adapter *padapter, unsigned char *raddr, unsigned ch BA_para_set |= BIT(0); } + psta = rtw_get_stainfo(pstapriv, raddr); + if (psta != NULL) { + if (psta->flags & WLAN_STA_AMSDU_DISABLE) + BA_para_set &= ~BIT(0); + } + BA_para_set = cpu_to_le16(BA_para_set); pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen)); @@ -10809,6 +10982,7 @@ unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr) return _SUCCESS; } +#ifdef CONFIG_AP_MODE unsigned int send_beacon(_adapter *padapter) { #if defined(CONFIG_PCI_HCI) && !defined(CONFIG_PCI_BCN_POLLING) @@ -10938,6 +11112,7 @@ unsigned int send_beacon(_adapter *padapter) #endif /*defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)*/ } +#endif /* CONFIG_AP_MODE */ /**************************************************************************** @@ -10973,11 +11148,13 @@ u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSI u8 *pframe = precv_frame->u.hdr.rx_data; u32 packet_len = precv_frame->u.hdr.len; u8 ie_offset; - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); struct registry_priv *pregistrypriv = &padapter->registrypriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - +#ifdef CONFIG_LAYER2_ROAMING + u32 *pbuf; +#endif len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr); @@ -11022,7 +11199,7 @@ u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSI /* get rx_snr */ if (precv_frame->u.hdr.attrib.data_rate >= DESC_RATE11M) { bssid->PhyInfo.is_cck_rate = 0; - for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) + for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) bssid->PhyInfo.rx_snr[rf_path] = precv_frame->u.hdr.attrib.phy_info.rx_snr[rf_path]; } else @@ -11059,11 +11236,13 @@ u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSI RTW_INFO("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len); return _FAIL; } +#ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT if (rtw_validate_value(_SUPPORTEDRATES_IE_, p+2, len) == _FALSE) { rtw_absorb_ssid_ifneed(padapter, bssid, pframe); RTW_DBG_DUMP("Invalidated Support Rate IE --", p, len+2); return _FAIL; } +#endif /* #ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT */ _rtw_memcpy(bssid->SupportedRates, (p + 2), len); i = len; } @@ -11074,11 +11253,13 @@ u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSI RTW_INFO("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len); return _FAIL; } +#ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT if (rtw_validate_value(_EXT_SUPPORTEDRATES_IE_, p+2, len) == _FALSE) { rtw_absorb_ssid_ifneed(padapter, bssid, pframe); RTW_DBG_DUMP("Invalidated EXT Support Rate IE --", p, len+2); return _FAIL; } +#endif /* #ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT */ _rtw_memcpy(bssid->SupportedRates + i, (p + 2), len); } @@ -11227,10 +11408,17 @@ u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSI /* save freerun counter */ bssid->PhyInfo.free_cnt = precv_frame->u.hdr.attrib.free_cnt; +#endif +#ifdef CONFIG_LAYER2_ROAMING + pbuf = (u32 *)((u8 *)pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + bssid->tsf = le32_to_cpu(*(pbuf + 1)); + bssid->tsf = bssid->tsf << 32; + bssid->tsf |= le32_to_cpu(*pbuf); #endif return _SUCCESS; } +#ifdef CONFIG_AP_MODE void start_create_ibss(_adapter *padapter) { unsigned short caps; @@ -11295,6 +11483,7 @@ void start_create_ibss(_adapter *padapter) update_bmc_sta(padapter); } +#endif /* CONFIG_AP_MODE */ void start_clnt_join(_adapter *padapter) { @@ -11433,7 +11622,7 @@ void start_clnt_auth(_adapter *padapter) RTW_PRINT("start auth\n"); #ifdef CONFIG_IOCTL_CFG80211 - if (rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE)) { + if (rtw_sec_chk_auth_type(padapter, MLME_AUTHTYPE_SAE)) { if (rtw_cached_pmkid(padapter, get_my_bssid(&pmlmeinfo->network)) != -1) { RTW_INFO("SAE: PMKSA cache entry found\n"); padapter->securitypriv.auth_alg = WLAN_AUTH_OPEN; @@ -11465,7 +11654,11 @@ void start_clnt_assoc(_adapter *padapter) pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE); #ifdef CONFIG_RTW_80211R - if (rtw_ft_roam(padapter)) + if (rtw_ft_roam(padapter) + #ifdef CONFIG_RTW_WNM + || rtw_wnm_btm_reassoc_req(padapter) + #endif + ) issue_reassocreq(padapter); else #endif @@ -11535,10 +11728,10 @@ Following are the functions to report events void report_survey_event(_adapter *padapter, union recv_frame *precv_frame) { struct cmd_obj *pcmd_obj; - u8 *pevtcmd; + u8 *pevtcmd; u32 cmdsz; - struct survey_event *psurvey_evt; - struct C2HEvent_Header *pc2h_evt_hdr; + struct survey_event *psurvey_evt; + struct rtw_evt_header *evt_hdr; struct mlme_ext_priv *pmlmeext; struct cmd_priv *pcmdpriv; /* u8 *pframe = precv_frame->u.hdr.rx_data; */ @@ -11554,7 +11747,7 @@ void report_survey_event(_adapter *padapter, union recv_frame *precv_frame) if (pcmd_obj == NULL) return; - cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header)); + cmdsz = (sizeof(struct survey_event) + sizeof(struct rtw_evt_header)); pevtcmd = (u8 *)rtw_zmalloc(cmdsz); if (pevtcmd == NULL) { rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); @@ -11563,19 +11756,19 @@ void report_survey_event(_adapter *padapter, union recv_frame *precv_frame) _rtw_init_listhead(&pcmd_obj->list); - pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdcode = CMD_SET_MLME_EVT; pcmd_obj->cmdsz = cmdsz; pcmd_obj->parmbuf = pevtcmd; pcmd_obj->rsp = NULL; pcmd_obj->rspsz = 0; - pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); - pc2h_evt_hdr->len = sizeof(struct survey_event); - pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey); - pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + evt_hdr = (struct rtw_evt_header *)(pevtcmd); + evt_hdr->len = sizeof(struct survey_event); + evt_hdr->id = EVT_SURVEY; + evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); - psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); + psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct rtw_evt_header)); if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL) { rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); @@ -11602,15 +11795,15 @@ void report_surveydone_event(_adapter *padapter, bool acs) u8 *pevtcmd; u32 cmdsz; struct surveydone_event *psurveydone_evt; - struct C2HEvent_Header *pc2h_evt_hdr; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct rtw_evt_header *evt_hdr; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); if (pcmd_obj == NULL) return; - cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header)); + cmdsz = (sizeof(struct surveydone_event) + sizeof(struct rtw_evt_header)); pevtcmd = (u8 *)rtw_zmalloc(cmdsz); if (pevtcmd == NULL) { rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); @@ -11619,20 +11812,21 @@ void report_surveydone_event(_adapter *padapter, bool acs) _rtw_init_listhead(&pcmd_obj->list); - pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdcode = CMD_SET_MLME_EVT; pcmd_obj->cmdsz = cmdsz; pcmd_obj->parmbuf = pevtcmd; pcmd_obj->rsp = NULL; pcmd_obj->rspsz = 0; - pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); - pc2h_evt_hdr->len = sizeof(struct surveydone_event); - pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone); - pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + evt_hdr = (struct rtw_evt_header *)(pevtcmd); + evt_hdr->len = sizeof(struct surveydone_event); + evt_hdr->id = EVT_SURVEY_DONE; + evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); - psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); + psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct rtw_evt_header)); psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt; + psurveydone_evt->activate_ch_cnt = pmlmeext->sitesurvey_res.activate_ch_cnt; psurveydone_evt->acs = acs; RTW_INFO("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter)); @@ -11648,19 +11842,18 @@ u32 report_join_res(_adapter *padapter, int aid_res, u16 status) struct cmd_obj *pcmd_obj; u8 *pevtcmd; u32 cmdsz; - struct joinbss_event *pjoinbss_evt; - struct C2HEvent_Header *pc2h_evt_hdr; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct joinbss_event *pjoinbss_evt; + struct rtw_evt_header *evt_hdr; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct cmd_priv *pcmdpriv = &padapter->cmdpriv; u32 ret = _FAIL; - int err = 0; pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); if (pcmd_obj == NULL) goto exit; - cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header)); + cmdsz = (sizeof(struct joinbss_event) + sizeof(struct rtw_evt_header)); pevtcmd = (u8 *)rtw_zmalloc(cmdsz); if (pevtcmd == NULL) { rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); @@ -11669,45 +11862,29 @@ u32 report_join_res(_adapter *padapter, int aid_res, u16 status) _rtw_init_listhead(&pcmd_obj->list); - pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdcode = CMD_SET_MLME_EVT; pcmd_obj->cmdsz = cmdsz; pcmd_obj->parmbuf = pevtcmd; pcmd_obj->rsp = NULL; pcmd_obj->rspsz = 0; - pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); - pc2h_evt_hdr->len = sizeof(struct joinbss_event); - pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss); - pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + evt_hdr = (struct rtw_evt_header *)(pevtcmd); + evt_hdr->len = sizeof(struct joinbss_event); + evt_hdr->id = EVT_JOINBSS; + evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); - pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); + pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct rtw_evt_header)); _rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX)); - pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = aid_res; + pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = aid_res; RTW_INFO("report_join_res(%d, %u)\n", aid_res, status); - err = rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network, status); - if (err) { - RTW_WARN(FUNC_ADPT_FMT": joinbss pre-handle fail!(err=%d) fw_state=0x%x\n", - FUNC_ADPT_ARG(padapter), err, get_fwstate(&padapter->mlmepriv)); - if (err == -1) { - rtw_mfree((u8 *)pevtcmd, sizeof(*pevtcmd)); - rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); - goto disconnect; - } - } + + rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network, status); + ret = rtw_enqueue_cmd(pcmdpriv, pcmd_obj); - goto exit; - -disconnect: - /* Follow rtw_indicate_disconnect flow */ - rtw_reset_securitypriv(padapter); - rtw_set_ips_deny(padapter, 3000); - _clr_fwstate_(&padapter->mlmepriv, _FW_LINKED); - rtw_clear_scan_deny(padapter); - ret = rtw_disassoc_cmd(padapter, 0, 0); exit: return ret; @@ -11716,18 +11893,18 @@ exit: void report_wmm_edca_update(_adapter *padapter) { struct cmd_obj *pcmd_obj; - u8 *pevtcmd; + u8 *pevtcmd; u32 cmdsz; - struct wmm_event *pwmm_event; - struct C2HEvent_Header *pc2h_evt_hdr; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct wmm_event *pwmm_event; + struct rtw_evt_header *evt_hdr; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); if (pcmd_obj == NULL) return; - cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header)); + cmdsz = (sizeof(struct wmm_event) + sizeof(struct rtw_evt_header)); pevtcmd = (u8 *)rtw_zmalloc(cmdsz); if (pevtcmd == NULL) { rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); @@ -11736,19 +11913,19 @@ void report_wmm_edca_update(_adapter *padapter) _rtw_init_listhead(&pcmd_obj->list); - pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdcode = CMD_SET_MLME_EVT; pcmd_obj->cmdsz = cmdsz; pcmd_obj->parmbuf = pevtcmd; pcmd_obj->rsp = NULL; pcmd_obj->rspsz = 0; - pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); - pc2h_evt_hdr->len = sizeof(struct wmm_event); - pc2h_evt_hdr->ID = GEN_EVT_CODE(_WMM); - pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + evt_hdr = (struct rtw_evt_header *)(pevtcmd); + evt_hdr->len = sizeof(struct wmm_event); + evt_hdr->id = EVT_WMM_UPDATE; + evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); - pwmm_event = (struct wmm_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); + pwmm_event = (struct wmm_event *)(pevtcmd + sizeof(struct rtw_evt_header)); pwmm_event->wmm = 0; rtw_enqueue_cmd(pcmdpriv, pcmd_obj); @@ -11760,30 +11937,30 @@ void report_wmm_edca_update(_adapter *padapter) u32 report_del_sta_event(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, bool enqueue, u8 locally_generated) { struct cmd_obj *pcmd_obj; - u8 *pevtcmd; + u8 *pevtcmd; u32 cmdsz; struct sta_info *psta; - int mac_id = -1; - struct stadel_event *pdel_sta_evt; - struct C2HEvent_Header *pc2h_evt_hdr; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + int mac_id = -1; + struct stadel_event *pdel_sta_evt; + struct rtw_evt_header *evt_hdr; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; u8 res = _SUCCESS; /* prepare cmd parameter */ - cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header)); + cmdsz = (sizeof(struct stadel_event) + sizeof(struct rtw_evt_header)); pevtcmd = (u8 *)rtw_zmalloc(cmdsz); if (pevtcmd == NULL) { res = _FAIL; goto exit; } - pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); - pc2h_evt_hdr->len = sizeof(struct stadel_event); - pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA); - pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + evt_hdr = (struct rtw_evt_header *)(pevtcmd); + evt_hdr->len = sizeof(struct stadel_event); + evt_hdr->id = EVT_DEL_STA; + evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); - pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); + pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct rtw_evt_header)); _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN); _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2); psta = rtw_get_stainfo(&padapter->stapriv, MacAddr); @@ -11807,7 +11984,7 @@ u32 report_del_sta_event(_adapter *padapter, unsigned char *MacAddr, unsigned sh } _rtw_init_listhead(&pcmd_obj->list); - pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdcode = CMD_SET_MLME_EVT; pcmd_obj->cmdsz = cmdsz; pcmd_obj->parmbuf = pevtcmd; @@ -11828,18 +12005,18 @@ exit: void report_add_sta_event(_adapter *padapter, unsigned char *MacAddr) { struct cmd_obj *pcmd_obj; - u8 *pevtcmd; + u8 *pevtcmd; u32 cmdsz; - struct stassoc_event *padd_sta_evt; - struct C2HEvent_Header *pc2h_evt_hdr; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct stassoc_event *padd_sta_evt; + struct rtw_evt_header *evt_hdr; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); if (pcmd_obj == NULL) return; - cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header)); + cmdsz = (sizeof(struct stassoc_event) + sizeof(struct rtw_evt_header)); pevtcmd = (u8 *)rtw_zmalloc(cmdsz); if (pevtcmd == NULL) { rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); @@ -11848,19 +12025,19 @@ void report_add_sta_event(_adapter *padapter, unsigned char *MacAddr) _rtw_init_listhead(&pcmd_obj->list); - pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdcode = CMD_SET_MLME_EVT; pcmd_obj->cmdsz = cmdsz; pcmd_obj->parmbuf = pevtcmd; pcmd_obj->rsp = NULL; pcmd_obj->rspsz = 0; - pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); - pc2h_evt_hdr->len = sizeof(struct stassoc_event); - pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA); - pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + evt_hdr = (struct rtw_evt_header *)(pevtcmd); + evt_hdr->len = sizeof(struct stassoc_event); + evt_hdr->id = EVT_ADD_STA; + evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); - padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); + padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct rtw_evt_header)); _rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN); RTW_INFO("report_add_sta_event: add STA\n"); @@ -12047,7 +12224,7 @@ void update_sta_info(_adapter *padapter, struct sta_info *psta) update_ldpc_stbc_cap(psta); _enter_critical_bh(&psta->lock, &irqL); - psta->state = _FW_LINKED; + psta->state = WIFI_ASOC_STATE; _exit_critical_bh(&psta->lock, &irqL); } @@ -12132,10 +12309,10 @@ static void rtw_mlmeext_disconnect(_adapter *padapter) rtw_dfs_rd_en_decision(padapter, self_action, 0); #endif - if (rtw_mi_get_ch_setting_union_no_self(padapter, &ch, &bw, &offset) != 0) { + if (rtw_mi_get_ch_setting_union_no_self(padapter, &ch, &bw, &offset) != 0) set_channel_bwmode(padapter, ch, offset, bw); - rtw_mi_update_union_chan_inf(padapter, ch, offset, bw); - } + rtw_mi_update_union_chan_inf(padapter, ch, offset, bw); + rtw_rfctl_update_op_mode(adapter_to_rfctl(padapter), BIT(padapter->iface_id), 0); } flush_all_cam_entry(padapter); @@ -12180,7 +12357,7 @@ void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res) u8 join_type; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; -#ifndef CONFIG_IOCTL_CFG80211 +#if (!defined(CONFIG_IOCTL_CFG80211)) || defined(CONFIG_LAYER2_ROAMING) struct security_priv *psecuritypriv = &padapter->securitypriv; #endif @@ -12204,11 +12381,12 @@ void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res) pmlmepriv->GetGatewayTryCnt = 0; #endif +#ifdef CONFIG_AP_MODE if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { /* update bc/mc sta_info */ update_bmc_sta(padapter); } - +#endif /* turn on dynamic functions */ /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); */ @@ -12296,10 +12474,30 @@ exit_mlmeext_joinbss_event_callback: rtw_rson_join_done(padapter); #endif -#ifdef CONFIG_PCI_DYNAMIC_ASPM - rtw_pci_dynamic_aspm_set_mode(padapter, ASPM_MODE_PERF); -#endif +#ifdef CONFIG_LAYER2_ROAMING + if ((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_) && + (pmlmepriv->roam_network)) { + struct xmit_frame *rframe; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + _list *plist, *phead; + _irqL irqL; + _pkt *pkt; + padapter->mlmepriv.roam_network = NULL; + _enter_critical_bh(&pxmitpriv->rpkt_queue.lock, &irqL); + phead = get_list_head(&pxmitpriv->rpkt_queue); + plist = get_next(phead); + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) { + rframe = LIST_CONTAINOR(plist, struct xmit_frame, list); + plist = get_next(plist); + rtw_list_delete(&rframe->list); + pkt = rframe->pkt; + rframe->pkt = NULL; + rtw_xmit_posthandle(padapter, rframe, pkt); + } + _exit_critical_bh(&pxmitpriv->rpkt_queue.lock, &irqL); + } +#endif RTW_INFO("=>%s - End to Connection without 4-way\n", __FUNCTION__); } @@ -12316,6 +12514,7 @@ void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta) if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { /* adhoc master or sta_count>1 */ /* nothing to do */ } else { /* adhoc client */ + #ifdef CONFIG_AP_MODE /* update TSF Value */ /* update_TSF(pmlmeext, pframe, len); */ @@ -12327,6 +12526,7 @@ void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta) rtw_warn_on(1); pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; + #endif } join_type = 2; @@ -12410,6 +12610,7 @@ void rtw_delba_check(_adapter *padapter, struct sta_info *psta, u8 from_timer) } } + u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta) { u8 ret = _FALSE; @@ -12596,15 +12797,20 @@ void linked_status_chk(_adapter *padapter, u8 from_timer) struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct sta_priv *pstapriv = &padapter->stapriv; -#if defined(CONFIG_ARP_KEEP_ALIVE) || defined(CONFIG_LAYER2_ROAMING) struct mlme_priv *pmlmepriv = &padapter->mlmepriv; -#endif #ifdef CONFIG_LAYER2_ROAMING struct recv_priv *precvpriv = &padapter->recvpriv; #endif +#ifdef CONFIG_RTW_WDS + rtw_wds_gptr_expire(padapter); +#endif + if (padapter->registrypriv.mp_mode == _TRUE) return; + + if (check_fwstate(pmlmepriv, WIFI_CSA_UPDATE_BEACON)) + return; if (is_client_associated_to_ap(padapter)) { /* linked infrastructure client mode */ @@ -12613,10 +12819,6 @@ void linked_status_chk(_adapter *padapter, u8 from_timer) int rx_chk_limit; int link_count_limit; - /* DO NOT keep alive while scanning */ - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) - return; - #if defined(CONFIG_RTW_REPEATER_SON) rtw_rson_scan_wk_cmd(padapter, RSON_SCAN_PROCESS); #elif defined(CONFIG_LAYER2_ROAMING) @@ -12734,7 +12936,7 @@ void linked_status_chk(_adapter *padapter, u8 from_timer) issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->cmn.mac_addr, 0, 0, 3, 1); if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) || rx_chk != _SUCCESS) { - if (rtw_mi_check_fwstate(padapter, _FW_UNDER_SURVEY)) + if (rtw_mi_check_fwstate(padapter, WIFI_UNDER_SURVEY)) tx_chk = issue_nulldata(padapter, psta->cmn.mac_addr, 1, 3, 1); else tx_chk = issue_nulldata(padapter, psta->cmn.mac_addr, 0, 3, 1); @@ -12772,7 +12974,7 @@ bypass_active_keep_alive: #ifdef DBG_EXPIRATION_CHK RTW_INFO("%s issue_nulldata(%d)\n", __FUNCTION__, from_timer ? 1 : 0); #endif - if (from_timer || rtw_mi_check_fwstate(padapter, _FW_UNDER_SURVEY)) + if (from_timer || rtw_mi_check_fwstate(padapter, WIFI_UNDER_SURVEY)) tx_chk = issue_nulldata(padapter, NULL, 1, 0, 0); else tx_chk = issue_nulldata(padapter, NULL, 0, 1, 1); @@ -12868,7 +13070,7 @@ void survey_timer_hdl(void *ctx) goto exit; } - init_h2fwcmd_w_parm_no_rsp(cmd, psurveyPara, GEN_CMD_CODE(_SiteSurvey)); + init_h2fwcmd_w_parm_no_rsp(cmd, psurveyPara, CMD_SITE_SURVEY); rtw_enqueue_cmd(pcmdpriv, cmd); } @@ -12887,6 +13089,106 @@ void rson_timer_hdl(void *ctx) #endif +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT +void rtw_tbtx_xmit_timer_hdl(void *ctx) +{ + _adapter *padapter = (_adapter *)ctx; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + if (ATOMIC_READ(&padapter->tbtx_remove_tx_pause) == _TRUE){ + ATOMIC_SET(&padapter->tbtx_tx_pause, _FALSE); + rtw_tx_control_cmd(padapter); + }else { + rtw_issue_action_token_rel(padapter); + ATOMIC_SET(&padapter->tbtx_tx_pause, _TRUE); + rtw_tx_control_cmd(padapter); + _set_timer(&pmlmeext->tbtx_xmit_timer, MAX_TXPAUSE_DURATION); + ATOMIC_SET(&padapter->tbtx_remove_tx_pause, _TRUE); + } +} + +#ifdef CONFIG_AP_MODE +void rtw_tbtx_token_dispatch_timer_hdl(void *ctx) +{ + _adapter *padapter = (_adapter *)ctx; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + _irqL irqL; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + _list *phead, *plist; + int i, found = _FALSE; + u8 nr_send, th_idx = 0; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + RTW_DBG("%s:asoc_cnt: %d\n",__func__, pstapriv->tbtx_asoc_list_cnt); + + // check number of TBTX sta + if (padapter->stapriv.tbtx_asoc_list_cnt < 2) + goto exit; + + // dispatch token + + nr_send = RTW_DIV_ROUND_UP(pstapriv->tbtx_asoc_list_cnt, NR_TBTX_SLOT); + + phead = &pstapriv->asoc_list; + plist = get_next(phead); + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + /* psta is supporting TBTX */ + if ((!psta) || (!psta->tbtx_enable)) + RTW_DBG("sta tbtx_enable is false\n"); + else { + for (i = 0; i < nr_send; i++) { + if (pstapriv->last_token_holder == psta) { + found = _TRUE; + goto outof_loop; + } + } + } + plist = get_next(plist); + } +outof_loop: + + RTW_DBG("rtw_tbtx_token_dispatch_timer_hdl() th_idx=%d, nr_send=%d, phead=%p, plist=%p, found=%d\n ", th_idx , nr_send, phead, plist, found); + if (!found) { + plist = get_next(phead); + while(rtw_end_of_queue_search(phead, plist) == _FALSE) { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + if ((!psta) || (!psta->tbtx_enable)) + RTW_DBG("sta tbtx_enable is false\n"); + else { + pstapriv->token_holder[th_idx] = psta; + rtw_issue_action_token_req(padapter, pstapriv->token_holder[th_idx++]); + break; + } + plist = get_next(plist); + } + } + + for (i=th_idx; itbtx_enable)) + RTW_DBG("sta tbtx_enable is false\n"); + else { + pstapriv->token_holder[th_idx] = psta; + rtw_issue_action_token_req(padapter, pstapriv->token_holder[th_idx++]); + i++; + } + } + ATOMIC_SET(&pstapriv->nr_token_keeper, nr_send); + + +exit: + // set_timer + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + _set_timer(&pmlmeext->tbtx_token_dispatch_timer, TBTX_TX_DURATION); +} +#endif /* CONFIG_AP_MODE */ +#endif /* CONFIG_RTW_TOKEN_BASED_XMIT */ + void link_timer_hdl(void *ctx) { _adapter *padapter = (_adapter *)ctx; @@ -12919,7 +13221,7 @@ void link_timer_hdl(void *ctx) } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) { #ifdef CONFIG_IOCTL_CFG80211 - if (rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE)) + if (rtw_sec_chk_auth_type(padapter, MLME_AUTHTYPE_SAE)) return; #endif /* CONFIG_IOCTL_CFG80211 */ @@ -13003,20 +13305,20 @@ void addba_timer_hdl(void *ctx) void report_sta_timeout_event(_adapter *padapter, u8 *MacAddr, unsigned short reason) { struct cmd_obj *pcmd_obj; - u8 *pevtcmd; + u8 *pevtcmd; u32 cmdsz; struct sta_info *psta; int mac_id; - struct stadel_event *pdel_sta_evt; - struct C2HEvent_Header *pc2h_evt_hdr; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct stadel_event *pdel_sta_evt; + struct rtw_evt_header *evt_hdr; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); if (pcmd_obj == NULL) return; - cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header)); + cmdsz = (sizeof(struct stadel_event) + sizeof(struct rtw_evt_header)); pevtcmd = (u8 *)rtw_zmalloc(cmdsz); if (pevtcmd == NULL) { rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); @@ -13025,19 +13327,19 @@ void report_sta_timeout_event(_adapter *padapter, u8 *MacAddr, unsigned short re _rtw_init_listhead(&pcmd_obj->list); - pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdcode = CMD_SET_MLME_EVT; pcmd_obj->cmdsz = cmdsz; pcmd_obj->parmbuf = pevtcmd; pcmd_obj->rsp = NULL; pcmd_obj->rspsz = 0; - pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); - pc2h_evt_hdr->len = sizeof(struct stadel_event); - pc2h_evt_hdr->ID = GEN_EVT_CODE(_TimeoutSTA); - pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + evt_hdr = (struct rtw_evt_header *)(pevtcmd); + evt_hdr->len = sizeof(struct stadel_event); + evt_hdr->id = EVT_TIMEOUT_STA; + evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); - pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); + pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct rtw_evt_header)); _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN); _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2); @@ -13075,7 +13377,7 @@ void sa_query_timer_hdl(void *ctx) struct mlme_priv *pmlmepriv = &padapter->mlmepriv; if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE && - check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) clnt_sa_query_timeout(padapter); else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) report_sta_timeout_event(padapter, psta->cmn.mac_addr, WLAN_REASON_PREV_AUTH_NOT_VALID); @@ -13083,419 +13385,6 @@ void sa_query_timer_hdl(void *ctx) #endif /* CONFIG_IEEE80211W */ -#ifdef CONFIG_RTW_80211R -void rtw_ft_update_bcn(_adapter *padapter, union recv_frame *precv_frame) -{ - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 *pframe = precv_frame->u.hdr.rx_data; - uint len = precv_frame->u.hdr.len; - WLAN_BSSID_EX *pbss; - - if (rtw_ft_chk_status(padapter,RTW_FT_ASSOCIATED_STA) - && (pmlmepriv->ft_roam.ft_updated_bcn == _FALSE)) { - pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX)); - if (pbss) { - if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) { - struct beacon_keys recv_beacon; - - update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE); - - /* update bcn keys */ - if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) { - RTW_INFO("%s: beacon keys ready\n", __func__); - _rtw_memcpy(&pmlmepriv->cur_beacon_keys, - &recv_beacon, sizeof(recv_beacon)); - if (is_hidden_ssid(recv_beacon.ssid, recv_beacon.ssid_len)) { - _rtw_memcpy(pmlmepriv->cur_beacon_keys.ssid, pmlmeinfo->network.Ssid.Ssid, IW_ESSID_MAX_SIZE); - pmlmepriv->cur_beacon_keys.ssid_len = pmlmeinfo->network.Ssid.SsidLength; - } - } else { - RTW_ERR("%s: get beacon keys failed\n", __func__); - _rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon)); - } - #ifdef CONFIG_BCN_CNT_CONFIRM_HDL - pmlmepriv->new_beacon_cnts = 0; - #endif - } - rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX)); - } - - /* check the vendor of the assoc AP */ - pmlmeinfo->assoc_AP_vendor = - check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), - (len - sizeof(struct rtw_ieee80211_hdr_3addr))); - - /* update TSF Value */ - update_TSF(pmlmeext, pframe, len); - pmlmeext->bcn_cnt = 0; - pmlmeext->last_bcn_cnt = 0; - pmlmepriv->ft_roam.ft_updated_bcn = _TRUE; - } -} - -void rtw_ft_start_clnt_join(_adapter *padapter) -{ - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); - - if (rtw_ft_otd_roam(padapter)) { - pmlmeinfo->state = WIFI_FW_AUTH_SUCCESS | WIFI_FW_STATION_STATE; - pft_roam->ft_event.ies = - (pft_roam->ft_action + sizeof(struct rtw_ieee80211_hdr_3addr) + 16); - pft_roam->ft_event.ies_len = - (pft_roam->ft_action_len - sizeof(struct rtw_ieee80211_hdr_3addr)); - - /*Not support RIC*/ - pft_roam->ft_event.ric_ies = NULL; - pft_roam->ft_event.ric_ies_len = 0; - rtw_ft_report_evt(padapter); - return; - } - - pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE; - start_clnt_auth(padapter); -} - -u8 rtw_ft_update_rsnie( - _adapter *padapter, u8 bwrite, - struct pkt_attrib *pattrib, u8 **pframe) -{ - struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); - u8 *pie; - u32 len; - - pie = rtw_get_ie(pft_roam->updated_ft_ies, EID_WPA2, &len, - pft_roam->updated_ft_ies_len); - - if (!bwrite) - return (pie)?_SUCCESS:_FAIL; - - if (pie) { - *pframe = rtw_set_ie(((u8 *)*pframe), EID_WPA2, len, - pie+2, &(pattrib->pktlen)); - } else - return _FAIL; - - return _SUCCESS; -} - -static u8 rtw_ft_update_mdie( - _adapter *padapter, struct pkt_attrib *pattrib, u8 **pframe) -{ - struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); - u8 *pie, mdie[3]; - u32 len = 3; - - if (rtw_ft_roam(padapter)) { - if ((pie = rtw_get_ie(pft_roam->updated_ft_ies, _MDIE_, - &len, pft_roam->updated_ft_ies_len))) { - pie = (pie + 2); /* ignore md-id & length */ - } else - return _FAIL; - } else { - *((u16 *)&mdie[0]) = pft_roam->mdid; - mdie[2] = pft_roam->ft_cap; - pie = &mdie[0]; - } - - *pframe = rtw_set_ie(((u8 *)*pframe), _MDIE_, len , pie, &(pattrib->pktlen)); - return _SUCCESS; -} - -static u8 rtw_ft_update_ftie( - _adapter *padapter, struct pkt_attrib *pattrib, u8 **pframe) -{ - struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); - u8 *pie; - u32 len; - - if ((pie = rtw_get_ie(pft_roam->updated_ft_ies, _FTIE_, &len, - pft_roam->updated_ft_ies_len)) != NULL) { - *pframe = rtw_set_ie(*pframe, _FTIE_, len , - (pie+2), &(pattrib->pktlen)); - } else - return _FAIL; - - return _SUCCESS; -} - -void rtw_ft_build_auth_req_ies(_adapter *padapter, - struct pkt_attrib *pattrib, u8 **pframe) -{ - u8 ftie_append = _TRUE; - - if (!pattrib || !(*pframe)) - return; - - if (!rtw_ft_roam(padapter)) - return; - - ftie_append = rtw_ft_update_rsnie(padapter, _TRUE, pattrib, pframe); - rtw_ft_update_mdie(padapter, pattrib, pframe); - if (ftie_append) - rtw_ft_update_ftie(padapter, pattrib, pframe); -} - -void rtw_ft_build_assoc_req_ies(_adapter *padapter, - u8 is_reassoc, struct pkt_attrib *pattrib, u8 **pframe) -{ - if (!pattrib || !(*pframe)) - return; - - if (rtw_ft_chk_flags(padapter, RTW_FT_PEER_EN)) - rtw_ft_update_mdie(padapter, pattrib, pframe); - - if ((!is_reassoc) || (!rtw_ft_roam(padapter))) - return; - - if (rtw_ft_update_rsnie(padapter, _FALSE, pattrib, pframe)) - rtw_ft_update_ftie(padapter, pattrib, pframe); -} - -u8 rtw_ft_update_auth_rsp_ies(_adapter *padapter, u8 *pframe, u32 len) -{ - u8 ret = _SUCCESS; - u8 target_ap_addr[ETH_ALEN] = {0}; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); - - if (!rtw_ft_roam(padapter)) - return _FAIL; - - /*rtw_ft_report_reassoc_evt already, - * and waiting for cfg80211_rtw_update_ft_ies */ - if (rtw_ft_authed_sta(padapter)) - return ret; - - if (!pframe || !len) - return _FAIL; - - rtw_buf_update(&pmlmepriv->auth_rsp, - &pmlmepriv->auth_rsp_len, pframe, len); - pft_roam->ft_event.ies = - (pmlmepriv->auth_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6); - pft_roam->ft_event.ies_len = - (pmlmepriv->auth_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6); - - /*Not support RIC*/ - pft_roam->ft_event.ric_ies = NULL; - pft_roam->ft_event.ric_ies_len = 0; - _rtw_memcpy(target_ap_addr, pmlmepriv->assoc_bssid, ETH_ALEN); - rtw_ft_report_reassoc_evt(padapter, target_ap_addr); - - return ret; -} - -static void rtw_ft_start_clnt_action(_adapter *padapter, u8 *pTargetAddr) -{ - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - - rtw_ft_set_status(padapter, RTW_FT_REQUESTING_STA); - rtw_ft_issue_action_req(padapter, pTargetAddr); - _set_timer(&pmlmeext->ft_link_timer, REASSOC_TO); -} - -void rtw_ft_start_roam(_adapter *padapter, u8 *pTargetAddr) -{ - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - - if (rtw_ft_otd_roam(padapter)) { - rtw_ft_start_clnt_action(padapter, pTargetAddr); - } else { - /*wait a little time to retrieve packets buffered in the current ap while scan*/ - _set_timer(&pmlmeext->ft_roam_timer, 30); - } -} - -void rtw_ft_issue_action_req(_adapter *padapter, u8 *pTargetAddr) -{ - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct xmit_frame *pmgntframe; - struct rtw_ieee80211_hdr *pwlanhdr; - struct pkt_attrib *pattrib; - u8 *pframe; - u8 category = RTW_WLAN_CATEGORY_FT; - u8 action = RTW_WLAN_ACTION_FT_REQ; - - pmgntframe = alloc_mgtxmitframe(pxmitpriv); - if (pmgntframe == NULL) - return; - - pattrib = &pmgntframe->attrib; - update_mgntframe_attrib(padapter, pattrib); - _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); - - pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; - pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; - pwlanhdr->frame_ctl = 0; - - _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); - - SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); - pmlmeext->mgnt_seq++; - set_frame_sub_type(pframe, WIFI_ACTION); - - pframe += sizeof(struct rtw_ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); - - pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); - pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); - - _rtw_memcpy(pframe, adapter_mac_addr(padapter), ETH_ALEN); - pframe += ETH_ALEN; - pattrib->pktlen += ETH_ALEN; - - _rtw_memcpy(pframe, pTargetAddr, ETH_ALEN); - pframe += ETH_ALEN; - pattrib->pktlen += ETH_ALEN; - - rtw_ft_update_mdie(padapter, pattrib, &pframe); - if (rtw_ft_update_rsnie(padapter, _TRUE, pattrib, &pframe)) - rtw_ft_update_ftie(padapter, pattrib, &pframe); - - pattrib->last_txcmdsz = pattrib->pktlen; - dump_mgntframe(padapter, pmgntframe); -} - -void rtw_ft_report_evt(_adapter *padapter) -{ - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&(pmlmeinfo->network); - struct cfg80211_ft_event_params ft_evt_parms; - _irqL irqL; - - _rtw_memset(&ft_evt_parms, 0, sizeof(ft_evt_parms)); - rtw_ft_update_stainfo(padapter, pnetwork); - - if (!pnetwork) - goto err_2; - - ft_evt_parms.ies_len = pft_roam->ft_event.ies_len; - ft_evt_parms.ies = rtw_zmalloc(ft_evt_parms.ies_len); - if (ft_evt_parms.ies) - _rtw_memcpy((void *)ft_evt_parms.ies, pft_roam->ft_event.ies, ft_evt_parms.ies_len); - else - goto err_2; - - ft_evt_parms.target_ap = rtw_zmalloc(ETH_ALEN); - if (ft_evt_parms.target_ap) - _rtw_memcpy((void *)ft_evt_parms.target_ap, pnetwork->MacAddress, ETH_ALEN); - else - goto err_1; - - ft_evt_parms.ric_ies = pft_roam->ft_event.ric_ies; - ft_evt_parms.ric_ies_len = pft_roam->ft_event.ric_ies_len; - - rtw_ft_lock_set_status(padapter, RTW_FT_AUTHENTICATED_STA, &irqL); - rtw_cfg80211_ft_event(padapter, &ft_evt_parms); - RTW_INFO("FT: rtw_ft_report_evt\n"); - rtw_mfree((u8 *)pft_roam->ft_event.target_ap, ETH_ALEN); -err_1: - rtw_mfree((u8 *)ft_evt_parms.ies, ft_evt_parms.ies_len); -err_2: - return; -} - -void rtw_ft_report_reassoc_evt(_adapter *padapter, u8 *pMacAddr) -{ - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); - struct cmd_obj *pcmd_obj = NULL; - struct stassoc_event *passoc_sta_evt = NULL; - struct C2HEvent_Header *pc2h_evt_hdr = NULL; - u8 *pevtcmd = NULL; - u32 cmdsz = 0; - - pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); - if (pcmd_obj == NULL) - return; - - cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header)); - pevtcmd = (u8 *)rtw_zmalloc(cmdsz); - if (pevtcmd == NULL) { - rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); - return; - } - - _rtw_init_listhead(&pcmd_obj->list); - pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); - pcmd_obj->cmdsz = cmdsz; - pcmd_obj->parmbuf = pevtcmd; - pcmd_obj->rsp = NULL; - pcmd_obj->rspsz = 0; - - pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); - pc2h_evt_hdr->len = sizeof(struct stassoc_event); - pc2h_evt_hdr->ID = GEN_EVT_CODE(_FT_REASSOC); - pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); - - passoc_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); - _rtw_memcpy((unsigned char *)(&(passoc_sta_evt->macaddr)), pMacAddr, ETH_ALEN); - rtw_enqueue_cmd(pcmdpriv, pcmd_obj); -} - -void rtw_ft_link_timer_hdl(void *ctx) -{ - _adapter *padapter = (_adapter *)ctx; - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); - - if (rtw_ft_chk_status(padapter, RTW_FT_REQUESTING_STA)) { - if (pft_roam->ft_req_retry_cnt < RTW_FT_ACTION_REQ_LMT) { - pft_roam->ft_req_retry_cnt++; - rtw_ft_issue_action_req(padapter, (u8 *)pmlmepriv->roam_network->network.MacAddress); - _set_timer(&pmlmeext->ft_link_timer, REASSOC_TO); - } else { - pft_roam->ft_req_retry_cnt = 0; - if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) - rtw_ft_set_status(padapter, RTW_FT_ASSOCIATED_STA); - else - rtw_ft_reset_status(padapter); - } - } -} - -void rtw_ft_roam_timer_hdl(void *ctx) -{ - _adapter *padapter = (_adapter *)ctx; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - - receive_disconnect(padapter, pmlmepriv->cur_network.network.MacAddress - , WLAN_REASON_ACTIVE_ROAM, _FALSE); -} - -void rtw_ft_roam_status_reset(_adapter *padapter) -{ - struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); - - if ((rtw_to_roam(padapter) > 0) && - (!rtw_ft_chk_status(padapter, RTW_FT_REQUESTED_STA))) { - rtw_ft_reset_status(padapter); - } - - padapter->mlmepriv.ft_roam.ft_updated_bcn = _FALSE; -} -#endif - -u8 NULL_hdl(_adapter *padapter, u8 *pbuf) -{ - return H2C_SUCCESS; -} - #ifdef CONFIG_AUTO_AP_MODE void rtw_auto_ap_rx_msg_dump(_adapter *padapter, union recv_frame *precv_frame, u8 *ehdr_pos) { @@ -13624,6 +13513,22 @@ static int rtw_auto_ap_start_beacon(_adapter *adapter) } #endif/* CONFIG_AUTO_AP_MODE */ +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT +u8 tx_control_hdl(_adapter *adapter) +{ + u8 val; + + if(ATOMIC_READ(&adapter->tbtx_tx_pause)) + val = 0xff; + else + val = 0x00; + + rtw_hal_set_hwreg(adapter, HW_VAR_TXPAUSE, &val); + + return H2C_SUCCESS; +} +#endif + #ifdef CONFIG_AP_MODE u8 stop_ap_hdl(_adapter *adapter) { @@ -13701,6 +13606,7 @@ u8 setopmode_hdl(_adapter *padapter, u8 *pbuf) u8 createbss_hdl(_adapter *padapter, u8 *pbuf) { +#ifdef CONFIG_AP_MODE struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network)); @@ -13709,14 +13615,12 @@ u8 createbss_hdl(_adapter *padapter, u8 *pbuf) u8 ret = H2C_SUCCESS; /* u8 initialgain; */ -#ifdef CONFIG_AP_MODE if ((parm->req_ch == 0 && pmlmeinfo->state == WIFI_FW_AP_STATE) || parm->req_ch != 0 ) { start_bss_network(padapter, parm); goto exit; } -#endif /* below is for ad-hoc master */ if (parm->adhoc) { @@ -13760,6 +13664,9 @@ ibss_post_hdl: exit: return ret; +#else + return H2C_SUCCESS; +#endif /* CONFIG_AP_MODE */ } u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf) @@ -13772,6 +13679,12 @@ u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf) #ifdef CONFIG_ANTENNA_DIVERSITY struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf; #endif /* CONFIG_ANTENNA_DIVERSITY */ +#ifdef CONFIG_LAYER2_ROAMING + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct wlan_network *rnetwork = pmlmepriv->roam_network; + struct beacon_keys bcn_keys; + u32 roam_ielen; +#endif u32 i; /* u8 initialgain; */ /* u32 acparm; */ @@ -13937,7 +13850,6 @@ u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf) rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk); set_channel_bwmode(padapter, u_ch, u_offset, u_bw); - rtw_mi_update_union_chan_inf(padapter, u_ch, u_offset, u_bw); doiqk = _FALSE; rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk); @@ -13947,6 +13859,45 @@ u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf) start_clnt_join(padapter); +#ifdef CONFIG_LAYER2_ROAMING + rtw_msleep_os(2); + if (rnetwork && (pmlmeinfo->state & (WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE))) { + struct beacon_keys bcn_keys; + u32 roam_ielen; + + if (!rnetwork) { + RTW_INFO("%s: pmlmepriv->roam_network is NULL. roaming fail!!\n", __func__); + return H2C_SUCCESS; + } + roam_ielen = rnetwork->network.IELength; + update_network(&(pmlmepriv->cur_network.network), &(rnetwork->network), padapter, _TRUE); + + /* update bcn keys */ + if (rtw_get_bcn_keys_from_bss(&rnetwork->network, &bcn_keys) == _TRUE) { + _rtw_memcpy(&pmlmepriv->cur_beacon_keys, &bcn_keys, sizeof(bcn_keys)); + if (is_hidden_ssid(bcn_keys.ssid, bcn_keys.ssid_len)) { + _rtw_memcpy(pmlmepriv->cur_beacon_keys.ssid, pmlmeinfo->network.Ssid.Ssid, IW_ESSID_MAX_SIZE); + pmlmepriv->cur_beacon_keys.ssid_len = pmlmeinfo->network.Ssid.SsidLength; + } + } else { + RTW_ERR("%s: get beacon keys failed\n", __func__); + _rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(bcn_keys)); + } + #ifdef CONFIG_BCN_CNT_CONFIRM_HDL + pmlmepriv->new_beacon_cnts = 0; + #endif + + /* check the vendor of the assoc AP */ + pmlmeinfo->assoc_AP_vendor = check_assoc_AP(rnetwork->network.IEs, rnetwork->network.IELength); + + /* update TSF Value */ + pmlmeext->TSFValue = rnetwork->network.tsf + rtw_get_passing_time_ms(rnetwork->last_scanned)*1000; + pmlmeext->bcn_cnt = 0; + pmlmeext->last_bcn_cnt = 0; + /* start auth */ + start_clnt_auth(padapter); + } +#endif return H2C_SUCCESS; } @@ -13984,12 +13935,11 @@ u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf) #endif rtw_sta_mstatus_report(padapter); - + rtw_mlmeext_disconnect(padapter); rtw_free_uc_swdec_pending_queue(padapter); - return H2C_SUCCESS; } @@ -14042,7 +13992,6 @@ static bool scan_abort_hdl(_adapter *adapter) , ss->channel_idx ); } - pmlmeext->scan_abort = _FALSE; ret = _TRUE; } @@ -14062,11 +14011,6 @@ u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_nu #ifndef RTW_SCAN_SPARSE_CH_NUM_BG #define RTW_SCAN_SPARSE_CH_NUM_BG 4 #endif -#ifdef CONFIG_LAYER2_ROAMING -#ifndef RTW_SCAN_SPARSE_CH_NUM_ROAMING_ACTIVE -#define RTW_SCAN_SPARSE_CH_NUM_ROAMING_ACTIVE 1 -#endif -#endif #define SCAN_SPARSE_CH_NUM_INVALID 255 @@ -14086,7 +14030,7 @@ u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_nu interval = rtw_get_passing_time_ms(mlmeext->last_scan_time); - if (rtw_mi_busy_traffic_check(adapter, _FALSE)) + if (rtw_mi_busy_traffic_check(adapter)) busy_traffic = _TRUE; if (rtw_mi_check_miracast_enabled(adapter)) @@ -14107,14 +14051,6 @@ u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_nu max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_BG); #endif -#if defined(CONFIG_LAYER2_ROAMING) && defined(RTW_SCAN_SPARSE_ROAMING_ACTIVE) - if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) { - if (busy_traffic == _TRUE && adapter->mlmepriv.need_to_roam == _TRUE) - max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_ROAMING_ACTIVE); - } -#endif - - if (max_allow_ch != SCAN_SPARSE_CH_NUM_INVALID) { int i; int k = 0; @@ -14210,17 +14146,28 @@ u32 rtw_scan_timeout_decision(_adapter *padapter) } static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out, - u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num, bool no_sparse) + u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num, bool no_sparse, int reason) { int i, j; int set_idx; u8 chan; struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(padapter)); +#ifdef CONFIG_RTW_ROAM_QUICKSCAN + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; +#endif /* clear first */ _rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel) * out_num); +#ifdef CONFIG_RTW_ROAM_QUICKSCAN + if ((reason == RTW_AUTO_SCAN_REASON_ROAM) && (pmlmeext->quickscan_next)) { + pmlmeext->quickscan_next = _FALSE; + _rtw_memcpy(out, pmlmeext->roam_ch, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT); + return pmlmeext->roam_ch_num; + } +#endif + /* acquire channels from in */ j = 0; for (i = 0; i < in_num; i++) { @@ -14243,8 +14190,7 @@ static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel _rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel)); - if (rfctl->channel_set[set_idx].ScanType == SCAN_PASSIVE - || rfctl->channel_set[set_idx].dfs) + if (rfctl->channel_set[set_idx].flags & (RTW_CHF_NO_IR | RTW_CHF_DFS)) out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN; j++; @@ -14272,8 +14218,7 @@ static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel out[j].hw_value = chan; - if (rfctl->channel_set[i].ScanType == SCAN_PASSIVE - || rfctl->channel_set[i].dfs) + if (rfctl->channel_set[i].flags & (RTW_CHF_NO_IR | RTW_CHF_DFS)) out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN; j++; @@ -14296,9 +14241,10 @@ static void sitesurvey_res_reset(_adapter *adapter, struct sitesurvey_parm *parm { struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res; RT_CHANNEL_INFO *chset = adapter_to_chset(adapter); - int i; + int i, reason = 0; ss->bss_cnt = 0; + ss->activate_ch_cnt = 0; ss->channel_idx = 0; ss->force_ssid_scan = 0; ss->igi_scan = 0; @@ -14318,11 +14264,12 @@ static void sitesurvey_res_reset(_adapter *adapter, struct sitesurvey_parm *parm } else ss->ssid[i].SsidLength = 0; } - + reason = parm->reason; ss->ch_num = rtw_scan_ch_decision(adapter , ss->ch, RTW_CHANNEL_SCAN_AMOUNT , parm->ch, parm->ch_num , parm->acs + , reason ); for (i = 0; i < MAX_CHANNEL_NUM; i++) @@ -14371,7 +14318,7 @@ static u8 sitesurvey_pick_ch_behavior(_adapter *padapter, u8 *ch, RT_SCAN_TYPE * scan_ch = pwdinfo->social_chan[ss->channel_idx]; ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, scan_ch); if (ch_set_idx >= 0) - scan_type = rfctl->channel_set[ch_set_idx].ScanType; + scan_type = rfctl->channel_set[ch_set_idx].flags & RTW_CHF_NO_IR ? SCAN_PASSIVE : SCAN_ACTIVE; else scan_type = SCAN_ACTIVE; } else @@ -14831,6 +14778,68 @@ void sitesurvey_set_offch_state(_adapter *adapter, u8 scan_state) _exit_critical_mutex(&rfctl->offch_mutex, NULL); } +#ifdef CONFIG_RTW_ROAM_QUICKSCAN +extern inline int is_same_ess(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b); +extern int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork); +void generate_quickss(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct wlan_network *pnetwork = NULL; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct rtw_ieee80211_channel *roam_ch = pmlmeext->roam_ch; + struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); + int chan; + _irqL irqL; + _list *plist, *phead; + u8 *target_ssid=NULL, *ssid=NULL, ds_cfg, j, ch_num; + u32 target_ssid_len=0, ssid_len=0; + u8 mark[166]; + + target_ssid = pmlmepriv->cur_network.network.Ssid.Ssid; + target_ssid_len = pmlmepriv->cur_network.network.Ssid.SsidLength; + _rtw_memset(mark, 0, sizeof(u8)*166); + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + phead = get_list_head(&(pmlmepriv->scanned_queue)); + if (!phead) { + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + return; + } + plist = get_next(phead); + if (!plist) { + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + return; + } + while (1) { + if (rtw_end_of_queue_search(phead, plist) == _TRUE) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + if (!pnetwork) + break; + + ds_cfg = pnetwork->network.Configuration.DSConfig; + if (is_same_ess(&pnetwork->network, &pmlmepriv->cur_network.network) && + rtw_is_desired_network(padapter, pnetwork)) + mark[ds_cfg] = 1; + + plist = get_next(plist); + } + /* ex: assume roaming channel=1/6/40/165, then mark[1]/[6]/[40]/[165] are 1. */ + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + ch_num = 0; + for (j = 0; j < rfctl->max_chan_nums; j++) { + chan = rfctl->channel_set[j].ChannelNum; + if (mark[chan]) { + roam_ch[ch_num].hw_value = chan; + roam_ch[ch_num++].flags = rfctl->channel_set[j].flags; + } + } + pmlmeext->roam_ch_num = ch_num; +} +#endif + u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf) { struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf; @@ -14840,13 +14849,16 @@ u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf) #endif struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct ss_res *ss = &pmlmeext->sitesurvey_res; -#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI - struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); +#if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND) + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); #endif u8 val8; #ifdef CONFIG_P2P struct wifidirect_info *pwdinfo = &padapter->wdinfo; +#ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; +#endif #endif #ifdef DBG_CHECK_FW_PS_STATE @@ -14877,13 +14889,15 @@ operation_by_state: goto operation_by_state; case SCAN_START: -#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI +#if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND) if ((pwdev_priv->pno_mac_addr[0] != 0xFF) && (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) - && (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _FALSE)) { + && (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _FALSE)) { u16 seq_num; +#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI rtw_hal_pno_random_gen_mac_addr(padapter); +#endif rtw_hal_set_hw_mac_addr(padapter, pwdev_priv->pno_mac_addr); get_random_bytes(&seq_num, 2); pwdev_priv->pno_scan_seq_num = seq_num & 0xFFF; @@ -14994,7 +15008,7 @@ operation_by_state: site_survey(padapter, scan_ch, scan_type); #if defined(CONFIG_ATMEL_RC_PATCH) - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) scan_ms = 20; else scan_ms = 40; @@ -15005,9 +15019,6 @@ operation_by_state: else #endif /*CONFIG_RTW_ACS*/ scan_ms = ss->scan_ch_ms; - if (scan_type == SCAN_ACTIVE) - scan_ms = SURVEY_TO_ACTIVE; - #endif #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL) @@ -15034,7 +15045,7 @@ operation_by_state: #ifdef CONFIG_SCAN_BACKOP case SCAN_BACKING_OP: { - u8 back_ch = 0, back_bw = 0, back_ch_offset = 0; + u8 back_ch, back_bw, back_ch_offset; u8 need_ch_setting_union = _TRUE; #ifdef CONFIG_MCC_MODE @@ -15043,8 +15054,12 @@ operation_by_state: #endif /* CONFIG_MCC_MODE */ if (need_ch_setting_union) { - if (rtw_mi_get_ch_setting_union(padapter, &back_ch, &back_bw, &back_ch_offset) == 0) + if (rtw_mi_get_ch_setting_union(padapter, &back_ch, &back_bw, &back_ch_offset) == 0) { rtw_warn_on(1); + back_ch = pmlmeext->cur_channel; + back_bw = pmlmeext->cur_bwmode; + back_ch_offset = pmlmeext->cur_ch_offset; + } } #ifdef DBG_SITESURVEY @@ -15169,7 +15184,7 @@ operation_by_state: #endif /* CONFIG_P2P */ case SCAN_COMPLETE: -#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI +#if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND) rtw_hal_set_hw_mac_addr(padapter, adapter_mac_addr(padapter)); #endif #ifdef CONFIG_P2P @@ -15179,7 +15194,7 @@ operation_by_state: #ifdef CONFIG_CONCURRENT_MODE if (pwdinfo->driver_interface == DRIVER_WEXT) { if (rtw_mi_check_status(padapter, MI_LINKED)) - _set_timer(&pwdinfo->ap_p2p_switch_timer, 500); + _set_timer(&prochinfo->ap_roch_ch_switch_timer, 500); } #endif @@ -15233,7 +15248,10 @@ operation_by_state: if (ss->token) rm_post_event(padapter, ss->token, RM_EV_survey_done); #endif /* CONFIG_RTW_80211K */ - +#ifdef CONFIG_RTW_ROAM_QUICKSCAN + if (padapter->mlmepriv.need_to_roam == _TRUE) + generate_quickss(padapter); +#endif break; } @@ -15252,6 +15270,19 @@ u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf) return H2C_SUCCESS; } +static u8 amsdu_spp_enable(_adapter *pdapter, enum security_type type) +{ + u8 ret = _FALSE; + + if (pdapter->registrypriv.amsdu_mode == RTW_AMSDU_MODE_SPP) { + if ( type == _AES_ || type == _CCMP_256_ + || type == _GCMP_ || type == _GCMP_256_ ) + ret = _SUCCESS; + } + + return ret; +} + /* SEC CAM Entry format (32 bytes) DW0 - MAC_ADDR[15:0] | Valid[15] | MFB[14:8] | RSVD[7] | GK[6] | MIC_KEY[5] | SEC_TYPE[4:2] | KID[1:0] @@ -15281,17 +15312,18 @@ u8 setkey_hdl(_adapter *padapter, u8 *pbuf) if (pparm->set_tx) pmlmeinfo->key_index = pparm->keyid; -#ifdef CONFIG_CONCURRENT_MODE +#ifndef SEC_DEFAULT_KEY_SEARCH if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) cam_id = rtw_iface_bcmc_id_get(padapter); else #endif - cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid, 1, &used); + cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid, 1, + !!(pparm->algorithm & _SEC_TYPE_256_), &used); if (cam_id < 0) goto enable_mc; -#ifndef CONFIG_CONCURRENT_MODE +#ifdef SEC_DEFAULT_KEY_SEARCH if (cam_id >= 0 && cam_id <= 3) { /* default key camid */ addr = null_addr; @@ -15334,15 +15366,22 @@ u8 setkey_hdl(_adapter *padapter, u8 *pbuf) goto enable_mc; } - ctrl = BIT(15) | BIT(6) | ((pparm->algorithm) << 2) | pparm->keyid; + ctrl = BIT(15) | BIT(6) | ((pparm->algorithm & 0x07) << 2) | pparm->keyid; RTW_PRINT("set group key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n" , cam_id, MAC_ARG(addr), pparm->keyid, security_type_str(pparm->algorithm)); + if (pparm->algorithm & _SEC_TYPE_256_) { + RTW_INFO_DUMP("GTK : ", pparm->key, sizeof(pparm->key)); + ctrl |= BIT(9); + } + + if (amsdu_spp_enable(padapter, pparm->algorithm) == _SUCCESS) + ctrl |= BIT(7); write_cam(padapter, cam_id, ctrl, addr, pparm->key); /* if ((cam_id > 3) && (((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)))*/ -#ifdef CONFIG_CONCURRENT_MODE +#ifndef SEC_DEFAULT_KEY_SEARCH if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) { if (is_wep_enc(pparm->algorithm)) { padapter->securitypriv.dot11Def_camid[pparm->keyid] = cam_id; @@ -15364,10 +15403,7 @@ u8 setkey_hdl(_adapter *padapter, u8 *pbuf) }*/ } } -#endif - - -#ifndef CONFIG_CONCURRENT_MODE +#else if (cam_id >= 0 && cam_id <= 3) rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)_TRUE); #endif @@ -15388,7 +15424,29 @@ u8 setkey_hdl(_adapter *padapter, u8 *pbuf) enable_mc: /* allow multicast packets to driver */ rtw_hal_set_hwreg(padapter, HW_VAR_ON_RCR_AM, null_addr); +#ifdef CONFIG_LAYER2_ROAMING + if (padapter->mlmepriv.roam_network) { + struct xmit_frame *rframe; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + _list *plist, *phead; + _irqL irqL; + _pkt *pkt; + padapter->mlmepriv.roam_network = NULL; + _enter_critical_bh(&pxmitpriv->rpkt_queue.lock, &irqL); + phead = get_list_head(&pxmitpriv->rpkt_queue); + plist = get_next(phead); + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) { + rframe = LIST_CONTAINOR(plist, struct xmit_frame, list); + plist = get_next(plist); + rtw_list_delete(&rframe->list); + pkt = rframe->pkt; + rframe->pkt = NULL; + rtw_xmit_posthandle(padapter, rframe, pkt); + } + _exit_critical_bh(&pxmitpriv->rpkt_queue.lock, &irqL); + } +#endif return H2C_SUCCESS; } @@ -15441,7 +15499,8 @@ u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf) pmlmeinfo->enc_algo = pparm->algorithm; - cam_id = rtw_camid_alloc(padapter, psta, pparm->keyid, pparm->gk, &used); + cam_id = rtw_camid_alloc(padapter, psta, pparm->keyid, pparm->gk, + !!(pparm->algorithm & _SEC_TYPE_256_), &used); if (cam_id < 0) goto exit; @@ -15480,10 +15539,18 @@ write_to_cam: RTW_PRINT("set %s key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n" , pparm->gk ? "group" : "pairwise" , cam_id, MAC_ARG(pparm->addr), pparm->keyid, security_type_str(pparm->algorithm)); - ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid; + ctrl = BIT(15) | ((pparm->algorithm & 0x07) << 2) | pparm->keyid; if (pparm->gk) ctrl |= BIT(6); + if (pparm->algorithm & _SEC_TYPE_256_) { + RTW_INFO_DUMP("PTK : ", pparm->key, sizeof(pparm->key)); + ctrl |= BIT(9); + } + if (amsdu_spp_enable(padapter, pparm->algorithm) == _SUCCESS) + ctrl |= BIT(7); write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key); + if (!(pparm->gk)) + ATOMIC_INC(&psta->keytrack); /*CVE-2020-24587*/ } ret = H2C_SUCCESS_RSP; @@ -15590,7 +15657,7 @@ u8 chk_bmc_sleepq_cmd(_adapter *padapter) goto exit; } - init_h2fwcmd_w_parm_no_parm_rsp(ph2c, GEN_CMD_CODE(_ChkBMCSleepq)); + init_h2fwcmd_w_parm_no_parm_rsp(ph2c, CMD_CHK_BMCSLEEPQ); res = rtw_enqueue_cmd(pcmdpriv, ph2c); @@ -15636,7 +15703,7 @@ u8 set_tx_beacon_cmd(_adapter *padapter, u8 flags) goto exit; } - init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon)); + init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, CMD_TX_BEACON); if (flags & RTW_CMDF_WAIT_ACK) { ph2c->sctx = &sctx; @@ -15663,39 +15730,33 @@ exit: u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf) { - u8 evt_code, evt_seq; - u16 evt_sz; - uint *peventbuf; + struct rtw_evt_header *evt_hdr; + u8 *peventbuf; void (*event_callback)(_adapter *dev, u8 *pbuf); struct evt_priv *pevt_priv = &(padapter->evtpriv); if (pbuf == NULL) goto _abort_event_; - peventbuf = (uint *)pbuf; - evt_sz = (u16)(*peventbuf & 0xffff); - evt_seq = (u8)((*peventbuf >> 24) & 0x7f); - evt_code = (u8)((*peventbuf >> 16) & 0xff); - + evt_hdr = (struct rtw_evt_header *)pbuf; + peventbuf = pbuf + sizeof(struct rtw_evt_header); #ifdef CHECK_EVENT_SEQ /* checking event sequence... */ - if (evt_seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f)) { - - pevt_priv->event_seq = (evt_seq + 1) & 0x7f; - + if (evt_hdr->seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f)) { + pevt_priv->event_seq = (evt_hdr->seq + 1) & 0x7f; goto _abort_event_; } #endif /* checking if event code is valid */ - if (evt_code >= MAX_C2HEVT) { + if (evt_hdr->id >= EVT_ID_MAX) { goto _abort_event_; } /* checking if event size match the event parm size */ - if ((wlanevents[evt_code].parmsize != 0) && - (wlanevents[evt_code].parmsize != evt_sz)) { + if ((wlanevents[evt_hdr->id].parmsize != 0) && + (wlanevents[evt_hdr->id].parmsize != evt_hdr->len)) { goto _abort_event_; @@ -15703,31 +15764,17 @@ u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf) ATOMIC_INC(&pevt_priv->event_seq); - peventbuf += 2; - if (peventbuf) { - event_callback = wlanevents[evt_code].event_callback; + event_callback = wlanevents[evt_hdr->id].event_callback; event_callback(padapter, (u8 *)peventbuf); - pevt_priv->evt_done_cnt++; } - _abort_event_: - - return H2C_SUCCESS; } -u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf) -{ - if (!pbuf) - return H2C_PARAMETERS_ERROR; - - return H2C_SUCCESS; -} - u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf) { #ifdef CONFIG_AP_MODE @@ -15795,6 +15842,7 @@ u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf) u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf) { +#ifdef CONFIG_AP_MODE /*RTW_INFO(FUNC_ADPT_FMT, FUNC_ADPT_ARG(padapter));*/ #ifdef CONFIG_SWTIMER_BASED_TXBCN @@ -15810,7 +15858,7 @@ u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf) /* tx bc/mc frames after update TIM */ chk_bmc_sleepq_hdl(padapter, NULL); #endif - +#endif /* CONFIG_AP_MODE */ return H2C_SUCCESS; } @@ -15820,6 +15868,7 @@ u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf) * set WLAN_BSSID_EX.SupportedRates * update WLAN_BSSID_EX.IEs's Supported Rate and Extended Supported Rate ie */ +#ifdef CONFIG_AP_MODE void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch) { u8 network_type, rate_len, total_rate_len, remainder_rate_len; @@ -15881,6 +15930,7 @@ void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch) pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork); } +#endif /* CONFIG_AP_MODE */ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) { @@ -15891,7 +15941,7 @@ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) struct mlme_priv *mlme; struct mlme_ext_priv *mlmeext; u8 u_ch, u_offset, u_bw; - int i; + int i, ret; dvobj = adapter_to_dvobj(adapter); @@ -15900,19 +15950,20 @@ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) dump_adapters_status(RTW_DBGDUMP , dvobj); } - if (join_res >= 0) { + ret = rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset); + if (join_res >= 0 && ret <= 0) { + join_res = -1; + dump_adapters_status(RTW_DBGDUMP , dvobj); + rtw_warn_on(1); + } + if (join_res >= 0) { #ifdef CONFIG_MCC_MODE /* MCC setting success, don't go to ch union process */ if (rtw_hal_set_mcc_setting_join_done_chk_ch(adapter)) return; #endif /* CONFIG_MCC_MODE */ - if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset) <= 0) { - dump_adapters_status(RTW_DBGDUMP , dvobj); - rtw_warn_on(1); - } - for (i = 0; i < dvobj->iface_nums; i++) { iface = dvobj->padapters[i]; mlme = &iface->mlmepriv; @@ -15921,6 +15972,7 @@ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) if (!iface || iface == adapter) continue; +#ifdef CONFIG_AP_MODE if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface)) && check_fwstate(mlme, WIFI_ASOC_STATE) ) { @@ -15977,6 +16029,7 @@ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) clr_fwstate(mlme, WIFI_OP_CH_SWITCHING); update_beacon(iface, 0xFF, NULL, _TRUE, 0); } +#endif /* CONFIG_AP_MODE */ } #ifdef CONFIG_DFS_MASTER @@ -15990,13 +16043,14 @@ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) if (!iface || iface == adapter) continue; - +#ifdef CONFIG_AP_MODE if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface)) && check_fwstate(mlme, WIFI_ASOC_STATE) ) { clr_fwstate(mlme, WIFI_OP_CH_SWITCHING); update_beacon(iface, 0xFF, NULL, _TRUE, 0); } +#endif } #ifdef CONFIG_DFS_MASTER rtw_dfs_rd_en_decision(adapter, MLME_STA_DISCONNECTED, 0); @@ -16006,9 +16060,13 @@ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset)) { RTW_INFO(FUNC_ADPT_FMT" union:%u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset); set_channel_bwmode(adapter, u_ch, u_offset, u_bw); - rtw_mi_update_union_chan_inf(adapter, u_ch, u_offset, u_bw); } + rtw_mi_update_union_chan_inf(adapter, u_ch, u_offset, u_bw); + + if (join_res >= 0) + rtw_rfctl_update_op_mode(adapter_to_rfctl(adapter), BIT(adapter->iface_id), 1); + if (DUMP_ADAPTERS_STATUS) { RTW_INFO(FUNC_ADPT_FMT" exit\n", FUNC_ADPT_ARG(adapter)); dump_adapters_status(RTW_DBGDUMP , dvobj); @@ -16137,6 +16195,7 @@ connect_allow_hdl: if (!iface || iface == adapter) continue; + #ifdef CONFIG_AP_MODE if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface)) && check_fwstate(mlme, WIFI_ASOC_STATE) ) { @@ -16149,8 +16208,9 @@ connect_allow_hdl: rtw_hal_set_hwreg(iface, HW_VAR_CHECK_TXBUF, 0); set_fwstate(mlme, WIFI_OP_CH_SWITCHING); - - } else if (check_fwstate(mlme, WIFI_STATION_STATE) + } else + #endif /* CONFIG_AP_MODE */ + if (check_fwstate(mlme, WIFI_STATION_STATE) && check_fwstate(mlme, WIFI_ASOC_STATE) ) { rtw_disassoc_cmd(iface, 500, RTW_CMDF_DIRECTLY); @@ -16170,6 +16230,7 @@ exit: if (connect_allow == _TRUE) { RTW_INFO(FUNC_ADPT_FMT" union: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset); + rtw_mi_update_union_chan_inf(adapter, u_ch, u_offset, u_bw); *ch = u_ch; *bw = u_bw; *offset = u_offset; @@ -16216,10 +16277,19 @@ void rtw_set_external_auth_status(_adapter *padapter, #endif /* CONFIG_IOCTL_CFG80211 */ } +u8 rtw_iqk_hdl(_adapter *padapter, unsigned char *pbuf) +{ + rtw_hal_phydm_cal_trigger(padapter); + return H2C_SUCCESS; +} + u8 rtw_set_chbw_hdl(_adapter *padapter, u8 *pbuf) { struct set_ch_parm *set_ch_parm; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + u8 ifbmp_s = rtw_mi_get_ld_sta_ifbmp(padapter); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + u8 u_ch, u_bw, u_offset; if (!pbuf) return H2C_PARAMETERS_ERROR; @@ -16230,43 +16300,116 @@ u8 rtw_set_chbw_hdl(_adapter *padapter, u8 *pbuf) FUNC_NDEV_ARG(padapter->pnetdev), set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset); - pmlmeext->cur_channel = set_ch_parm->ch; - pmlmeext->cur_ch_offset = set_ch_parm->ch_offset; - pmlmeext->cur_bwmode = set_ch_parm->bw; + /* update ch, bw, offset for all asoc STA ifaces */ + if (ifbmp_s) { + _adapter *iface; + int i; + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (!iface || !(ifbmp_s & BIT(iface->iface_id))) + continue; + + /* update STA mode ch/bw/offset */ + iface->mlmeextpriv.cur_channel = set_ch_parm->ch; + iface->mlmeextpriv.cur_bwmode = set_ch_parm->bw; + iface->mlmeextpriv.cur_ch_offset = set_ch_parm->ch_offset; + /* updaet STA mode DSConfig , ap mode will update in rtw_change_bss_chbw_cmd */ + iface->mlmepriv.cur_network.network.Configuration.DSConfig = set_ch_parm->ch; + } + } + + LeaveAllPowerSaveModeDirect(padapter); + set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw); + rtw_mi_get_ch_setting_union(padapter, &u_ch, &u_bw, &u_offset); + rtw_mi_update_union_chan_inf(padapter, u_ch, u_offset, u_bw); + rtw_rfctl_update_op_mode(dvobj_to_rfctl(dvobj), 0, 0); + return H2C_SUCCESS; } -u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf) +u8 rtw_set_chplan_hdl(_adapter *padapter, unsigned char *pbuf) { - struct SetChannelPlan_param *setChannelPlan_param; + struct SetChannelPlan_param *param; struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); if (!pbuf) return H2C_PARAMETERS_ERROR; - setChannelPlan_param = (struct SetChannelPlan_param *)pbuf; + param = (struct SetChannelPlan_param *)pbuf; - if (!rtw_is_channel_plan_valid(setChannelPlan_param->channel_plan)) + if (param->regd_src == REGD_SRC_RTK_PRIV + && !rtw_is_channel_plan_valid(param->channel_plan)) return H2C_PARAMETERS_ERROR; - rfctl->country_ent = setChannelPlan_param->country_ent; - rfctl->ChannelPlan = setChannelPlan_param->channel_plan; +#ifdef CONFIG_REGD_SRC_FROM_OS + if (rfctl->regd_src == REGD_SRC_OS) + rtw_mfree((void *)rfctl->country_ent, sizeof(struct country_chplan)); +#endif + + rfctl->regd_src = param->regd_src; + rfctl->country_ent = param->country_ent; + rfctl->ChannelPlan = param->channel_plan; - rfctl->max_chan_nums = init_channel_set(padapter, rfctl->ChannelPlan, rfctl->channel_set); - init_channel_list(padapter, rfctl->channel_set, &rfctl->channel_list); #if CONFIG_TXPWR_LIMIT rtw_txpwr_init_regd(rfctl); #endif + rtw_rfctl_chplan_init(padapter); + rtw_hal_set_odm_var(padapter, HAL_ODM_REGULATION, NULL, _TRUE); #ifdef CONFIG_IOCTL_CFG80211 rtw_regd_apply_flags(adapter_to_wiphy(padapter)); #endif + rtw_nlrtw_reg_change_event(padapter); + + if (GET_HAL_DATA(padapter)->txpwr_limit_loaded + && rtw_get_hw_init_completed(padapter)) + rtw_hal_update_txpwr_level(padapter); + + return H2C_SUCCESS; +} + +u8 rtw_get_chplan_hdl(_adapter *padapter, unsigned char *pbuf) +{ + struct get_channel_plan_param *param; + struct get_chplan_resp *resp; + struct rf_ctl_t *rfctl; + + if (!pbuf) + return H2C_PARAMETERS_ERROR; + + rfctl = adapter_to_rfctl(padapter); + param = (struct get_channel_plan_param *)pbuf; + + resp = rtw_vmalloc(sizeof(struct get_chplan_resp) + sizeof(RT_CHANNEL_INFO) * rfctl->max_chan_nums); + if (!resp) + return H2C_CMD_FAIL; + + resp->regd_src = rfctl->regd_src; + + if (rfctl->country_ent) { + _rtw_memcpy(&resp->country_ent, rfctl->country_ent, sizeof(struct country_chplan)); + resp->has_country = 1; + } else + resp->has_country = 0; + + resp->channel_plan = rfctl->ChannelPlan; +#if CONFIG_TXPWR_LIMIT + resp->regd_name = rfctl->regd_name; +#endif +#ifdef CONFIG_DFS_MASTER + resp->dfs_domain = rtw_rfctl_get_dfs_domain(rfctl); +#endif + resp->chset_num = rfctl->max_chan_nums; + + _rtw_memcpy(resp->chset, rfctl->channel_set, sizeof(RT_CHANNEL_INFO) * rfctl->max_chan_nums); + *param->resp = resp; + return H2C_SUCCESS; } @@ -16286,6 +16429,49 @@ u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf) return H2C_SUCCESS; } +void csa_timer_hdl(void *FunctionContext) +{ + _adapter *padapter = (_adapter *)FunctionContext; + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 i, update_beacon = _FALSE; + + for (i = 0; i < dvobj->iface_nums; i++) { + _adapter *iface; + iface = dvobj->padapters[i]; + if (!iface) + continue; + if (check_fwstate(pmlmepriv, WIFI_CSA_UPDATE_BEACON)) { + clr_fwstate(pmlmepriv, WIFI_CSA_UPDATE_BEACON); + update_beacon = _TRUE; + } + } + + /* wait beacons more than 70 seconds */ + if(update_beacon == _TRUE) { + RTW_INFO("wait beacons more than 70 seconds\n"); + return ; + } + + if(rfctl->csa_ch == 0) { + RTW_INFO("channel switch done\n"); + return ; + } + + /* channel switch */ + if (rtw_set_csa_cmd(padapter) != _SUCCESS) { + rfctl->csa_ch = 0; + rfctl->csa_switch_cnt = 0; + rfctl->csa_ch_offset = 0; + rfctl->csa_ch_width = 0; + rfctl->csa_ch_freq_seg0 = 0; + rfctl->csa_ch_freq_seg1 = 0; + } +} + u8 set_csa_hdl(_adapter *adapter, unsigned char *pbuf) { #if CONFIG_DFS @@ -16428,7 +16614,11 @@ u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf) rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk); /* switch back to base-chnl */ + doiqk = _TRUE; + rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk); set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + doiqk = _FALSE; + rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk); rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START); @@ -16563,41 +16753,6 @@ u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf) return H2C_SUCCESS; } -u8 rtw_getmacreg_hdl(_adapter *padapter, u8 *pbuf) -{ - - struct readMAC_parm *preadmacparm = NULL; - u8 sz = 0; - u32 addr = 0; - u32 value = 0; - - if (!pbuf) - return H2C_PARAMETERS_ERROR; - - preadmacparm = (struct readMAC_parm *) pbuf; - sz = preadmacparm->len; - addr = preadmacparm->addr; - value = 0; - - switch (sz) { - case 1: - value = rtw_read8(padapter, addr); - break; - case 2: - value = rtw_read16(padapter, addr); - break; - case 4: - value = rtw_read32(padapter, addr); - break; - default: - RTW_INFO("%s: Unknown size\n", __func__); - break; - } - RTW_INFO("%s: addr:0x%02x valeu:0x%02x\n", __func__, addr, value); - - return H2C_SUCCESS; -} - int rtw_sae_preprocess(_adapter *adapter, const u8 *buf, u32 len, u8 tx) { #ifdef CONFIG_IOCTL_CFG80211 @@ -16659,3 +16814,14 @@ exit: #endif /* CONFIG_IOCTL_CFG80211 */ } +/* Needs to confirm with FW the value of REG_RX_BEACON_LENGTH */ +u8 rtw_write_bcnlen_hdl(_adapter *padapter, u8 *pbuf) +{ +#ifdef CONFIG_WRITE_BCN_LEN_TO_FW + struct write_bcnlen_param *parm = (struct write_bcnlen_param *)pbuf; + u16 bcn_len = parm->bcn_len; + + rtw_write16(padapter, REG_RX_BEACON_LENGTH + 2, bcn_len); +#endif + return H2C_SUCCESS; +} diff --git a/core/rtw_mp.c b/core/rtw_mp.c index 79ae501..c092680 100644 --- a/core/rtw_mp.c +++ b/core/rtw_mp.c @@ -237,6 +237,7 @@ s32 init_mp_priv(PADAPTER padapter) pmppriv->pktInterval = 0; pmppriv->pktLength = 1000; pmppriv->bprocess_mp_mode = _FALSE; + pmppriv->efuse_update_file= _FALSE; mp_init_xmit_attrib(&pmppriv->tx, padapter); @@ -392,7 +393,14 @@ void mpt_InitHWConfig(PADAPTER Adapter) PlatformEFIOWrite2Byte(Adapter, REG_RXFLTMAP1_8814B, 0x2000); } #endif - +#if defined(CONFIG_RTL8723F) + /* todo: 8723F not verify yet */ + else if (IS_HARDWARE_TYPE_8723F(Adapter)) { + /* 8723F mac is similar with 8723D, + * but can't find 8723D here. + */ + } +#endif } static void PHY_IQCalibrate(PADAPTER padapter, u8 bReCovery) @@ -512,13 +520,15 @@ static void PHY_SetRFPathSwitch(PADAPTER padapter , BOOLEAN bMain) { #endif } else if (IS_HARDWARE_TYPE_8822C(padapter)) { #ifdef CONFIG_RTL8822C - /* remove for MP EVM Fail, need to review by willis 20180809 phy_set_rf_path_switch_8822c(phydm, bMain); - */ #endif } else if (IS_HARDWARE_TYPE_8814B(padapter)) { #ifdef CONFIG_RTL8814B /* phy_set_rf_path_switch_8814b(phydm, bMain); */ +#endif + } else if (IS_HARDWARE_TYPE_8723F(padapter)) { +#ifdef CONFIG_RTL8723F + phy_set_rf_path_switch_8723f(phydm, bMain); #endif } } @@ -753,56 +763,60 @@ static void init_mp_data(PADAPTER padapter) pDM_Odm->rf_calibrate_info.txpowertrack_control = _FALSE; } -void MPT_PwrCtlDM(PADAPTER padapter, u32 bstart) + +void MPT_PwrCtlDM(PADAPTER padapter, u32 trk_type) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct dm_struct *pDM_Odm = &pHalData->odmpriv; u32 rf_ability; - padapter->mppriv.tssitrk_on = bstart == 3; + padapter->mppriv.tssitrk_on = trk_type == 3; - if (bstart == 1) { - RTW_INFO("in MPT_PwrCtlDM start\n"); + if (trk_type == 0) { /* thermal PwrTrk off*/ + struct txpwrtrack_cfg c; + u8 chnl = 0 ; - rf_ability = ((u32)halrf_cmn_info_get(pDM_Odm, HALRF_CMNINFO_ABILITY)) | HAL_RF_TX_PWR_TRACK; - halrf_cmn_info_set(pDM_Odm, HALRF_CMNINFO_ABILITY, rf_ability); - halrf_set_pwr_track(pDM_Odm, bstart); - pDM_Odm->rf_calibrate_info.txpowertrack_control = _TRUE; - padapter->mppriv.mp_dm = 1; - - } else { - RTW_INFO("in MPT_PwrCtlDM stop\n"); + RTW_INFO("in Thermal tracking off\n"); rf_ability = ((u32)halrf_cmn_info_get(pDM_Odm, HALRF_CMNINFO_ABILITY)) & ~HAL_RF_TX_PWR_TRACK; halrf_cmn_info_set(pDM_Odm, HALRF_CMNINFO_ABILITY, rf_ability); - halrf_set_pwr_track(pDM_Odm, bstart); - pDM_Odm->rf_calibrate_info.txpowertrack_control = _FALSE; + halrf_cmn_info_set(pDM_Odm, HALRF_CMNINFO_POWER_TRACK_CONTROL, trk_type); + halrf_set_pwr_track(pDM_Odm, FALSE); + pDM_Odm->rf_calibrate_info.txpowertrack_control = trk_type; if (IS_HARDWARE_TYPE_8822C(padapter)) padapter->mppriv.mp_dm = 1; /* default enable dpk tracking */ else padapter->mppriv.mp_dm = 0; - { - struct txpwrtrack_cfg c; - u8 chnl = 0 ; - _rtw_memset(&c, 0, sizeof(struct txpwrtrack_cfg)); - configure_txpower_track(pDM_Odm, &c); - odm_clear_txpowertracking_state(pDM_Odm); - if (*c.odm_tx_pwr_track_set_pwr) { - if (pDM_Odm->support_ic_type == ODM_RTL8188F) - (*c.odm_tx_pwr_track_set_pwr)(pDM_Odm, MIX_MODE, RF_PATH_A, chnl); - else if (pDM_Odm->support_ic_type == ODM_RTL8723D) { - (*c.odm_tx_pwr_track_set_pwr)(pDM_Odm, BBSWING, RF_PATH_A, chnl); - SetTxPower(padapter); - } else if (pDM_Odm->support_ic_type == ODM_RTL8192F) { - (*c.odm_tx_pwr_track_set_pwr)(pDM_Odm, MIX_MODE, RF_PATH_A, chnl); - (*c.odm_tx_pwr_track_set_pwr)(pDM_Odm, MIX_MODE, RF_PATH_B, chnl); - } else { - (*c.odm_tx_pwr_track_set_pwr)(pDM_Odm, BBSWING, RF_PATH_A, chnl); - (*c.odm_tx_pwr_track_set_pwr)(pDM_Odm, BBSWING, RF_PATH_B, chnl); - } + + _rtw_memset(&c, 0, sizeof(struct txpwrtrack_cfg)); + configure_txpower_track(pDM_Odm, &c); + odm_clear_txpowertracking_state(pDM_Odm); + if (*c.odm_tx_pwr_track_set_pwr) { + if (pDM_Odm->support_ic_type == ODM_RTL8188F) + (*c.odm_tx_pwr_track_set_pwr)(pDM_Odm, MIX_MODE, RF_PATH_A, chnl); + else if (pDM_Odm->support_ic_type == ODM_RTL8723D) { + (*c.odm_tx_pwr_track_set_pwr)(pDM_Odm, BBSWING, RF_PATH_A, chnl); + SetTxPower(padapter); + } else if (pDM_Odm->support_ic_type == ODM_RTL8192F) { + (*c.odm_tx_pwr_track_set_pwr)(pDM_Odm, MIX_MODE, RF_PATH_A, chnl); + (*c.odm_tx_pwr_track_set_pwr)(pDM_Odm, MIX_MODE, RF_PATH_B, chnl); + } else { + (*c.odm_tx_pwr_track_set_pwr)(pDM_Odm, BBSWING, RF_PATH_A, chnl); + (*c.odm_tx_pwr_track_set_pwr)(pDM_Odm, BBSWING, RF_PATH_B, chnl); } } + return ; } + rf_ability = ((u32)halrf_cmn_info_get(pDM_Odm, HALRF_CMNINFO_ABILITY)) | HAL_RF_TX_PWR_TRACK; + halrf_cmn_info_set(pDM_Odm, HALRF_CMNINFO_ABILITY, rf_ability); + halrf_cmn_info_set(pDM_Odm, HALRF_CMNINFO_POWER_TRACK_CONTROL, trk_type); + if (trk_type == 1 || trk_type == 3) /* Thermal PwrTrk ON , TSSI PwrTrk ON */ + halrf_set_pwr_track(pDM_Odm, TRUE); + else + halrf_set_pwr_track(pDM_Odm, false);/* TSSI K */ + pDM_Odm->rf_calibrate_info.txpowertrack_control = trk_type; + padapter->mppriv.mp_dm = 1; + } @@ -854,7 +868,7 @@ u32 mp_join(PADAPTER padapter, u8 mode) goto end_of_mp_start_test; /* init mp_start_test status */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { rtw_disassoc_cmd(padapter, 500, 0); rtw_indicate_disconnect(padapter, 0, _FALSE); rtw_free_assoc_resources_cmd(padapter, _TRUE, 0); @@ -863,7 +877,7 @@ u32 mp_join(PADAPTER padapter, u8 mode) /*pmlmepriv->fw_state = WIFI_MP_STATE;*/ init_fwstate(pmlmepriv, WIFI_MP_STATE); - set_fwstate(pmlmepriv, _FW_UNDER_LINKING); + set_fwstate(pmlmepriv, WIFI_UNDER_LINKING); /* 3 2. create a new psta for mp driver */ /* clear psta in the cur_network, if any */ @@ -892,8 +906,8 @@ u32 mp_join(PADAPTER padapter, u8 mode) _rtw_memcpy(pnetwork, &padapter->registrypriv.dev_network, padapter->registrypriv.dev_network.Length); rtw_indicate_connect(padapter); - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); - set_fwstate(pmlmepriv, _FW_LINKED); + _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING); + set_fwstate(pmlmepriv, WIFI_ASOC_STATE); end_of_mp_start_test: @@ -1074,7 +1088,7 @@ static void mpt_AdjustRFRegByRateByChan92CU(PADAPTER pAdapter, u8 RateIdx, u8 Ch { u8 eRFPath; u32 rfReg0x26; - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(pAdapter); if (RateIdx < MPT_RATE_6M) /* CCK rate,for 88cu */ @@ -1106,7 +1120,7 @@ static void mpt_AdjustRFRegByRateByChan92CU(PADAPTER pAdapter, u8 RateIdx, u8 Ch } } - for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) + for (eRFPath = 0; eRFPath < hal_spec->rf_reg_path_num; eRFPath++) write_rfreg(pAdapter, eRFPath, RF_SYN_G2, rfReg0x26); } #endif @@ -1280,7 +1294,7 @@ static struct xmit_frame *alloc_mp_xmitframe(struct xmit_priv *pxmitpriv) struct xmit_frame *pmpframe; struct xmit_buf *pxmitbuf; - pmpframe = rtw_alloc_xmitframe(pxmitpriv); + pmpframe = rtw_alloc_xmitframe(pxmitpriv, 0); if (pmpframe == NULL) return NULL; @@ -2003,6 +2017,11 @@ void SetPacketTx(PADAPTER padapter) rtl8814b_prepare_mp_txdesc(padapter, pmp_priv); #endif /* CONFIG_RTL8814B */ +#if defined(CONFIG_RTL8723F) + if (IS_HARDWARE_TYPE_8723F(padapter)) + rtl8723f_prepare_mp_txdesc(padapter, pmp_priv); +#endif /* CONFIG_RTL8723F */ + /* 3 4. make wlan header, make_wlanhdr() */ hdr = (struct rtw_ieee80211_hdr *)pkt_start; set_frame_sub_type(&hdr->frame_ctl, pattrib->subtype); @@ -2122,6 +2141,7 @@ void SetPacketRx(PADAPTER pAdapter, u8 bStartRx, u8 bAB) pHalData->ReceiveConfig |= RCR_APP_PHYST_RXFF; #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) +/* todo: 8723F */ write_bbreg(pAdapter, 0x550, BIT3, bEnable); #endif rtw_write16(pAdapter, REG_RXFLTMAP0, 0xFFEF); /* REG_RXFLTMAP0 (RX Filter Map Group 0) */ @@ -2363,7 +2383,9 @@ static u32 rtw_GetPSDData(PADAPTER pAdapter, u32 point) { u32 psd_val = 0; -#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A) \ + || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) + u16 psd_reg = 0x910; u16 psd_regL = 0xF44; #else @@ -2438,12 +2460,12 @@ u32 mp_query_psd(PADAPTER pAdapter, u8 *data) data[0] = '\0'; pdata = data; - if (psd_stop > 1536 || psd_stop < 1) { + if (psd_stop > 1920 || psd_stop < 1) { rtw_warn_on(1); - psd_stop = 1536; + psd_stop = 1920; } - if (IS_HARDWARE_TYPE_8822C(pAdapter)) { + if (IS_HARDWARE_TYPE_8822C(pAdapter) || IS_HARDWARE_TYPE_8723F(pAdapter)) { u32 *psdbuf = rtw_zmalloc(sizeof(u32)*256); if (psdbuf == NULL) { diff --git a/core/rtw_odm.c b/core/rtw_odm.c index de0fbde..9651d4f 100644 --- a/core/rtw_odm.c +++ b/core/rtw_odm.c @@ -178,6 +178,11 @@ void rtw_odm_releasespinlock(_adapter *adapter, enum rt_spinlock_type type) } } +s16 rtw_odm_get_tx_power_mbm(struct dm_struct *dm, u8 rfpath, u8 rate, u8 bw, u8 cch) +{ + return phy_get_txpwr_single_mbm(dm->adapter, rfpath, mgn_rate_to_rs(rate), rate, bw, cch, 0, 0, 0, NULL); +} + #ifdef CONFIG_DFS_MASTER inline void rtw_odm_radar_detect_reset(_adapter *adapter) { @@ -200,6 +205,20 @@ inline BOOLEAN rtw_odm_radar_detect(_adapter *adapter) return phydm_radar_detect(adapter_to_phydm(adapter)); } +static enum phydm_dfs_region_domain _rtw_dfs_regd_to_phydm[] = { + [RTW_DFS_REGD_NONE] = PHYDM_DFS_DOMAIN_UNKNOWN, + [RTW_DFS_REGD_FCC] = PHYDM_DFS_DOMAIN_FCC, + [RTW_DFS_REGD_MKK] = PHYDM_DFS_DOMAIN_MKK, + [RTW_DFS_REGD_ETSI] = PHYDM_DFS_DOMAIN_ETSI, +}; + +#define rtw_dfs_regd_to_phydm(region) (((region) >= RTW_DFS_REGD_NUM) ? _rtw_dfs_regd_to_phydm[RTW_DFS_REGD_NONE] : _rtw_dfs_regd_to_phydm[(region)]) + +void rtw_odm_update_dfs_region(struct dvobj_priv *dvobj) +{ + odm_cmn_info_init(dvobj_to_phydm(dvobj), ODM_CMNINFO_DFS_REGION_DOMAIN, rtw_dfs_regd_to_phydm(rtw_rfctl_get_dfs_domain(dvobj_to_rfctl(dvobj)))); +} + inline u8 rtw_odm_radar_detect_polling_int_ms(struct dvobj_priv *dvobj) { return phydm_dfs_polling_time(dvobj_to_phydm(dvobj)); diff --git a/core/rtw_p2p.c b/core/rtw_p2p.c index ff9bca8..24372de 100644 --- a/core/rtw_p2p.c +++ b/core/rtw_p2p.c @@ -598,7 +598,7 @@ u32 build_beacon_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) /* Value: */ /* Associated BSSID */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) _rtw_memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[0], ETH_ALEN); else _rtw_memset(wfdie + wfdielen, 0x00, ETH_ALEN); @@ -710,7 +710,7 @@ u32 build_probe_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) /* Value: */ /* Associated BSSID */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) _rtw_memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[0], ETH_ALEN); else _rtw_memset(wfdie + wfdielen, 0x00, ETH_ALEN); @@ -853,7 +853,7 @@ u32 build_probe_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 tunnel /* Value: */ /* Associated BSSID */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) _rtw_memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[0], ETH_ALEN); else _rtw_memset(wfdie + wfdielen, 0x00, ETH_ALEN); @@ -1007,7 +1007,7 @@ u32 build_assoc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) /* Value: */ /* Associated BSSID */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) _rtw_memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[0], ETH_ALEN); else _rtw_memset(wfdie + wfdielen, 0x00, ETH_ALEN); @@ -1106,7 +1106,7 @@ u32 build_assoc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) /* Value: */ /* Associated BSSID */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) _rtw_memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[0], ETH_ALEN); else _rtw_memset(wfdie + wfdielen, 0x00, ETH_ALEN); @@ -1205,7 +1205,7 @@ u32 build_nego_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) /* Value: */ /* Associated BSSID */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) _rtw_memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[0], ETH_ALEN); else _rtw_memset(wfdie + wfdielen, 0x00, ETH_ALEN); @@ -1304,7 +1304,7 @@ u32 build_nego_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) /* Value: */ /* Associated BSSID */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) _rtw_memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[0], ETH_ALEN); else _rtw_memset(wfdie + wfdielen, 0x00, ETH_ALEN); @@ -1404,7 +1404,7 @@ u32 build_nego_confirm_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) /* Value: */ /* Associated BSSID */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) _rtw_memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[0], ETH_ALEN); else _rtw_memset(wfdie + wfdielen, 0x00, ETH_ALEN); @@ -1504,7 +1504,7 @@ u32 build_invitation_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) /* Value: */ /* Associated BSSID */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) _rtw_memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[0], ETH_ALEN); else _rtw_memset(wfdie + wfdielen, 0x00, ETH_ALEN); @@ -1617,7 +1617,7 @@ u32 build_invitation_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) /* Value: */ /* Associated BSSID */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) _rtw_memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[0], ETH_ALEN); else _rtw_memset(wfdie + wfdielen, 0x00, ETH_ALEN); @@ -1730,7 +1730,7 @@ u32 build_provdisc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) /* Value: */ /* Associated BSSID */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) _rtw_memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[0], ETH_ALEN); else _rtw_memset(wfdie + wfdielen, 0x00, ETH_ALEN); @@ -1830,7 +1830,7 @@ u32 build_provdisc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) /* Value: */ /* Associated BSSID */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) _rtw_memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[0], ETH_ALEN); else _rtw_memset(wfdie + wfdielen, 0x00, ETH_ALEN); @@ -2911,6 +2911,7 @@ u8 process_p2p_group_negotation_confirm(struct wifidirect_info *pwdinfo, u8 *pfr { #ifdef CONFIG_CONCURRENT_MODE _adapter *padapter = pwdinfo->padapter; + struct roch_info *prochinfo = &padapter->rochinfo; #endif u8 *ies; u32 ies_len; @@ -2956,7 +2957,7 @@ u8 process_p2p_group_negotation_confirm(struct wifidirect_info *pwdinfo, u8 *pfr if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) { /* Switch back to the AP channel soon. */ - _set_timer(&pwdinfo->ap_p2p_switch_timer, 100); + _set_timer(&prochinfo->ap_roch_ch_switch_timer, 100); } #endif } else { @@ -3029,8 +3030,6 @@ void find_phase_handler(_adapter *padapter) } -void p2p_concurrent_handler(_adapter *padapter); - void restore_p2p_state_handler(_adapter *padapter) { struct wifidirect_info *pwdinfo = &padapter->wdinfo; @@ -3055,7 +3054,7 @@ void restore_p2p_state_handler(_adapter *padapter) if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) { #ifdef CONFIG_CONCURRENT_MODE - p2p_concurrent_handler(padapter); + rtw_concurrent_handler(padapter); #else /* In the P2P client mode, the driver should not switch back to its listen channel */ /* because this P2P client should stay at the operating channel of P2P GO. */ @@ -3102,344 +3101,7 @@ void pre_tx_negoreq_handler(_adapter *padapter) } -#ifdef CONFIG_CONCURRENT_MODE -void p2p_concurrent_handler(_adapter *padapter) -{ - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - u8 val8; - #ifdef CONFIG_IOCTL_CFG80211 - if (pwdinfo->driver_interface == DRIVER_CFG80211 - && !rtw_cfg80211_get_is_roch(padapter)) - return; -#endif - - if (rtw_mi_check_status(padapter, MI_LINKED)) { - u8 union_ch = rtw_mi_get_union_chan(padapter); - u8 union_bw = rtw_mi_get_union_bw(padapter); - u8 union_offset = rtw_mi_get_union_offset(padapter); - - pwdinfo->operating_channel = union_ch; - - if (pwdinfo->driver_interface == DRIVER_CFG80211) { - RTW_INFO("%s, switch ch back to union=%u,%u, %u\n" - , __func__, union_ch, union_bw, union_offset); - set_channel_bwmode(padapter, union_ch, union_offset, union_bw); - rtw_back_opch(padapter); - - } else if (pwdinfo->driver_interface == DRIVER_WEXT) { - if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) { - /* Now, the driver stays on the AP's channel. */ - /* If the pwdinfo->ext_listen_period = 0, that means the P2P listen state is not available on listen channel. */ - if (pwdinfo->ext_listen_period > 0) { - RTW_INFO("[%s] P2P_STATE_IDLE, ext_listen_period = %d\n", __FUNCTION__, pwdinfo->ext_listen_period); - - if (union_ch != pwdinfo->listen_channel) { - rtw_leave_opch(padapter); - set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); - } - - rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); - - if (!rtw_mi_check_mlmeinfo_state(padapter, WIFI_FW_AP_STATE)) { - val8 = 1; - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - } - /* Todo: To check the value of pwdinfo->ext_listen_period is equal to 0 or not. */ - _set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period); - } - - } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) || - rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL) || - (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _FALSE) || - rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ)) { - /* Now, the driver is in the listen state of P2P mode. */ - RTW_INFO("[%s] P2P_STATE_IDLE, ext_listen_interval = %d\n", __FUNCTION__, pwdinfo->ext_listen_interval); - - /* Commented by Albert 2012/11/01 */ - /* If the AP's channel is the same as the listen channel, we should still be in the listen state */ - /* Other P2P device is still able to find this device out even this device is in the AP's channel. */ - /* So, configure this device to be able to receive the probe request frame and set it to listen state. */ - if (union_ch != pwdinfo->listen_channel) { - - set_channel_bwmode(padapter, union_ch, union_offset, union_bw); - if (!rtw_mi_check_status(padapter, MI_AP_MODE)) { - val8 = 0; - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - } - rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE); - rtw_back_opch(padapter); - } - - /* Todo: To check the value of pwdinfo->ext_listen_interval is equal to 0 or not. */ - _set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval); - - } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK)) { - /* The driver had finished the P2P handshake successfully. */ - val8 = 0; - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - set_channel_bwmode(padapter, union_ch, union_offset, union_bw); - rtw_back_opch(padapter); - - } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) { - val8 = 1; - set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - issue_probereq_p2p(padapter, NULL); - _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); - } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _TRUE) { - val8 = 1; - set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - issue_probereq_p2p(padapter, NULL); - _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); - } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ) && pwdinfo->invitereq_info.benable == _TRUE) { - /* - val8 = 1; - set_channel_bwmode(padapter, , HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - issue_probereq_p2p(padapter, NULL); - _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); - */ - } - } - } else { - /* In p2p+softap. When in P2P_STATE_GONEGO_OK, not back to listen channel.*/ - if (!rtw_p2p_chk_state(pwdinfo , P2P_STATE_GONEGO_OK) || padapter->registrypriv.full_ch_in_p2p_handshake == 0) - set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); - else - RTW_INFO("%s, buddy not linked, go nego ok, not back to listen channel\n", __func__); - } - -} -#endif - -#ifdef CONFIG_IOCTL_CFG80211 -u8 roch_stay_in_cur_chan(_adapter *padapter) -{ - int i; - _adapter *iface; - struct mlme_priv *pmlmepriv; - struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); - u8 rst = _FALSE; - - for (i = 0; i < dvobj->iface_nums; i++) { - iface = dvobj->padapters[i]; - if (iface) { - pmlmepriv = &iface->mlmepriv; - - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING | WIFI_UNDER_WPS | WIFI_UNDER_KEY_HANDSHAKE) == _TRUE) { - RTW_INFO(ADPT_FMT"- _FW_UNDER_LINKING |WIFI_UNDER_WPS | WIFI_UNDER_KEY_HANDSHAKE (mlme state:0x%x)\n", - ADPT_ARG(iface), get_fwstate(&iface->mlmepriv)); - rst = _TRUE; - break; - } - #ifdef CONFIG_AP_MODE - if (MLME_IS_AP(iface) || MLME_IS_MESH(iface)) { - if (rtw_ap_sta_states_check(iface) == _TRUE) { - rst = _TRUE; - break; - } - } - #endif - } - } - - return rst; -} - -static int ro_ch_handler(_adapter *adapter, u8 *buf) -{ - int ret = H2C_SUCCESS; - struct p2p_roch_parm *roch_parm = (struct p2p_roch_parm *)buf; - struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); - struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &adapter->cfg80211_wdinfo; -#ifdef CONFIG_CONCURRENT_MODE - struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; -#ifdef RTW_ROCH_BACK_OP - struct wifidirect_info *pwdinfo = &adapter->wdinfo; -#endif -#endif - u8 ready_on_channel = _FALSE; - u8 remain_ch; - unsigned int duration; - - _enter_critical_mutex(&pwdev_priv->roch_mutex, NULL); - - if (rtw_cfg80211_get_is_roch(adapter) != _TRUE) - goto exit; - - remain_ch = (u8)ieee80211_frequency_to_channel(roch_parm->ch.center_freq); - duration = roch_parm->duration; - - RTW_INFO(FUNC_ADPT_FMT" ch:%u duration:%d, cookie:0x%llx\n" - , FUNC_ADPT_ARG(adapter), remain_ch, roch_parm->duration, roch_parm->cookie); - - if (roch_parm->wdev && roch_parm->cookie) { - if (pcfg80211_wdinfo->ro_ch_wdev != roch_parm->wdev) { - RTW_WARN(FUNC_ADPT_FMT" ongoing wdev:%p, wdev:%p\n" - , FUNC_ADPT_ARG(adapter), pcfg80211_wdinfo->ro_ch_wdev, roch_parm->wdev); - rtw_warn_on(1); - } - - if (pcfg80211_wdinfo->remain_on_ch_cookie != roch_parm->cookie) { - RTW_WARN(FUNC_ADPT_FMT" ongoing cookie:0x%llx, cookie:0x%llx\n" - , FUNC_ADPT_ARG(adapter), pcfg80211_wdinfo->remain_on_ch_cookie, roch_parm->cookie); - rtw_warn_on(1); - } - } - - if (roch_stay_in_cur_chan(adapter) == _TRUE) { - remain_ch = rtw_mi_get_union_chan(adapter); - RTW_INFO(FUNC_ADPT_FMT" stay in union ch:%d\n", FUNC_ADPT_ARG(adapter), remain_ch); - } - - #ifdef CONFIG_CONCURRENT_MODE - if (rtw_mi_check_status(adapter, MI_LINKED) && (0 != rtw_mi_get_union_chan(adapter))) { - if ((remain_ch != rtw_mi_get_union_chan(adapter)) && !check_fwstate(&adapter->mlmepriv, _FW_LINKED)) { - if (remain_ch != pmlmeext->cur_channel - #ifdef RTW_ROCH_BACK_OP - || ATOMIC_READ(&pwdev_priv->switch_ch_to) == 1 - #endif - ) { - rtw_leave_opch(adapter); - - #ifdef RTW_ROCH_BACK_OP - RTW_INFO("%s, set switch ch timer, duration=%d\n", __func__, duration - pwdinfo->ext_listen_interval); - ATOMIC_SET(&pwdev_priv->switch_ch_to, 0); - _set_timer(&pwdinfo->ap_p2p_switch_timer, duration - pwdinfo->ext_listen_interval); - #endif - } - } - ready_on_channel = _TRUE; - } else - #endif /* CONFIG_CONCURRENT_MODE */ - { - if (remain_ch != rtw_get_oper_ch(adapter)) - ready_on_channel = _TRUE; - } - - if (ready_on_channel == _TRUE) { - #ifndef RTW_SINGLE_WIPHY - if (!check_fwstate(&adapter->mlmepriv, _FW_LINKED)) - #endif - { - #ifdef CONFIG_CONCURRENT_MODE - if (rtw_get_oper_ch(adapter) != remain_ch) - #endif - { - /* if (!padapter->mlmepriv.LinkDetectInfo.bBusyTraffic) */ - set_channel_bwmode(adapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); - } - } - } - - #ifdef CONFIG_BT_COEXIST - rtw_btcoex_ScanNotify(adapter, _TRUE); - #endif - - RTW_INFO("%s, set ro ch timer, duration=%d\n", __func__, duration); - _set_timer(&pcfg80211_wdinfo->remain_on_ch_timer, duration); - -exit: - _exit_critical_mutex(&pwdev_priv->roch_mutex, NULL); - - return ret; -} - -static int cancel_ro_ch_handler(_adapter *padapter, u8 *buf) -{ - int ret = H2C_SUCCESS; - struct p2p_roch_parm *roch_parm = (struct p2p_roch_parm *)buf; - struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); - struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; - struct wireless_dev *wdev; - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - u8 ch, bw, offset; - - _enter_critical_mutex(&pwdev_priv->roch_mutex, NULL); - - if (rtw_cfg80211_get_is_roch(padapter) != _TRUE) - goto exit; - - if (roch_parm->wdev && roch_parm->cookie) { - if (pcfg80211_wdinfo->ro_ch_wdev != roch_parm->wdev) { - RTW_WARN(FUNC_ADPT_FMT" ongoing wdev:%p, wdev:%p\n" - , FUNC_ADPT_ARG(padapter), pcfg80211_wdinfo->ro_ch_wdev, roch_parm->wdev); - rtw_warn_on(1); - } - - if (pcfg80211_wdinfo->remain_on_ch_cookie != roch_parm->cookie) { - RTW_WARN(FUNC_ADPT_FMT" ongoing cookie:0x%llx, cookie:0x%llx\n" - , FUNC_ADPT_ARG(padapter), pcfg80211_wdinfo->remain_on_ch_cookie, roch_parm->cookie); - rtw_warn_on(1); - } - } - -#if defined(RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE) - _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer); - ATOMIC_SET(&pwdev_priv->switch_ch_to, 1); -#endif - - if (rtw_mi_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { - if (0) - RTW_INFO(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", - FUNC_ADPT_ARG(padapter), ch, bw, offset); - } else if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->listen_channel) { - ch = pwdinfo->listen_channel; - bw = CHANNEL_WIDTH_20; - offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - if (0) - RTW_INFO(FUNC_ADPT_FMT" back to listen ch - ch:%u, bw:%u, offset:%u\n", - FUNC_ADPT_ARG(padapter), ch, bw, offset); - } else { - ch = pcfg80211_wdinfo->restore_channel; - bw = CHANNEL_WIDTH_20; - offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - if (0) - RTW_INFO(FUNC_ADPT_FMT" back to restore ch - ch:%u, bw:%u, offset:%u\n", - FUNC_ADPT_ARG(padapter), ch, bw, offset); - } - - set_channel_bwmode(padapter, ch, offset, bw); - rtw_back_opch(padapter); - - rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); -#ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo)); -#endif - - wdev = pcfg80211_wdinfo->ro_ch_wdev; - - rtw_cfg80211_set_is_roch(padapter, _FALSE); - pcfg80211_wdinfo->ro_ch_wdev = NULL; - rtw_cfg80211_set_last_ro_ch_time(padapter); - - rtw_cfg80211_remain_on_channel_expired(wdev - , pcfg80211_wdinfo->remain_on_ch_cookie - , &pcfg80211_wdinfo->remain_on_ch_channel - , pcfg80211_wdinfo->remain_on_ch_type, GFP_KERNEL); - - RTW_INFO("cfg80211_remain_on_channel_expired cookie:0x%llx\n" - , pcfg80211_wdinfo->remain_on_ch_cookie); - -#ifdef CONFIG_BT_COEXIST - rtw_btcoex_ScanNotify(padapter, _FALSE); -#endif - -exit: - _exit_critical_mutex(&pwdev_priv->roch_mutex, NULL); - - return ret; -} - -static void ro_ch_timer_process(void *FunctionContext) -{ - _adapter *adapter = (_adapter *)FunctionContext; - - p2p_cancel_roch_cmd(adapter, 0, NULL, 0); -} #if 0 static void rtw_change_p2pie_op_ch(_adapter *padapter, const u8 *frame_body, u32 len, u8 ch) @@ -4275,15 +3937,6 @@ int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx) return is_p2p_frame; } - -void rtw_init_cfg80211_wifidirect_info(_adapter *padapter) -{ - struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; - - _rtw_memset(pcfg80211_wdinfo, 0x00, sizeof(struct cfg80211_wifidirect_info)); - - rtw_init_timer(&pcfg80211_wdinfo->remain_on_ch_timer, padapter, ro_ch_timer_process, padapter); -} #endif /* CONFIG_IOCTL_CFG80211 */ s32 p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType, u8 *buf) @@ -4302,7 +3955,7 @@ s32 p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType, u8 *buf) case P2P_PRE_TX_PROVDISC_PROCESS_WK: #ifdef CONFIG_CONCURRENT_MODE if (rtw_mi_check_status(padapter, MI_LINKED)) - p2p_concurrent_handler(padapter); + rtw_concurrent_handler(padapter); else pre_tx_provdisc_handler(padapter); #else @@ -4313,7 +3966,7 @@ s32 p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType, u8 *buf) case P2P_PRE_TX_INVITEREQ_PROCESS_WK: #ifdef CONFIG_CONCURRENT_MODE if (rtw_mi_check_status(padapter, MI_LINKED)) - p2p_concurrent_handler(padapter); + rtw_concurrent_handler(padapter); else pre_tx_invitereq_handler(padapter); #else @@ -4324,7 +3977,7 @@ s32 p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType, u8 *buf) case P2P_PRE_TX_NEGOREQ_PROCESS_WK: #ifdef CONFIG_CONCURRENT_MODE if (rtw_mi_check_status(padapter, MI_LINKED)) - p2p_concurrent_handler(padapter); + rtw_concurrent_handler(padapter); else pre_tx_negoreq_handler(padapter); #else @@ -4332,21 +3985,6 @@ s32 p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType, u8 *buf) #endif break; -#ifdef CONFIG_CONCURRENT_MODE - case P2P_AP_P2P_CH_SWITCH_PROCESS_WK: - p2p_concurrent_handler(padapter); - break; -#endif - -#ifdef CONFIG_IOCTL_CFG80211 - case P2P_RO_CH_WK: - ret = ro_ch_handler(padapter, buf); - break; - case P2P_CANCEL_RO_CH_WK: - ret = cancel_ro_ch_handler(padapter, buf); - break; -#endif - default: rtw_warn_on(1); break; @@ -4499,13 +4137,16 @@ void p2p_ps_wk_hdl(_adapter *padapter, u8 p2p_ps_state) rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); +#ifdef CONFIG_LPS if (pwdinfo->opp_ps == 1) { if (pwrpriv->smart_ps == 0) { pwrpriv->smart_ps = 2; if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) - rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(pwrpriv->pwr_mode))); + rtw_exec_lps(padapter, pwrpriv->pwr_mode); } } +#endif /* CONFIG_LPS */ + pwdinfo->noa_index = 0; pwdinfo->ctwindow = 0; pwdinfo->opp_ps = 0; @@ -4519,7 +4160,7 @@ void p2p_ps_wk_hdl(_adapter *padapter, u8 p2p_ps_state) _exit_pwrlock(&adapter_to_pwrctl(padapter)->lock); if ((ps_deny & (PS_DENY_SCAN | PS_DENY_JOIN)) - || rtw_mi_check_fwstate(padapter, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING))) { + || rtw_mi_check_fwstate(padapter, (WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING))) { pwdinfo->p2p_ps_mode = P2P_PS_NONE; RTW_DBG(FUNC_ADPT_FMT" Block P2P PS under site survey or LINKING\n", FUNC_ADPT_ARG(padapter)); return; @@ -4536,14 +4177,17 @@ void p2p_ps_wk_hdl(_adapter *padapter, u8 p2p_ps_state) #endif /* CONFIG_MCC_MODE */ pwdinfo->p2p_ps_state = p2p_ps_state; +#ifdef CONFIG_LPS if (pwdinfo->ctwindow > 0) { if (pwrpriv->smart_ps != 0) { pwrpriv->smart_ps = 0; RTW_INFO("%s(): Enter CTW, change SmartPS\n", __FUNCTION__); if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) - rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(pwrpriv->pwr_mode))); + rtw_exec_lps(padapter, pwrpriv->pwr_mode); } } +#endif /* CONFIG_LPS */ + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); } break; @@ -4601,7 +4245,7 @@ u8 p2p_ps_wk_cmd(_adapter *padapter, u8 p2p_ps_state, u8 enqueue) pdrvextra_cmd_parm->size = 0; pdrvextra_cmd_parm->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, ph2c); } else @@ -4708,26 +4352,6 @@ static void find_phase_timer_process(void *FunctionContext) p2p_protocol_wk_cmd(adapter, P2P_FIND_PHASE_WK); } -#ifdef CONFIG_CONCURRENT_MODE -void ap_p2p_switch_timer_process(void *FunctionContext) -{ - _adapter *adapter = (_adapter *)FunctionContext; - struct wifidirect_info *pwdinfo = &adapter->wdinfo; -#ifdef CONFIG_IOCTL_CFG80211 - struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); -#endif - - if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) - return; - -#ifdef CONFIG_IOCTL_CFG80211 - ATOMIC_SET(&pwdev_priv->switch_ch_to, 1); -#endif - - p2p_protocol_wk_cmd(adapter, P2P_AP_P2P_CH_SWITCH_PROCESS_WK); -} -#endif - void reset_global_wifidirect_info(_adapter *padapter) { struct wifidirect_info *pwdinfo; @@ -4959,9 +4583,6 @@ void rtw_init_wifidirect_timers(_adapter *padapter) rtw_init_timer(&pwdinfo->pre_tx_scan_timer, padapter, pre_tx_scan_timer_process, padapter); rtw_init_timer(&pwdinfo->reset_ch_sitesurvey, padapter, reset_ch_sitesurvey_timer_process, padapter); rtw_init_timer(&pwdinfo->reset_ch_sitesurvey2, padapter, reset_ch_sitesurvey_timer_process2, padapter); -#ifdef CONFIG_CONCURRENT_MODE - rtw_init_timer(&pwdinfo->ap_p2p_switch_timer, padapter, ap_p2p_switch_timer_process, padapter); -#endif } void rtw_init_wifidirect_addrs(_adapter *padapter, u8 *dev_addr, u8 *iface_addr) @@ -5288,6 +4909,9 @@ int rtw_p2p_enable(_adapter *padapter, enum P2P_ROLE role) { int ret = _SUCCESS; struct wifidirect_info *pwdinfo = &(padapter->wdinfo); +#ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; +#endif if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT || role == P2P_ROLE_GO) { #if defined(CONFIG_CONCURRENT_MODE) && (!defined(RTW_P2P_GROUP_INTERFACE) || !RTW_P2P_GROUP_INTERFACE) @@ -5351,7 +4975,7 @@ int rtw_p2p_enable(_adapter *padapter, enum P2P_ROLE role) reset_ch_sitesurvey_timer_process(padapter); reset_ch_sitesurvey_timer_process2(padapter); #ifdef CONFIG_CONCURRENT_MODE - _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer); + _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer); #endif rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE); rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_NONE); diff --git a/core/rtw_pwrctrl.c b/core/rtw_pwrctrl.c index 6ef90c4..03dfaf9 100644 --- a/core/rtw_pwrctrl.c +++ b/core/rtw_pwrctrl.c @@ -94,9 +94,9 @@ void _ips_enter(_adapter *padapter) if (pwrpriv->ips_mode == IPS_LEVEL_2) pwrpriv->bkeepfwalive = _TRUE; -#ifdef CONFIG_RTW_CFGVEDNOR_LLSTATS +#ifdef CONFIG_RTW_CFGVENDOR_LLSTATS pwrpriv->pwr_saving_start_time = rtw_get_current_time(); -#endif /* CONFIG_RTW_CFGVEDNOR_LLSTATS */ +#endif /* CONFIG_RTW_CFGVENDOR_LLSTATS */ rtw_ips_pwr_down(padapter); pwrpriv->rf_pwrstate = rf_off; @@ -138,9 +138,9 @@ int _ips_leave(_adapter *padapter) if (result == _SUCCESS) pwrpriv->rf_pwrstate = rf_on; -#ifdef CONFIG_RTW_CFGVEDNOR_LLSTATS +#ifdef CONFIG_RTW_CFGVENDOR_LLSTATS pwrpriv->pwr_saving_time += rtw_get_passing_time_ms(pwrpriv->pwr_saving_start_time); -#endif /* CONFIG_RTW_CFGVEDNOR_LLSTATS */ +#endif /* CONFIG_RTW_CFGVENDOR_LLSTATS */ RTW_PRINT("nolinked power save leave\n"); @@ -192,11 +192,6 @@ int ips_leave(_adapter *padapter) } #endif /* CONFIG_IPS */ -#ifdef CONFIG_AUTOSUSPEND - extern void autosuspend_enter(_adapter *padapter); - extern int autoresume_enter(_adapter *padapter); -#endif - #ifdef SUPPORT_HW_RFOFF_DETECTED int rtw_hw_suspend(_adapter *padapter); int rtw_hw_resume(_adapter *padapter); @@ -232,12 +227,12 @@ bool rtw_pwr_unassociated_idle(_adapter *adapter) #ifdef CONFIG_P2P pwdinfo = &(iface->wdinfo); #endif - if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_SITE_MONITOR) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_UNDER_SURVEY) || check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS) || MLME_IS_AP(iface) || MLME_IS_MESH(iface) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE) - #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) + #if defined(CONFIG_IOCTL_CFG80211) || rtw_cfg80211_get_is_roch(iface) == _TRUE || (rtw_cfg80211_is_ro_ch_once(adapter) && rtw_cfg80211_get_last_ro_ch_passing_ms(adapter) < 3000) @@ -290,8 +285,10 @@ void rtw_ps_processor(_adapter *padapter) ps_deny = rtw_ps_deny_get(padapter); _exit_pwrlock(&adapter_to_pwrctl(padapter)->lock); if (ps_deny != 0) { - RTW_INFO(FUNC_ADPT_FMT ": ps_deny=0x%08X, skip power save!\n", - FUNC_ADPT_ARG(padapter), ps_deny); + if (!MLME_IS_MONITOR(padapter)) { + RTW_INFO(FUNC_ADPT_FMT ": ps_deny=0x%08X, skip power save!\n", + FUNC_ADPT_ARG(padapter), ps_deny); + } goto exit; } @@ -309,43 +306,22 @@ void rtw_ps_processor(_adapter *padapter) /* RTW_INFO("==> fw report state(0x%x)\n",rtw_read8(padapter,0x1ca)); */ if (pwrpriv->bHWPwrPindetect) { -#ifdef CONFIG_AUTOSUSPEND - if (padapter->registrypriv.usbss_enable) { - if (pwrpriv->rf_pwrstate == rf_on) { - if (padapter->net_closed == _TRUE) - pwrpriv->ps_flag = _TRUE; + + rfpwrstate = RfOnOffDetect(padapter); + RTW_INFO("@@@@- #2 %s==> rfstate:%s\n", __FUNCTION__, (rfpwrstate == rf_on) ? "rf_on" : "rf_off"); - rfpwrstate = RfOnOffDetect(padapter); - RTW_INFO("@@@@- #1 %s==> rfstate:%s\n", __FUNCTION__, (rfpwrstate == rf_on) ? "rf_on" : "rf_off"); - if (rfpwrstate != pwrpriv->rf_pwrstate) { - if (rfpwrstate == rf_off) { - pwrpriv->change_rfpwrstate = rf_off; - - pwrpriv->bkeepfwalive = _TRUE; - pwrpriv->brfoffbyhw = _TRUE; - - autosuspend_enter(padapter); - } - } - } - } else -#endif /* CONFIG_AUTOSUSPEND */ - { - rfpwrstate = RfOnOffDetect(padapter); - RTW_INFO("@@@@- #2 %s==> rfstate:%s\n", __FUNCTION__, (rfpwrstate == rf_on) ? "rf_on" : "rf_off"); - - if (rfpwrstate != pwrpriv->rf_pwrstate) { - if (rfpwrstate == rf_off) { - pwrpriv->change_rfpwrstate = rf_off; - pwrpriv->brfoffbyhw = _TRUE; - rtw_hw_suspend(padapter); - } else { - pwrpriv->change_rfpwrstate = rf_on; - rtw_hw_resume(padapter); - } - RTW_INFO("current rf_pwrstate(%s)\n", (pwrpriv->rf_pwrstate == rf_off) ? "rf_off" : "rf_on"); + if (rfpwrstate != pwrpriv->rf_pwrstate) { + if (rfpwrstate == rf_off) { + pwrpriv->change_rfpwrstate = rf_off; + pwrpriv->brfoffbyhw = _TRUE; + rtw_hw_suspend(padapter); + } else { + pwrpriv->change_rfpwrstate = rf_on; + rtw_hw_resume(padapter); } + RTW_INFO("current rf_pwrstate(%s)\n", (pwrpriv->rf_pwrstate == rf_off) ? "rf_off" : "rf_on"); } + pwrpriv->pwr_state_check_cnts++; } #endif /* SUPPORT_HW_RFOFF_DETECTED */ @@ -358,41 +334,12 @@ void rtw_ps_processor(_adapter *padapter) if ((pwrpriv->rf_pwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts % 4) == 0)) { RTW_INFO("==>%s .fw_state(%x)\n", __FUNCTION__, get_fwstate(pmlmepriv)); -#if defined(CONFIG_BT_COEXIST) && defined (CONFIG_AUTOSUSPEND) -#else - pwrpriv->change_rfpwrstate = rf_off; -#endif -#ifdef CONFIG_AUTOSUSPEND - if (padapter->registrypriv.usbss_enable) { - if (pwrpriv->bHWPwrPindetect) - pwrpriv->bkeepfwalive = _TRUE; - - if (padapter->net_closed == _TRUE) - pwrpriv->ps_flag = _TRUE; - -#if defined(CONFIG_BT_COEXIST) && defined (CONFIG_AUTOSUSPEND) - if (_TRUE == pwrpriv->bInternalAutoSuspend) - RTW_INFO("<==%s .pwrpriv->bInternalAutoSuspend)(%x)\n", __FUNCTION__, pwrpriv->bInternalAutoSuspend); - else { - pwrpriv->change_rfpwrstate = rf_off; - RTW_INFO("<==%s .pwrpriv->bInternalAutoSuspend)(%x) call autosuspend_enter\n", __FUNCTION__, pwrpriv->bInternalAutoSuspend); - autosuspend_enter(padapter); - } -#else - autosuspend_enter(padapter); -#endif /* if defined (CONFIG_BT_COEXIST)&& defined (CONFIG_AUTOSUSPEND) */ - } else if (pwrpriv->bHWPwrPindetect) { - } else -#endif /* CONFIG_AUTOSUSPEND */ - { -#if defined(CONFIG_BT_COEXIST) && defined (CONFIG_AUTOSUSPEND) - pwrpriv->change_rfpwrstate = rf_off; -#endif /* defined (CONFIG_BT_COEXIST)&& defined (CONFIG_AUTOSUSPEND) */ + pwrpriv->change_rfpwrstate = rf_off; #ifdef CONFIG_IPS ips_enter(padapter); #endif - } + } exit: #ifndef CONFIG_IPS_CHECK_IN_WD @@ -712,13 +659,13 @@ u8 PS_RDY_CHECK(_adapter *padapter) if (rtw_time_after(pwrpriv->lps_deny_time, rtw_get_current_time())) return _FALSE; - if (check_fwstate(pmlmepriv, WIFI_SITE_MONITOR) + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) || check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS) || MLME_IS_AP(padapter) || MLME_IS_MESH(padapter) || MLME_IS_MONITOR(padapter) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE) - #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) + #if defined(CONFIG_IOCTL_CFG80211) || rtw_cfg80211_get_is_roch(padapter) == _TRUE #endif || rtw_is_scan_deny(padapter) @@ -861,22 +808,126 @@ void rtw_set_fw_in_ips_mode(PADAPTER padapter, u8 enable) } #endif /* CONFIG_PNO_SUPPORT */ - -void rtw_leave_lps_and_chk(_adapter *padapter, u8 ps_mode) +void rtw_exec_lps(_adapter *padapter, u8 ps_mode) { struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + if (ps_mode == PS_MODE_ACTIVE) { +#ifdef CONFIG_LPS_ACK + _enter_critical_mutex(&pwrpriv->lps_ack_mutex, NULL); + rtw_sctx_init(&pwrpriv->lps_ack_sctx, 100); +#endif /* CONFIG_LPS_ACK */ + + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); + rtw_hal_set_hwreg(padapter, HW_VAR_LPS_STATE_CHK, (u8 *)(&ps_mode)); + +#ifdef CONFIG_LPS_ACK + _exit_critical_mutex(&pwrpriv->lps_ack_mutex, NULL); +#endif /* CONFIG_LPS_ACK */ + } else { + if (MLME_IS_ASOC(padapter)) + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); + else + RTW_INFO(FUNC_ADPT_FMT": It can't execute LPS without Wi-Fi connection!\n", + FUNC_ADPT_ARG(padapter)); + } +} + +void rtw_lps_rfon_ctrl(_adapter *padapter, u8 rfon_ctrl) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + u8 rpwm = 0; + + if (pwrpriv->bFwCurrentInPSMode && pwrpriv->pwr_mode != PS_MODE_ACTIVE) { + if (rfon_ctrl == rf_on) { +#ifdef CONFIG_LPS_LCLK + if (pwrpriv->lps_level >= LPS_LCLK) { + s32 ready = _FAIL; + systime stime; + s32 utime; + u32 timeout; /* unit: ms */ + +#ifdef LPS_RPWM_WAIT_MS + timeout = LPS_RPWM_WAIT_MS; +#else + timeout = 30; +#endif /* !LPS_RPWM_WAIT_MS */ + + stime = rtw_get_current_time(); + do { + ready = rtw_register_task_alive(padapter, LPS_ALIVE); + if (ready == _SUCCESS) + break; + + utime = rtw_get_passing_time_ms(stime); + if (utime > timeout) + break; + + rtw_msleep_os(1); + } while (1); + + if (ready == _FAIL) + RTW_INFO(FUNC_ADPT_FMT": It is not ready to leave 32K !!!\n", + FUNC_ADPT_ARG(padapter)); + } +#endif /* CONFIG_LPS_LCLK */ + #ifdef CONFIG_LPS_ACK _enter_critical_mutex(&pwrpriv->lps_ack_mutex, NULL); rtw_sctx_init(&pwrpriv->lps_ack_sctx, 100); #endif /* CONFIG_LPS_ACK */ - rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); - rtw_hal_set_hwreg(padapter, HW_VAR_LPS_STATE_CHK, (u8 *)(&ps_mode)); + + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE_RFON_CTRL, (u8 *)(&rfon_ctrl)); + rtw_hal_set_hwreg(padapter, HW_VAR_LPS_RFON_CHK, (u8 *)(&rfon_ctrl)); #ifdef CONFIG_LPS_ACK _exit_critical_mutex(&pwrpriv->lps_ack_mutex, NULL); #endif /* CONFIG_LPS_ACK */ - + } else { + if (MLME_IS_ASOC(padapter)) { +#ifdef CONFIG_LPS_PG + if (pwrpriv->lps_level == LPS_PG) { + if (rtw_hal_set_lps_pg_info_cmd(padapter) == _FAIL) + RTW_INFO(FUNC_ADPT_FMT": Send PG H2C command Fail! \n", + FUNC_ADPT_ARG(padapter)); + } +#endif /* CONFIG_LPS_PG */ + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE_RFON_CTRL, (u8 *)(&rfon_ctrl)); + } else { + RTW_INFO(FUNC_ADPT_FMT": It can't execute RFON without Wi-Fi connection!\n", + FUNC_ADPT_ARG(padapter)); + } + +#ifdef CONFIG_LPS_LCLK + if (pwrpriv->lps_level >= LPS_LCLK) { + rtw_unregister_task_alive(padapter, LPS_ALIVE); + + if (pwrpriv->alives == 0) { + u8 polling_cnt = 0; + u8 reg_val8 = 0; + u8 result = _FAIL; + + do { + rtw_msleep_os(1); + reg_val8 = rtw_read8(padapter, REG_CR); + if (reg_val8 == 0xEA) { + result= _SUCCESS; + break; + } + polling_cnt++; + } while (polling_cnt < 100); + + if (result == _FAIL ) + RTW_INFO(FUNC_ADPT_FMT": It is not finished to enter 32K !!!\n", + FUNC_ADPT_ARG(padapter)); + } + } +#endif /* CONFIG_LPS_LCLK */ + } + } else { + RTW_INFO(FUNC_ADPT_FMT": RFON can't work due to ps state is not in LPS !\n", + FUNC_ADPT_ARG(padapter)); + } } void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode, const char *msg) @@ -1024,7 +1075,7 @@ void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode rtw_hal_set_hwreg(padapter, HW_VAR_H2C_INACTIVE_IPS, (u8 *)(&ps_mode)); #endif /* CONFIG_WOWLAN */ - rtw_leave_lps_and_chk(padapter, ps_mode); + rtw_exec_lps(padapter, ps_mode); #ifdef CONFIG_LPS_PG if (pwrpriv->lps_level == LPS_PG) { @@ -1105,9 +1156,8 @@ void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode pwrpriv->wmm_smart_ps = pregistrypriv->wmm_smart_ps; #endif /* CONFIG_WMMPS_STA */ + rtw_exec_lps(padapter, ps_mode); - if (check_fwstate(pmlmepriv, _FW_LINKED)) - rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); #ifdef CONFIG_WOWLAN if (pwrpriv->wowlan_mode == _TRUE) rtw_hal_set_hwreg(padapter, HW_VAR_H2C_INACTIVE_IPS, (u8 *)(&ps_mode)); @@ -1220,9 +1270,9 @@ void LPS_Enter(PADAPTER padapter, const char *msg) sprintf(buf, "WIFI-%s", msg); pwrpriv->bpower_saving = _TRUE; -#ifdef CONFIG_RTW_CFGVEDNOR_LLSTATS +#ifdef CONFIG_RTW_CFGVENDOR_LLSTATS pwrpriv->pwr_saving_start_time = rtw_get_current_time(); -#endif /* CONFIG_RTW_CFGVEDNOR_LLSTATS */ +#endif /* CONFIG_RTW_CFGVENDOR_LLSTATS */ rtw_set_ps_mode(padapter, pwrpriv->power_mgnt, padapter->registrypriv.smart_ps, 0, buf); @@ -1276,9 +1326,9 @@ void LPS_Leave(PADAPTER padapter, const char *msg) sprintf(buf, "WIFI-%s", msg); rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, buf); -#ifdef CONFIG_RTW_CFGVEDNOR_LLSTATS +#ifdef CONFIG_RTW_CFGVENDOR_LLSTATS pwrpriv->pwr_saving_time += rtw_get_passing_time_ms(pwrpriv->pwr_saving_start_time); -#endif /* CONFIG_RTW_CFGVEDNOR_LLSTATS */ +#endif /* CONFIG_RTW_CFGVENDOR_LLSTATS */ } } @@ -1375,23 +1425,14 @@ void LeaveAllPowerSaveModeDirect(PADAPTER Adapter) #endif } else { if (pwrpriv->rf_pwrstate == rf_off) { -#ifdef CONFIG_AUTOSUSPEND - if (Adapter->registrypriv.usbss_enable) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) - usb_disable_autosuspend(adapter_to_dvobj(Adapter)->pusbdev); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)) - adapter_to_dvobj(Adapter)->pusbdev->autosuspend_disabled = Adapter->bDisableAutosuspend;/* autosuspend disabled by the user */ -#endif - } else -#endif - { + #if defined(CONFIG_FWLPS_IN_IPS) || defined(CONFIG_SWLPS_IN_IPS) || defined(CONFIG_RTL8188E) #ifdef CONFIG_IPS - if (_FALSE == ips_leave(pri_padapter)) - RTW_INFO("======> ips_leave fail.............\n"); + if (_FALSE == ips_leave(pri_padapter)) + RTW_INFO("======> ips_leave fail.............\n"); #endif #endif /* CONFIG_SWLPS_IN_IPS || (CONFIG_PLATFORM_SPRD && CONFIG_RTL8188E) */ - } + } } @@ -1447,23 +1488,14 @@ void LeaveAllPowerSaveMode(PADAPTER Adapter) #endif } else { if (adapter_to_pwrctl(Adapter)->rf_pwrstate == rf_off) { -#ifdef CONFIG_AUTOSUSPEND - if (Adapter->registrypriv.usbss_enable) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) - usb_disable_autosuspend(adapter_to_dvobj(Adapter)->pusbdev); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)) - adapter_to_dvobj(Adapter)->pusbdev->autosuspend_disabled = Adapter->bDisableAutosuspend;/* autosuspend disabled by the user */ -#endif - } else -#endif - { + #if defined(CONFIG_FWLPS_IN_IPS) || defined(CONFIG_SWLPS_IN_IPS) || (defined(CONFIG_PLATFORM_SPRD) && defined(CONFIG_RTL8188E)) #ifdef CONFIG_IPS - if (_FALSE == ips_leave(Adapter)) - RTW_INFO("======> ips_leave fail.............\n"); + if (_FALSE == ips_leave(Adapter)) + RTW_INFO("======> ips_leave fail.............\n"); #endif #endif /* CONFIG_SWLPS_IN_IPS || (CONFIG_PLATFORM_SPRD && CONFIG_RTL8188E) */ - } + } } @@ -1589,7 +1621,8 @@ static void dma_event_callback(struct work_struct *work) #ifdef CONFIG_LPS_RPWM_TIMER #define DBG_CPWM_CHK_FAIL -#if defined(DBG_CPWM_CHK_FAIL) && (defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)) +#if defined(DBG_CPWM_CHK_FAIL) && (defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) \ + || defined(CONFIG_RTL8723F)) #define CPU_EXCEPTION_CODE 0xFAFAFAFA static void rtw_cpwm_chk_fail_debug(_adapter *padapter) { @@ -1658,7 +1691,8 @@ static void rpwmtimeout_workitem_callback(struct work_struct *work) pwrpriv->rpwm_retry = 0; _exit_pwrlock(&pwrpriv->lock); -#if defined(DBG_CPWM_CHK_FAIL) && (defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)) +#if defined(DBG_CPWM_CHK_FAIL) && (defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) \ + || defined(CONFIG_RTL8723F)) RTW_INFO("+%s: rpwm=0x%02X cpwm=0x%02X\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm); rtw_cpwm_chk_fail_debug(padapter); #endif @@ -2155,7 +2189,7 @@ void rtw_init_pwrctrl_priv(PADAPTER padapter) struct registry_priv *registry_par = &padapter->registrypriv; #endif #ifdef CONFIG_GPIO_WAKEUP - u8 val8 = 0; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); #endif #if defined(CONFIG_CONCURRENT_MODE) @@ -2191,18 +2225,8 @@ void rtw_init_pwrctrl_priv(PADAPTER padapter) pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL; pwrctrlpriv->pwr_state_check_cnts = 0; - #ifdef CONFIG_AUTOSUSPEND - pwrctrlpriv->bInternalAutoSuspend = _FALSE; - #endif pwrctrlpriv->bInSuspend = _FALSE; pwrctrlpriv->bkeepfwalive = _FALSE; - -#ifdef CONFIG_AUTOSUSPEND -#ifdef SUPPORT_HW_RFOFF_DETECTED - pwrctrlpriv->pwr_state_check_interval = (pwrctrlpriv->bHWPwrPindetect) ? 1000 : 2000; -#endif -#endif - pwrctrlpriv->LpsIdleCount = 0; /* pwrctrlpriv->FWCtrlPSMode =padapter->registrypriv.power_mgnt; */ /* PS_MODE_MIN; */ @@ -2272,23 +2296,38 @@ void rtw_init_pwrctrl_priv(PADAPTER padapter) #endif /* CONFIG_HAS_EARLYSUSPEND || CONFIG_ANDROID_POWER */ #ifdef CONFIG_GPIO_WAKEUP + pwrctrlpriv->wowlan_gpio_index = WAKEUP_GPIO_IDX; + /* set output low state in initial */ + pwrctrlpriv->wowlan_gpio_output_state = GPIO_OUTPUT_LOW; /*default low active*/ pwrctrlpriv->is_high_active = HIGH_ACTIVE_DEV2HST; pwrctrlpriv->hst2dev_high_active = HIGH_ACTIVE_HST2DEV; + +#if (defined(CONFIG_RTL8192F) && defined(CONFIG_USB_HCI) && defined(CONFIG_BT_COEXIST)) + if (pHalData->EEPROMBluetoothCoexist == _TRUE) { + /* for 8725AU case */ + pwrctrlpriv->wowlan_gpio_index = WAKEUP_GPIO_IDX_8725AU; + pwrctrlpriv->is_high_active = HIGH_ACTIVE_DEV2HST_8725AU; + } +#endif #ifdef CONFIG_RTW_ONE_PIN_GPIO - rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE); - rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX); + rtw_hal_switch_gpio_wl_ctrl(padapter, pwrctrlpriv->wowlan_gpio_index, _TRUE); + rtw_hal_set_input_gpio(padapter, pwrctrlpriv->wowlan_gpio_index); #else #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE if (pwrctrlpriv->is_high_active == 0) - rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX); + rtw_hal_set_input_gpio(padapter, pwrctrlpriv->wowlan_gpio_index); else - rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, 0); + rtw_hal_set_output_gpio(padapter, pwrctrlpriv->wowlan_gpio_index, + GPIO_OUTPUT_LOW); #else - val8 = (pwrctrlpriv->is_high_active == 0) ? 1 : 0; - rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8); - RTW_INFO("%s: set GPIO_%d %d as default.\n", - __func__, WAKEUP_GPIO_IDX, val8); + rtw_hal_set_output_gpio(padapter, pwrctrlpriv->wowlan_gpio_index + , pwrctrlpriv->wowlan_gpio_output_state); + rtw_hal_switch_gpio_wl_ctrl(padapter, pwrctrlpriv->wowlan_gpio_index, _TRUE); + RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in initial and %s_ACTIVE.\n", + __func__, pwrctrlpriv->wowlan_gpio_index, + pwrctrlpriv->wowlan_gpio_output_state ? "HIGH" : "LOW", + pwrctrlpriv->is_high_active ? "HIGI" : "LOW"); #endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/ #endif /* CONFIG_RTW_ONE_PIN_GPIO */ #endif /* CONFIG_GPIO_WAKEUP */ @@ -2328,7 +2367,17 @@ void rtw_init_pwrctrl_priv(PADAPTER padapter) #ifdef CONFIG_WOW_PATTERN_HW_CAM _rtw_mutex_init(&pwrctrlpriv->wowlan_pattern_cam_mutex); #endif + +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + pwrctrlpriv->wowlan_keep_alive_ack_index = 0xFF; + pwrctrlpriv->wowlan_wake_pattern_index = 0xFF; +#endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ pwrctrlpriv->wowlan_aoac_rpt_loc = 0; +#ifdef CONFIG_WAR_OFFLOAD +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) + rtw_wow_war_mdns_parms_reset(padapter, _TRUE); +#endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */ +#endif /* CONFIG_WAR_OFFLOAD */ #endif /* CONFIG_WOWLAN */ #ifdef CONFIG_LPS_POFF @@ -2626,11 +2675,7 @@ int _rtw_pwr_wakeup(_adapter *padapter, u32 ips_deffer_ms, const char *caller) } #endif - if (pwrpriv->bInSuspend - #ifdef CONFIG_AUTOSUSPEND - && pwrpriv->bInternalAutoSuspend == _FALSE - #endif - ) { + if (pwrpriv->bInSuspend) { RTW_INFO("%s wait bInSuspend...\n", __func__); while (pwrpriv->bInSuspend && ((rtw_get_passing_time_ms(start) <= 3000 && !rtw_is_do_late_resume(pwrpriv)) @@ -2644,71 +2689,27 @@ int _rtw_pwr_wakeup(_adapter *padapter, u32 ips_deffer_ms, const char *caller) } /* System suspend is not allowed to wakeup */ - if ((_TRUE == pwrpriv->bInSuspend) - #ifdef CONFIG_AUTOSUSPEND - && (pwrpriv->bInternalAutoSuspend == _FALSE) - #endif - ) { + if (_TRUE == pwrpriv->bInSuspend) { ret = _FAIL; goto exit; } -#ifdef CONFIG_AUTOSUSPEND - /* usb autosuspend block??? */ - if ((pwrpriv->bInternalAutoSuspend == _TRUE) && (padapter->net_closed == _TRUE)) { - ret = _FAIL; - goto exit; - } -#endif /* I think this should be check in IPS, LPS, autosuspend functions... */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { -#if defined(CONFIG_BT_COEXIST) && defined (CONFIG_AUTOSUSPEND) - if (_TRUE == pwrpriv->bInternalAutoSuspend) { - if (0 == pwrpriv->autopm_cnt) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) - if (usb_autopm_get_interface(adapter_to_dvobj(padapter)->pusbintf) < 0) - RTW_INFO("can't get autopm:\n"); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)) - usb_autopm_disable(adapter_to_dvobj(padapter)->pusbintf); -#else - usb_autoresume_device(adapter_to_dvobj(padapter)->pusbdev, 1); -#endif - pwrpriv->autopm_cnt++; - } -#endif /* #if defined (CONFIG_BT_COEXIST) && defined (CONFIG_AUTOSUSPEND) */ - ret = _SUCCESS; - goto exit; -#if defined(CONFIG_BT_COEXIST) && defined (CONFIG_AUTOSUSPEND) - } -#endif /* #if defined (CONFIG_BT_COEXIST) && defined (CONFIG_AUTOSUSPEND) */ + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { + ret = _SUCCESS; + goto exit; } if (rf_off == pwrpriv->rf_pwrstate) { -#ifdef CONFIG_USB_HCI -#ifdef CONFIG_AUTOSUSPEND - if (pwrpriv->brfoffbyhw == _TRUE) { - RTW_INFO("hw still in rf_off state ...........\n"); + +#ifdef CONFIG_IPS + RTW_INFO("%s call ips_leave....\n", __FUNCTION__); + if (_FAIL == ips_leave(padapter)) { + RTW_INFO("======> ips_leave fail.............\n"); ret = _FAIL; goto exit; - } else if (padapter->registrypriv.usbss_enable) { - RTW_INFO("%s call autoresume_enter....\n", __FUNCTION__); - if (_FAIL == autoresume_enter(padapter)) { - RTW_INFO("======> autoresume fail.............\n"); - ret = _FAIL; - goto exit; - } - } else -#endif -#endif - { -#ifdef CONFIG_IPS - RTW_INFO("%s call ips_leave....\n", __FUNCTION__); - if (_FAIL == ips_leave(padapter)) { - RTW_INFO("======> ips_leave fail.............\n"); - ret = _FAIL; - goto exit; - } -#endif } +#endif + } /* TODO: the following checking need to be merged... */ diff --git a/core/rtw_recv.c b/core/rtw_recv.c old mode 100755 new mode 100644 index e417f13..90f27ac --- a/core/rtw_recv.c +++ b/core/rtw_recv.c @@ -23,12 +23,14 @@ static void rtw_signal_stat_timer_hdl(void *ctx); enum { SIGNAL_STAT_CALC_PROFILE_0 = 0, SIGNAL_STAT_CALC_PROFILE_1, + SIGNAL_STAT_CALC_PROFILE_2, SIGNAL_STAT_CALC_PROFILE_MAX }; -u8 signal_stat_calc_profile[SIGNAL_STAT_CALC_PROFILE_MAX][2] = { +u8 signal_stat_calc_profile[SIGNAL_STAT_CALC_PROFILE_MAX][3] = { {4, 1}, /* Profile 0 => pre_stat : curr_stat = 4 : 1 */ - {3, 7} /* Profile 1 => pre_stat : curr_stat = 3 : 7 */ + {3, 7}, /* Profile 1 => pre_stat : curr_stat = 3 : 7 */ + {0, 10} /* Profile 2 => pre_stat : curr_stat = 0 : 10 */ }; #ifndef RTW_SIGNAL_STATE_CALC_PROFILE @@ -45,9 +47,6 @@ static u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3}; static u8 SNAP_ETH_TYPE_TDLS[2] = {0x89, 0x0d}; #endif -#ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL -int recv_frame_monitor(_adapter *padapter, union recv_frame *rframe); -#endif void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv) { @@ -284,6 +283,7 @@ int rtw_free_recvframe(union recv_frame *precvframe, _queue *pfree_recv_queue) rtw_list_delete(&(precvframe->u.hdr.list)); precvframe->u.hdr.len = 0; + precvframe->u.hdr.attrib.phy_info.physts_rpt_valid = _FALSE; rtw_list_insert_tail(&(precvframe->u.hdr.list), get_list_head(pfree_recv_queue)); @@ -397,16 +397,32 @@ u32 rtw_free_uc_swdec_pending_queue(_adapter *adapter) } +#ifndef CONFIG_RECVBUF_QUEUE_LOCK_BH +#ifdef CONFIG_SDIO_HCI +#define CONFIG_RECVBUF_QUEUE_LOCK_BH 1 +#else +#define CONFIG_RECVBUF_QUEUE_LOCK_BH 0 +#endif +#endif /* CONFIG_RECVBUF_QUEUE_LOCK_BH */ + sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue) { _irqL irqL; +#if CONFIG_RECVBUF_QUEUE_LOCK_BH _enter_critical_bh(&queue->lock, &irqL); +#else + _enter_critical_ex(&queue->lock, &irqL); +#endif rtw_list_delete(&precvbuf->list); rtw_list_insert_head(&precvbuf->list, get_list_head(queue)); +#if CONFIG_RECVBUF_QUEUE_LOCK_BH _exit_critical_bh(&queue->lock, &irqL); +#else + _exit_critical_ex(&queue->lock, &irqL); +#endif return _SUCCESS; } @@ -414,20 +430,23 @@ sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue) sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue) { _irqL irqL; -#ifdef CONFIG_SDIO_HCI + +#if CONFIG_RECVBUF_QUEUE_LOCK_BH _enter_critical_bh(&queue->lock, &irqL); #else _enter_critical_ex(&queue->lock, &irqL); -#endif/*#ifdef CONFIG_SDIO_HCI*/ +#endif rtw_list_delete(&precvbuf->list); rtw_list_insert_tail(&precvbuf->list, get_list_head(queue)); -#ifdef CONFIG_SDIO_HCI + +#if CONFIG_RECVBUF_QUEUE_LOCK_BH _exit_critical_bh(&queue->lock, &irqL); #else _exit_critical_ex(&queue->lock, &irqL); -#endif/*#ifdef CONFIG_SDIO_HCI*/ +#endif + return _SUCCESS; } @@ -438,11 +457,11 @@ struct recv_buf *rtw_dequeue_recvbuf(_queue *queue) struct recv_buf *precvbuf; _list *plist, *phead; -#ifdef CONFIG_SDIO_HCI +#if CONFIG_RECVBUF_QUEUE_LOCK_BH _enter_critical_bh(&queue->lock, &irqL); #else _enter_critical_ex(&queue->lock, &irqL); -#endif/*#ifdef CONFIG_SDIO_HCI*/ +#endif if (_rtw_queue_empty(queue) == _TRUE) precvbuf = NULL; @@ -457,11 +476,11 @@ struct recv_buf *rtw_dequeue_recvbuf(_queue *queue) } -#ifdef CONFIG_SDIO_HCI +#if CONFIG_RECVBUF_QUEUE_LOCK_BH _exit_critical_bh(&queue->lock, &irqL); #else _exit_critical_ex(&queue->lock, &irqL); -#endif/*#ifdef CONFIG_SDIO_HCI*/ +#endif return precvbuf; @@ -597,6 +616,9 @@ union recv_frame *decryptor(_adapter *padapter, union recv_frame *precv_frame) break; case _TKIP_: case _AES_: + case _GCMP_: + case _GCMP_256_: + case _CCMP_256_: default: prxattrib->key_index = psecuritypriv->dot118021XGrpKeyid; break; @@ -637,9 +659,15 @@ union recv_frame *decryptor(_adapter *padapter, union recv_frame *precv_frame) res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame); break; case _AES_: + case _CCMP_256_: DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_aes); res = rtw_aes_decrypt(padapter, (u8 *)precv_frame); break; + case _GCMP_: + case _GCMP_256_: + DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_gcmp); + res = rtw_gcmp_decrypt(padapter, (u8 *)precv_frame); + break; #ifdef CONFIG_WAPI_SUPPORT case _SMS4_: DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_wapi); @@ -1104,6 +1132,102 @@ exit: return ret; } + +sint rtw_tdls_rx_data_validate_hdr( + _adapter *adapter, + union recv_frame *precv_frame, + struct sta_info **psta +) +{ + u8 *ptr = precv_frame->u.hdr.rx_data; + sint ret = _SUCCESS; + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &adapter->stapriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + u8 *mybssid = get_bssid(pmlmepriv); + u8 *myhwaddr = adapter_mac_addr(adapter); + u8 *sta_addr = pattrib->ta; + sint bmcast = IS_MCAST(pattrib->dst); + + struct tdls_info *ptdlsinfo = &adapter->tdlsinfo; +#ifdef CONFIG_TDLS_CH_SW + struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info; +#endif + struct sta_info *ptdls_sta = NULL; + u8 *psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE; + /* frame body located after [+2]: ether-type, [+1]: payload type */ + u8 *pframe_body = psnap_type + 2 + 1; + + *psta = ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->ta); + if (ptdls_sta == NULL) { + ret = _FAIL; + goto exit; + } else if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) { + /* filter packets that SA is myself or multicast or broadcast */ + if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)) { + ret = _FAIL; + goto exit; + } + /* da should be for me */ + if ((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) { + ret = _FAIL; + goto exit; + } + /* check BSSID */ + if (_rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))) { + ret = _FAIL; + goto exit; + } + +#ifdef CONFIG_TDLS_CH_SW + if (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE) { + if (adapter->mlmeextpriv.cur_channel != rtw_get_oper_ch(adapter)) { + pchsw_info->ch_sw_state |= TDLS_PEER_AT_OFF_STATE; + if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE)) + _cancel_timer_ex(&ptdls_sta->ch_sw_timer); + /* On_TDLS_Peer_Traffic_Rsp(adapter, precv_frame); */ + } + } +#endif + + /* process UAPSD tdls sta */ + process_pwrbit_data(adapter, precv_frame, ptdls_sta); + + /* if NULL-frame, check pwrbit */ + if ((get_frame_sub_type(ptr) & WIFI_DATA_NULL) == WIFI_DATA_NULL) { + /* NULL-frame with pwrbit=1, buffer_STA should buffer frames for sleep_STA */ + if (GetPwrMgt(ptr)) { + /* it would be triggered when we are off channel and receiving NULL DATA */ + /* we can confirm that peer STA is at off channel */ + RTW_INFO("TDLS: recv peer null frame with pwr bit 1\n"); + /* ptdls_sta->tdls_sta_state|=TDLS_PEER_SLEEP_STATE; */ + } + + /* TODO: Updated BSSID's seq. */ + /* RTW_INFO("drop Null Data\n"); */ + ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE); + ret = _FAIL; + goto exit; + } + + /* receive some of all TDLS management frames, process it at ON_TDLS */ + if (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_TDLS, 2)) { + ret = OnTDLS(adapter, precv_frame); + goto exit; + } + + if ((get_frame_sub_type(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) + process_wmmps_data(adapter, precv_frame, ptdls_sta); + + ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE); + + } + +exit: + return ret; +} #endif /* CONFIG_TDLS */ void count_rx_stats(_adapter *padapter, union recv_frame *prframe, struct sta_info *sta) @@ -1167,6 +1291,157 @@ void count_rx_stats(_adapter *padapter, union recv_frame *prframe, struct sta_in } +int rtw_sta_rx_data_validate_hdr(_adapter *adapter, union recv_frame *rframe, struct sta_info **sta) +{ + struct sta_priv *stapriv = &adapter->stapriv; + u8 *mybssid = get_bssid(&adapter->mlmepriv); + u8 *myhwaddr = adapter_mac_addr(adapter); + struct rx_pkt_attrib *rattrib = &rframe->u.hdr.attrib; + u8 *whdr = get_recvframe_data(rframe); + u8 is_ra_bmc = IS_MCAST(GetAddr1Ptr(whdr)) ? 1 : 0; + sint ret = _FAIL; + + if (rattrib->to_fr_ds == 0) { + _rtw_memcpy(rattrib->ra, GetAddr1Ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->ta, get_addr2_ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->dst, GetAddr1Ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->src, get_addr2_ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->bssid, GetAddr3Ptr(whdr), ETH_ALEN); + + #ifdef CONFIG_TDLS + if (adapter->tdlsinfo.link_established == _TRUE) + ret = rtw_tdls_rx_data_validate_hdr(adapter, rframe, sta); + else + #endif + { + /* For Station mode, sa and bssid should always be BSSID, and DA is my mac-address */ + if (!_rtw_memcmp(rattrib->bssid, rattrib->src, ETH_ALEN)) + goto exit; + + *sta = rtw_get_stainfo(stapriv, get_addr2_ptr(whdr)); + if (*sta) + ret = _SUCCESS; + } + goto exit; + } + + if (!(MLME_STATE(adapter) & (WIFI_ASOC_STATE | WIFI_UNDER_LINKING))) { + if (!is_ra_bmc) { + /* for AP multicast issue , modify by yiwei */ + static systime send_issue_deauth_time = 0; + + /* RTW_INFO("After send deauth , %u ms has elapsed.\n", rtw_get_passing_time_ms(send_issue_deauth_time)); */ + if (rtw_get_passing_time_ms(send_issue_deauth_time) > 10000 || send_issue_deauth_time == 0) { + send_issue_deauth_time = rtw_get_current_time(); + RTW_INFO(FUNC_ADPT_FMT" issue_deauth to "MAC_FMT" with reason(7), mlme_state:0x%x\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(get_addr2_ptr(whdr)), MLME_STATE(adapter)); + issue_deauth(adapter, get_addr2_ptr(whdr), WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); + } + } + #ifdef DBG_RX_DROP_FRAME + RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" fw_state:0x%x\n" + , FUNC_ADPT_ARG(adapter), MLME_STATE(adapter)); + #endif + goto exit; + } + + _rtw_memcpy(rattrib->ra, GetAddr1Ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->ta, get_addr2_ptr(whdr), ETH_ALEN); + + switch (rattrib->to_fr_ds) { + case 2: + _rtw_memcpy(rattrib->dst, GetAddr1Ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->src, GetAddr3Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */ + _rtw_memcpy(rattrib->bssid, get_addr2_ptr(whdr), ETH_ALEN); + break; + case 3: + _rtw_memcpy(rattrib->dst, GetAddr3Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */ + _rtw_memcpy(rattrib->src, GetAddr4Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */ + _rtw_memcpy(rattrib->bssid, get_addr2_ptr(whdr), ETH_ALEN); + break; + default: + ret = RTW_RX_HANDLED; /* don't count for drop */ + goto exit; + } + + /* filter packets that SA is myself */ + if (!rattrib->amsdu && _rtw_memcmp(myhwaddr, rattrib->src, ETH_ALEN)) { + #ifdef DBG_RX_DROP_FRAME + RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" SA="MAC_FMT", myhwaddr="MAC_FMT"\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(rattrib->src), MAC_ARG(myhwaddr)); + #endif + goto exit; + } + + *sta = rtw_get_stainfo(stapriv, rattrib->ta); + if (*sta == NULL) { + #ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL + if (!is_ra_bmc && !IS_RADAR_DETECTED(adapter_to_rfctl(adapter))) { + RTW_INFO(FUNC_ADPT_FMT" issue_deauth to "MAC_FMT" with reason(7), unknown TA\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(rattrib->ta)); + issue_deauth(adapter, rattrib->ta, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); + } + #endif + #ifdef DBG_RX_DROP_FRAME + RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" can't get psta under STATION_MODE ; drop pkt\n" + , FUNC_ADPT_ARG(adapter)); + #endif + goto exit; + } + +#ifdef CONFIG_RTW_WDS_AUTO_EN + if (rattrib->to_fr_ds == 3 && !(sta->flags & WLAN_STA_WDS)) + sta->flags |= WLAN_STA_WDS; +#endif + + /*if ((get_frame_sub_type(whdr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { + } + */ + + if (get_frame_sub_type(whdr) & BIT(6)) { + /* No data, will not indicate to upper layer, temporily count it here */ + count_rx_stats(adapter, rframe, *sta); + ret = RTW_RX_HANDLED; + goto exit; + } + +#ifdef CONFIG_RTW_WDS + if (adapter_use_wds(adapter) + && !rattrib->amsdu && IS_MCAST(rattrib->dst) + && rtw_rx_wds_gptr_check(adapter, rattrib->src) + ) { + /* will not indicate to upper layer, temporily count it here */ + count_rx_stats(adapter, rframe, *sta); + ret = RTW_RX_HANDLED; + goto exit; + } +#endif + + ret = _SUCCESS; + +exit: + return ret; +} + +int rtw_sta_rx_amsdu_act_check(union recv_frame *rframe + , const u8 *da, const u8 *sa) +{ + int act = RTW_RX_MSDU_ACT_INDICATE; + +#ifdef CONFIG_RTW_WDS + _adapter *adapter = rframe->u.hdr.adapter; + + if (adapter_use_wds(adapter) + && IS_MCAST(da) + && rtw_rx_wds_gptr_check(adapter, sa) + ) { + act = 0; + } +#endif + + return act; +} + sint sta2sta_data_frame( _adapter *adapter, union recv_frame *precv_frame, @@ -1183,18 +1458,6 @@ sint sta2sta_data_frame( u8 *sta_addr = pattrib->ta; sint bmcast = IS_MCAST(pattrib->dst); -#ifdef CONFIG_TDLS - struct tdls_info *ptdlsinfo = &adapter->tdlsinfo; -#ifdef CONFIG_TDLS_CH_SW - struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info; -#endif - struct sta_info *ptdls_sta = NULL; - u8 *psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE; - /* frame body located after [+2]: ether-type, [+1]: payload type */ - u8 *pframe_body = psnap_type + 2 + 1; -#endif - - /* RTW_INFO("[%s] %d, seqnum:%d\n", __FUNCTION__, __LINE__, pattrib->seq_num); */ if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) || @@ -1218,102 +1481,6 @@ sint sta2sta_data_frame( goto exit; } - } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) { -#ifdef CONFIG_TDLS - - /* direct link data transfer */ - if (ptdlsinfo->link_established == _TRUE) { - *psta = ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->ta); - if (ptdls_sta == NULL) { - ret = _FAIL; - goto exit; - } else if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) { - /* filter packets that SA is myself or multicast or broadcast */ - if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)) { - ret = _FAIL; - goto exit; - } - /* da should be for me */ - if ((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) { - ret = _FAIL; - goto exit; - } - /* check BSSID */ - if (_rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || - _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || - (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))) { - ret = _FAIL; - goto exit; - } - -#ifdef CONFIG_TDLS_CH_SW - if (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE) { - if (adapter->mlmeextpriv.cur_channel != rtw_get_oper_ch(adapter)) { - pchsw_info->ch_sw_state |= TDLS_PEER_AT_OFF_STATE; - if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE)) - _cancel_timer_ex(&ptdls_sta->ch_sw_timer); - /* On_TDLS_Peer_Traffic_Rsp(adapter, precv_frame); */ - } - } -#endif - - /* process UAPSD tdls sta */ - process_pwrbit_data(adapter, precv_frame, ptdls_sta); - - /* if NULL-frame, check pwrbit */ - if ((get_frame_sub_type(ptr) & WIFI_DATA_NULL) == WIFI_DATA_NULL) { - /* NULL-frame with pwrbit=1, buffer_STA should buffer frames for sleep_STA */ - if (GetPwrMgt(ptr)) { - /* it would be triggered when we are off channel and receiving NULL DATA */ - /* we can confirm that peer STA is at off channel */ - RTW_INFO("TDLS: recv peer null frame with pwr bit 1\n"); - /* ptdls_sta->tdls_sta_state|=TDLS_PEER_SLEEP_STATE; */ - } - - /* TODO: Updated BSSID's seq. */ - /* RTW_INFO("drop Null Data\n"); */ - ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE); - ret = _FAIL; - goto exit; - } - - /* receive some of all TDLS management frames, process it at ON_TDLS */ - if (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_TDLS, 2)) { - ret = OnTDLS(adapter, precv_frame); - goto exit; - } - - if ((get_frame_sub_type(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) - process_wmmps_data(adapter, precv_frame, ptdls_sta); - - ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE); - - } - } else -#endif /* CONFIG_TDLS */ - { - /* For Station mode, sa and bssid should always be BSSID, and DA is my mac-address */ - if (!_rtw_memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) { - ret = _FAIL; - goto exit; - } - } - - } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) { - if (bmcast) { - /* For AP mode, if DA == MCAST, then BSSID should be also MCAST */ - if (!IS_MCAST(pattrib->bssid)) { - ret = _FAIL; - goto exit; - } - } else { /* not mc-frame */ - /* For AP mode, if DA is non-MCAST, then it must be BSSID, and bssid == BSSID */ - if (!_rtw_memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) { - ret = _FAIL; - goto exit; - } - } - } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) { _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); _rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN); @@ -1325,11 +1492,7 @@ sint sta2sta_data_frame( } else ret = _FAIL; -#ifdef CONFIG_TDLS - if (ptdls_sta == NULL) -#endif - *psta = rtw_get_stainfo(pstapriv, sta_addr); - + *psta = rtw_get_stainfo(pstapriv, sta_addr); if (*psta == NULL) { #ifdef CONFIG_MP_INCLUDED if (adapter->registrypriv.mp_mode == 1) { @@ -1343,7 +1506,6 @@ sint sta2sta_data_frame( exit: return ret; - } sint ap2sta_data_frame( @@ -1356,80 +1518,11 @@ sint ap2sta_data_frame( sint ret = _SUCCESS; struct sta_priv *pstapriv = &adapter->stapriv; struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - u8 *mybssid = get_bssid(pmlmepriv); u8 *myhwaddr = adapter_mac_addr(adapter); sint bmcast = IS_MCAST(pattrib->dst); - - if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) - && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE - || check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) - ) { - - /* filter packets that SA is myself or multicast or broadcast */ - if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)) { - #ifdef DBG_RX_DROP_FRAME - RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" SA="MAC_FMT", myhwaddr="MAC_FMT"\n" - , FUNC_ADPT_ARG(adapter), MAC_ARG(pattrib->src), MAC_ARG(myhwaddr)); - #endif - ret = _FAIL; - goto exit; - } - - /* da should be for me */ - if ((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) { - #ifdef DBG_RX_DROP_FRAME - RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" DA="MAC_FMT"\n" - , FUNC_ADPT_ARG(adapter), MAC_ARG(pattrib->dst)); - #endif - ret = _FAIL; - goto exit; - } - - - /* check BSSID */ - if (_rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || - _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || - (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))) { - #ifdef DBG_RX_DROP_FRAME - RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" BSSID="MAC_FMT", mybssid="MAC_FMT"\n" - , FUNC_ADPT_ARG(adapter), MAC_ARG(pattrib->bssid), MAC_ARG(mybssid)); - #endif -#ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL - if (!bmcast - && !IS_RADAR_DETECTED(adapter_to_rfctl(adapter)) - ) { - RTW_INFO(ADPT_FMT" -issue_deauth to the nonassociated ap=" MAC_FMT " for the reason(7)\n", ADPT_ARG(adapter), MAC_ARG(pattrib->bssid)); - issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); - } -#endif - ret = _FAIL; - goto exit; - } - - *psta = rtw_get_stainfo(pstapriv, pattrib->ta); - if (*psta == NULL) { - #ifdef DBG_RX_DROP_FRAME - RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" can't get psta under STATION_MODE ; drop pkt\n" - , FUNC_ADPT_ARG(adapter)); - #endif - ret = _FAIL; - goto exit; - } - - /*if ((get_frame_sub_type(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { - } - */ - - if (get_frame_sub_type(ptr) & BIT(6)) { - /* No data, will not indicate to upper layer, temporily count it here */ - count_rx_stats(adapter, precv_frame, *psta); - ret = RTW_RX_HANDLED; - goto exit; - } - - } else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && - (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) { + if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && + (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) { _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); _rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN); _rtw_memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN); @@ -1447,11 +1540,6 @@ sint ap2sta_data_frame( goto exit; } - - } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) { - /* Special case */ - ret = RTW_RX_HANDLED; - goto exit; } else { if (_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && (!bmcast)) { *psta = rtw_get_stainfo(pstapriv, pattrib->ta); @@ -1480,8 +1568,6 @@ sint ap2sta_data_frame( } exit: - - return ret; } @@ -1498,40 +1584,8 @@ sint sta2ap_data_frame( unsigned char *mybssid = get_bssid(pmlmepriv); sint ret = _SUCCESS; - - if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) { - /* For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR */ - if (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN)) { - ret = _FAIL; - goto exit; - } - - *psta = rtw_get_stainfo(pstapriv, pattrib->ta); - if (*psta == NULL) { - if (!IS_RADAR_DETECTED(adapter_to_rfctl(adapter))) { -#ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL - RTW_INFO("issue_deauth to sta=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src)); - issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); -#endif - } - - ret = RTW_RX_HANDLED; - goto exit; - } - - process_pwrbit_data(adapter, precv_frame, *psta); - - if ((get_frame_sub_type(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) - process_wmmps_data(adapter, precv_frame, *psta); - - if (get_frame_sub_type(ptr) & BIT(6)) { - /* No data, will not indicate to upper layer, temporily count it here */ - count_rx_stats(adapter, precv_frame, *psta); - ret = RTW_RX_HANDLED; - goto exit; - } - } else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && - (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) { + if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && + (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) { /* RTW_INFO("%s ,in WIFI_MP_STATE\n",__func__); */ _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); _rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN); @@ -1630,11 +1684,13 @@ sint validate_recv_ctrl_frame(_adapter *padapter, union recv_frame *precv_frame) if (wmmps_ac) return _FAIL; + #ifdef CONFIG_AP_MODE if (psta->state & WIFI_STA_ALIVE_CHK_STATE) { RTW_INFO("%s alive check-rx ps-poll\n", __func__); psta->expire_to = pstapriv->expire_to; psta->state ^= WIFI_STA_ALIVE_CHK_STATE; } + #endif if ((psta->state & WIFI_SLEEP_STATE) && (rtw_tim_map_is_set(padapter, pstapriv->sta_dz_bitmap, psta->cmn.aid))) { _irqL irqL; @@ -1745,6 +1801,7 @@ static sint validate_mgmt_protect(_adapter *adapter, union recv_frame *precv_fra const u8 *igtk; u16 igtk_id; u64* ipn; + enum security_type bip_cipher; #endif u8 *mgmt_DATA; @@ -1857,6 +1914,7 @@ bip_verify: #ifdef CONFIG_RTW_MESH if (MLME_IS_MESH(adapter)) { if (psta->igtk_bmp) { + bip_cipher = psta->dot11wCipher; igtk = psta->igtk.skey; igtk_id = psta->igtk_id; ipn = &psta->igtk_pn.val; @@ -1867,16 +1925,18 @@ bip_verify: } else #endif { + bip_cipher = sec->dot11wCipher; igtk = sec->dot11wBIPKey[sec->dot11wBIPKeyid].skey; igtk_id = sec->dot11wBIPKeyid; ipn = &sec->dot11wBIPrxpn.val; } /* verify BIP MME IE */ - ret = rtw_BIP_verify(adapter - , get_recvframe_data(precv_frame) - , get_recvframe_len(precv_frame) - , igtk, igtk_id, ipn); + ret = rtw_bip_verify(bip_cipher, pattrib->pkt_len, + get_recvframe_data(precv_frame), + get_recvframe_len(precv_frame), + igtk, igtk_id, ipn); + if (ret == _FAIL) { /* RTW_INFO("802.11w BIP verify fail\n"); */ goto fail; @@ -1891,9 +1951,19 @@ bip_verify: goto exit; } + if (!psta || !(psta->flags & WLAN_STA_MFP)) { + /* not peer or peer is not MFP capable, drop it */ + goto fail; + } + /* cases to decrypt mgmt frame */ pattrib->bdecrypted = 0; - pattrib->encrypt = _AES_; +#ifdef CONFIG_RTW_MESH + if (is_bmc) + pattrib->encrypt = psta->group_privacy; + else +#endif + pattrib->encrypt = psta->dot118021XPrivacy; pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); /* set iv and icv length */ @@ -2026,8 +2096,18 @@ sint validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame) if (MLME_IS_MESH(adapter)) { ret = rtw_mesh_rx_data_validate_hdr(adapter, precv_frame, &psta); goto pre_validate_status_chk; - } + } else #endif +#ifdef CONFIG_AP_MODE + if (MLME_IS_AP(adapter)) { + ret = rtw_ap_rx_data_validate_hdr(adapter, precv_frame, &psta); + goto pre_validate_status_chk; + } else +#endif + if (MLME_IS_STA(adapter)) { + ret = rtw_sta_rx_data_validate_hdr(adapter, precv_frame, &psta); + goto pre_validate_status_chk; + } switch (pattrib->to_fr_ds) { case 0: @@ -2042,19 +2122,19 @@ sint validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame) case 1: _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); _rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN); - _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); - _rtw_memcpy(pattrib->src, GetAddr3Ptr(ptr), ETH_ALEN); - _rtw_memcpy(pattrib->bssid, get_addr2_ptr(ptr), ETH_ALEN); - ret = ap2sta_data_frame(adapter, precv_frame, &psta); + _rtw_memcpy(pattrib->dst, GetAddr3Ptr(ptr), ETH_ALEN); + _rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN); + _rtw_memcpy(pattrib->bssid, GetAddr1Ptr(ptr), ETH_ALEN); + ret = sta2ap_data_frame(adapter, precv_frame, &psta); break; case 2: _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); _rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN); - _rtw_memcpy(pattrib->dst, GetAddr3Ptr(ptr), ETH_ALEN); - _rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN); - _rtw_memcpy(pattrib->bssid, GetAddr1Ptr(ptr), ETH_ALEN); - ret = sta2ap_data_frame(adapter, precv_frame, &psta); + _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); + _rtw_memcpy(pattrib->src, GetAddr3Ptr(ptr), ETH_ALEN); + _rtw_memcpy(pattrib->bssid, get_addr2_ptr(ptr), ETH_ALEN); + ret = ap2sta_data_frame(adapter, precv_frame, &psta); break; case 3: @@ -2064,9 +2144,8 @@ sint validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame) break; } -#ifdef CONFIG_RTW_MESH pre_validate_status_chk: -#endif + if (ret == _FAIL) { #ifdef DBG_RX_DROP_FRAME RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" case:%d, res:%d, ra="MAC_FMT", ta="MAC_FMT"\n" @@ -2086,6 +2165,16 @@ pre_validate_status_chk: goto exit; } + if ((psta->flags & WLAN_STA_AMSDU_DISABLE) && pattrib->amsdu) { + #ifdef DBG_RX_DROP_FRAME + RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" amsdu not allowed"MAC_FMT"\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr)); + #endif + ret = _FAIL; + goto exit; + + } + precv_frame->u.hdr.psta = psta; precv_frame->u.hdr.preorder_ctrl = NULL; pattrib->ack_policy = 0; @@ -2151,6 +2240,72 @@ pre_validate_status_chk: pattrib->iv_len = pattrib->icv_len = 0; } + /* drop unprotected frame in protected network. */ + if (psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_ ) { + if (IS_MCAST(pattrib->ra)) { + if (!pattrib->privacy) { + #ifdef DBG_RX_DROP_FRAME + RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT"recv plaintext bmc packet for sta="MAC_FMT"\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr)); + #endif + ret = _FAIL; + goto exit; + } + } else { + /* unicast */ + u16 ether_type; + u8* ether_ptr = NULL; + u16 eapol_type = 0x888e; + ether_ptr = ptr + pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib) + LLC_HEADER_SIZE; + _rtw_memcpy(ðer_type, ether_ptr, 2); + ether_type = ntohs((unsigned short)ether_type); + + if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { + /* CVE-2020-26140, CVE-2020-26143, CVE-2020-26147, let eapol packet go through*/ + if (!pattrib->privacy && ether_type != eapol_type ) { + #ifdef DBG_RX_DROP_FRAME + RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT"recv plaintext unicast packet for sta="MAC_FMT"\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr)); + #endif + ret = _FAIL; + goto exit; + } + /* CVE-2020-26144, pevernt plaintext A-MSDU */ + /* This can prevent plantext A-MSDU cloacked as an EAPOL frame */ + if (!pattrib->privacy && pattrib->amsdu) { + #ifdef DBG_RX_DROP_FRAME + RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT"recv plaintext A-MSDU for sta="MAC_FMT"\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr)); + #endif + ret = _FAIL; + goto exit; + } + /* CVE-2020-26139, Drop any forwarding eapol packet until 4-way has done. */ + if ((ether_type == eapol_type) + && (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) + && (psta->dot118021XPrivacy == _NO_PRIVACY_) + && (!_rtw_memcmp( adapter_mac_addr(adapter), pattrib->dst, ETH_ALEN))) { + #ifdef DBG_RX_DROP_FRAME + RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" recv eapol packet forwarding(dst:"MAC_FMT") before 4-way finish.\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(pattrib->dst)); + #endif + ret = _FAIL; + goto exit; + } + } else { + /* CVE-2020-26140, CVE-2020-26143, CVE-2020-26147 */ + if (!pattrib->privacy) { + #ifdef DBG_RX_DROP_FRAME + RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT"recv plaintext packet for sta="MAC_FMT"\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr)); + #endif + ret = _FAIL; + goto exit; + } + } + } + } + #ifdef CONFIG_RTW_MESH if (!pattrib->amsdu && pattrib->mesh_ctrl_present @@ -2358,89 +2513,62 @@ exit: return retval; } +/* Reture expected handling for LLC */ +enum rtw_rx_llc_hdl rtw_recv_llc_parse(u8 *msdu, u16 msdu_len) +{ + u16 eth_type; + + if (msdu_len < 8) + return RTW_RX_LLC_KEEP; + + eth_type = RTW_GET_BE16(msdu + SNAP_SIZE); + + if ((_rtw_memcmp(msdu, rtw_rfc1042_header, SNAP_SIZE) + && eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) + || _rtw_memcmp(msdu, rtw_bridge_tunnel_header, SNAP_SIZE)) { + /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ + return RTW_RX_LLC_REMOVE; + } else { + /* Leave Ethernet header part of hdr and full payload */ + return RTW_RX_LLC_KEEP; + } + + /* TODO: VLAN tagged */ +} /* remove the wlanhdr and add the eth_hdr */ -sint wlanhdr_to_ethhdr(union recv_frame *precvframe) +sint wlanhdr_to_ethhdr(union recv_frame *precvframe, enum rtw_rx_llc_hdl llc_hdl) { - sint rmv_len; - u16 eth_type, len; - u8 bsnaphdr; - u8 *psnap_type; - struct ieee80211_snap_hdr *psnap; - - sint ret = _SUCCESS; - _adapter *adapter = precvframe->u.hdr.adapter; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - u8 *ptr = get_recvframe_data(precvframe) ; /* point to frame_ctrl field */ struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; - + sint rmv_len; + u16 eth_type, len; + sint ret = _SUCCESS; if (pattrib->encrypt) recvframe_pull_tail(precvframe, pattrib->icv_len); - psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib)); - psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib) + SNAP_SIZE; - /* convert hdr + possible LLC headers into Ethernet header */ - /* eth_type = (psnap_type[0] << 8) | psnap_type[1]; */ - if ((_rtw_memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) && - (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) == _FALSE) && - (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2) == _FALSE)) || - /* eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || */ - _rtw_memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) { - /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ - bsnaphdr = _TRUE; - } else { - /* Leave Ethernet header part of hdr and full payload */ - bsnaphdr = _FALSE; - } - - rmv_len = pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib) + (bsnaphdr ? SNAP_SIZE : 0); + rmv_len = pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib) + (llc_hdl ? SNAP_SIZE : 0); len = precvframe->u.hdr.len - rmv_len; - - _rtw_memcpy(ð_type, ptr + rmv_len, 2); - eth_type = ntohs((unsigned short)eth_type); /* pattrib->ether_type */ - pattrib->eth_type = eth_type; - - - if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)) { - ptr += rmv_len ; - *ptr = 0x87; - *(ptr + 1) = 0x12; - - eth_type = 0x8712; - /* append rx status for mp test packets */ - ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2) - 24); - if (!ptr) { - ret = _FAIL; - goto exiting; - } - _rtw_memcpy(ptr, get_rxmem(precvframe), 24); - ptr += 24; - } else { - ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0))); - if (!ptr) { - ret = _FAIL; - goto exiting; - } + ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (llc_hdl ? 2 : 0))); + if (!ptr) { + ret = _FAIL; + goto exiting; } - if (ptr) { - _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN); - _rtw_memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN); + _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN); + _rtw_memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN); - if (!bsnaphdr) { - len = htons(len); - _rtw_memcpy(ptr + 12, &len, 2); - } - - rtw_rframe_set_os_pkt(precvframe); + if (!llc_hdl) { + len = htons(len); + _rtw_memcpy(ptr + 12, &len, 2); } + rtw_rframe_set_os_pkt(precvframe); + exiting: return ret; - } #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) @@ -2514,7 +2642,10 @@ union recv_frame *recvframe_defrag(_adapter *adapter, _queue *defrag_q) struct recv_frame_hdr *pfhdr, *pnfhdr; union recv_frame *prframe, *pnextrframe; _queue *pfree_recv_queue; - + u8 *pdata = NULL; + u64 tmp_iv_hdr = 0; + u64 pkt_pn = 0, cur_pn = 0; + struct rx_pkt_attrib *pattrib = NULL; curfragnum = 0; pfree_recv_queue = &adapter->recvpriv.free_recv_queue; @@ -2522,6 +2653,15 @@ union recv_frame *recvframe_defrag(_adapter *adapter, _queue *defrag_q) phead = get_list_head(defrag_q); plist = get_next(phead); prframe = LIST_CONTAINOR(plist, union recv_frame, u); + /* CVE-2020-26146 */ + pattrib = &prframe->u.hdr.attrib; + if (pattrib->encrypt == _AES_ || pattrib->encrypt == _CCMP_256_ + || pattrib->encrypt == _GCMP_ || pattrib->encrypt == _GCMP_256_ ) { + pdata = prframe->u.hdr.rx_data; + tmp_iv_hdr = le64_to_cpu(*(u64*)(pdata + pattrib->hdrlen)); + /* get the first frame's PN. */ + cur_pn = CCMPH_2_PN(tmp_iv_hdr); + } pfhdr = &prframe->u.hdr; rtw_list_delete(&(prframe->u.list)); @@ -2551,7 +2691,33 @@ union recv_frame *recvframe_defrag(_adapter *adapter, _queue *defrag_q) while (rtw_end_of_queue_search(phead, plist) == _FALSE) { pnextrframe = LIST_CONTAINOR(plist, union recv_frame , u); pnfhdr = &pnextrframe->u.hdr; + /* CVE-2020-26146, check whether the PN is consecutive. */ + pattrib = &pnextrframe->u.hdr.attrib; + if (pattrib->encrypt == _AES_ || pattrib->encrypt == _CCMP_256_ + || pattrib->encrypt == _GCMP_ || pattrib->encrypt == _GCMP_256_ ) { + pdata = pnextrframe->u.hdr.rx_data; + tmp_iv_hdr = le64_to_cpu(*(u64*)(pdata + pattrib->hdrlen)); + pkt_pn = CCMPH_2_PN(tmp_iv_hdr); + if (pkt_pn != cur_pn + 1) { + RTW_INFO("%s non-consective PN! old:%llu, new:%llu\n", + __func__, cur_pn, pkt_pn); + /* PN must be consecutive */ + /* release the defrag_q & prframe */ + rtw_free_recvframe(prframe, pfree_recv_queue); + rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); + return NULL; + } else { + cur_pn = pkt_pn; + } + } + /* CVE-2020-24587, The keytrack of the fragment is supposed to be the same with other's */ + if (pfhdr->keytrack != pnfhdr->keytrack) { + RTW_INFO("Inconsistent key track, drop fragmented frame!\n"); + rtw_free_recvframe(prframe, pfree_recv_queue); + rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); + return NULL; + } /* check the fragment sequence (2nd ~n fragment frame) */ @@ -2632,6 +2798,16 @@ union recv_frame *recvframe_chk_defrag(PADAPTER padapter, union recv_frame *prec if ((ismfrag == 0) && (fragnum == 0)) { prtnframe = precv_frame;/* isn't a fragment frame */ + } else { + /* CVE-2020-26145, group addressed frame cannot use fragmentation!! */ + if (IS_MCAST(pfhdr->attrib.ra)) { + RTW_INFO("DROP group addressed fragment!\n"); + rtw_free_recvframe(precv_frame, pfree_recv_queue); + return NULL; + } + /* CVE-2020-24587 */ + if ((psta) && (pdefrag_q)) + precv_frame->u.hdr.keytrack = ATOMIC_READ(&psta->keytrack); } if (ismfrag == 1) { @@ -2705,13 +2881,14 @@ static int rtw_recv_indicatepkt_check(union recv_frame *rframe, u8 *ehdr_pos, u3 _adapter *adapter = rframe->u.hdr.adapter; struct recv_priv *recvpriv = &adapter->recvpriv; struct ethhdr *ehdr = (struct ethhdr *)ehdr_pos; + struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib; #ifdef DBG_IP_R_MONITOR int i; - struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib; struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; struct mlme_priv *pmlmepriv = &adapter->mlmepriv; struct wlan_network *cur_network = &(pmlmepriv->cur_network); #endif/*DBG_IP_R_MONITOR*/ + enum eap_type eapol_type; int ret = _FAIL; #ifdef CONFIG_WAPI_SUPPORT @@ -2727,8 +2904,13 @@ static int rtw_recv_indicatepkt_check(union recv_frame *rframe, u8 *ehdr_pos, u3 if (rframe->u.hdr.psta) rtw_st_ctl_rx(rframe->u.hdr.psta, ehdr_pos); - if (ntohs(ehdr->h_proto) == 0x888e) - parsing_eapol_packet(adapter, ehdr_pos + ETH_HLEN, rframe->u.hdr.psta, 0); + if (ntohs(ehdr->h_proto) == 0x888e) { + eapol_type = parsing_eapol_packet(adapter, ehdr_pos + ETH_HLEN, rframe->u.hdr.psta, 0); + if ((eapol_type == EAPOL_1_4 || eapol_type == EAPOL_3_4) && pattrib->encrypt == 0) { + rframe->u.hdr.psta->resp_nonenc_eapol_key_starttime = rtw_get_current_time(); + RTW_INFO("Receive unencrypted eapol key\n"); + } + } #ifdef DBG_ARP_DUMP else if (ntohs(ehdr->h_proto) == ETH_P_ARP) dump_arp_pkt(RTW_DBGDUMP, ehdr->h_dest, ehdr->h_source, ehdr_pos + ETH_HLEN, 0); @@ -2783,7 +2965,7 @@ exit: return ret; } -#ifdef CONFIG_RTW_MESH +#if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) static void recv_free_fwd_resource(_adapter *adapter, struct xmit_frame *fwd_frame, _list *b2u_list) { struct xmit_priv *xmitpriv = &adapter->xmitpriv; @@ -2791,7 +2973,7 @@ static void recv_free_fwd_resource(_adapter *adapter, struct xmit_frame *fwd_fra if (fwd_frame) rtw_free_xmitframe(xmitpriv, fwd_frame); -#if CONFIG_RTW_MESH_DATA_BMC_TO_UC +#if CONFIG_RTW_DATA_BMC_TO_UC if (!rtw_is_list_empty(b2u_list)) { struct xmit_frame *b2uframe; _list *list; @@ -2824,7 +3006,7 @@ static void recv_fwd_pkt_hdl(_adapter *adapter, _pkt *pkt } } -#if CONFIG_RTW_MESH_DATA_BMC_TO_UC +#if CONFIG_RTW_DATA_BMC_TO_UC if (!rtw_is_list_empty(b2u_list)) { _list *list = get_next(b2u_list); struct xmit_frame *b2uframe; @@ -2861,7 +3043,48 @@ static void recv_fwd_pkt_hdl(_adapter *adapter, _pkt *pkt exit: return; } -#endif /* CONFIG_RTW_MESH */ +#endif /* defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) */ + +/* + * From WFA suggestion: * + * If first subframe meets one of the following condition, * + * the whole received AMSDU should drop. * + * 1. subframe's DA is not the same as RA in From DS case. * + * 2. subframe's SA is not the same as TA in To DS case. * + * 3. subframe's DA is AA:AA:03:00:00:00 * + */ +static u8 validate_amsdu_content(_adapter *padapter, union recv_frame *prframe, + const u8 *da, const u8 *sa) +{ + struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; + u8 ret = _SUCCESS; + + /* Use the recommendation method form Wi-Fi alliance to check subframe */ + /* in protected network */ + if (padapter->registrypriv.amsdu_mode == RTW_AMSDU_MODE_NON_SPP && + padapter->securitypriv.dot11PrivacyAlgrthm != _NO_PRIVACY_) { + + /* 1.check From DS */ + if (pattrib->to_fr_ds == 2) { + if (_rtw_memcmp(da, pattrib->ra, ETH_ALEN) == _FALSE) + ret = _FAIL; + } + + /* 2.check To DS */ + if (pattrib->to_fr_ds == 1) { + if (_rtw_memcmp(sa, pattrib->ta, ETH_ALEN) == _FALSE) + ret = _FAIL; + } + + /* 3.Check whether DA is AA:AA:03:00:00:00 */ + if (_rtw_memcmp(da, rtw_rfc1042_header, ETH_ALEN) == _TRUE) + ret = _FAIL; + + } + + return ret; + +} int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) { @@ -2875,10 +3098,11 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) _queue *pfree_recv_queue = &(precvpriv->free_recv_queue); const u8 *da, *sa; int act; -#ifdef CONFIG_RTW_MESH /* TODO: move AP mode forward & b2u logic here */ +#if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) struct xmit_frame *fwd_frame; _list b2u_list; #endif + enum rtw_rx_llc_hdl llc_hdl; u8 mctrl_len = 0; int ret = _SUCCESS; @@ -2888,6 +3112,8 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) if (rattrib->iv_len > 0) recvframe_pull(prframe, rattrib->iv_len); + if (rattrib->encrypt) + recvframe_pull_tail(prframe, rattrib->icv_len); a_len = prframe->u.hdr.len; pdata = prframe->u.hdr.rx_data; @@ -2901,10 +3127,11 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) } act = RTW_RX_MSDU_ACT_INDICATE; + #if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) + fwd_frame = NULL; + #endif #ifdef CONFIG_RTW_MESH - fwd_frame = NULL; - if (MLME_IS_MESH(padapter)) { u8 *mda = pdata, *msa = pdata + ETH_ALEN; struct rtw_ieee80211s_hdr *mctrl = (struct rtw_ieee80211s_hdr *)(pdata + ETH_HLEN); @@ -2912,34 +3139,56 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) v_ret = rtw_mesh_rx_data_validate_mctrl(padapter, prframe , mctrl, mda, msa, &mctrl_len, &da, &sa); + + if (validate_amsdu_content(padapter, prframe, da, sa) == _FAIL) { + RTW_INFO("%s check subframe content fail!\n", __func__); + break; + } + if (v_ret != _SUCCESS) goto move_to_next; + llc_hdl = rtw_recv_llc_parse(pdata + ETH_HLEN + mctrl_len, nSubframe_Length - mctrl_len); act = rtw_mesh_rx_msdu_act_check(prframe - , mda, msa, da, sa, mctrl, &fwd_frame, &b2u_list); + , mda, msa, da, sa, mctrl + , pdata + ETH_HLEN + mctrl_len, llc_hdl + , &fwd_frame, &b2u_list); } else #endif { da = pdata; sa = pdata + ETH_ALEN; + + if (validate_amsdu_content(padapter, prframe, da, sa) == _FAIL) { + RTW_INFO("%s check subframe content fail!\n", __func__); + break; + } + + llc_hdl = rtw_recv_llc_parse(pdata + ETH_HLEN, nSubframe_Length); + #ifdef CONFIG_AP_MODE + if (MLME_IS_AP(padapter)) { + act = rtw_ap_rx_msdu_act_check(prframe, da, sa + , pdata + ETH_HLEN, llc_hdl, &fwd_frame, &b2u_list); + } else + #endif + if (MLME_IS_STA(padapter)) + act = rtw_sta_rx_amsdu_act_check(prframe, da, sa); } - #ifdef CONFIG_RTW_MESH if (!act) goto move_to_next; - #endif rtw_led_rx_control(padapter, da); sub_pkt = rtw_os_alloc_msdu_pkt(prframe, da, sa - , pdata + ETH_HLEN + mctrl_len, nSubframe_Length - mctrl_len); + , pdata + ETH_HLEN + mctrl_len, nSubframe_Length - mctrl_len, llc_hdl); if (sub_pkt == NULL) { if (act & RTW_RX_MSDU_ACT_INDICATE) { #ifdef DBG_RX_DROP_FRAME RTW_INFO("DBG_RX_DROP_FRAME %s rtw_os_alloc_msdu_pkt fail\n", __func__); #endif } - #ifdef CONFIG_RTW_MESH + #if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) if (act & RTW_RX_MSDU_ACT_FORWARD) { #ifdef DBG_TX_DROP_FRAME RTW_INFO("DBG_TX_DROP_FRAME %s rtw_os_alloc_msdu_pkt fail\n", __func__); @@ -2950,7 +3199,7 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) break; } - #ifdef CONFIG_RTW_MESH + #if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) if (act & RTW_RX_MSDU_ACT_FORWARD) { recv_fwd_pkt_hdl(padapter, sub_pkt, act, fwd_frame, &b2u_list); if (!(act & RTW_RX_MSDU_ACT_INDICATE)) @@ -2963,9 +3212,7 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) else rtw_os_pkt_free(sub_pkt); -#ifdef CONFIG_RTW_MESH move_to_next: -#endif /* move the data point to data content */ pdata += ETH_HLEN; a_len -= ETH_HLEN; @@ -3022,22 +3269,35 @@ static int recv_process_mpdu(_adapter *padapter, union recv_frame *prframe) goto exit; } } else { + u8 *msdu = get_recvframe_data(prframe) + + pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib); + u16 msdu_len = prframe->u.hdr.len + - pattrib->hdrlen - pattrib->iv_len - RATTRIB_GET_MCTRL_LEN(pattrib) + - (pattrib->encrypt ? pattrib->icv_len : 0); + enum rtw_rx_llc_hdl llc_hdl = rtw_recv_llc_parse(msdu, msdu_len); int act = RTW_RX_MSDU_ACT_INDICATE; - #ifdef CONFIG_RTW_MESH /* TODO: move AP mode forward & b2u logic here */ + #if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) struct xmit_frame *fwd_frame = NULL; _list b2u_list; - if (MLME_IS_MESH(padapter) && pattrib->mesh_ctrl_present) { - act = rtw_mesh_rx_msdu_act_check(prframe - , pattrib->mda, pattrib->msa - , pattrib->dst, pattrib->src - , (struct rtw_ieee80211s_hdr *)(get_recvframe_data(prframe) + pattrib->hdrlen + pattrib->iv_len) - , &fwd_frame, &b2u_list); - } + #ifdef CONFIG_RTW_MESH + if (MLME_IS_MESH(padapter)) { + if (pattrib->mesh_ctrl_present) + act = rtw_mesh_rx_msdu_act_check(prframe + , pattrib->mda, pattrib->msa + , pattrib->dst, pattrib->src + , (struct rtw_ieee80211s_hdr *)(msdu - RATTRIB_GET_MCTRL_LEN(pattrib)) + , msdu, llc_hdl + , &fwd_frame, &b2u_list); + } else + #endif + if (MLME_IS_AP(padapter)) + act = rtw_ap_rx_msdu_act_check(prframe, pattrib->dst, pattrib->src + , msdu, llc_hdl, &fwd_frame, &b2u_list); #endif - #ifdef CONFIG_RTW_MESH + #if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) if (!act) { rtw_free_recvframe(prframe, pfree_recv_queue); ret = _FAIL; @@ -3047,7 +3307,7 @@ static int recv_process_mpdu(_adapter *padapter, union recv_frame *prframe) rtw_led_rx_control(padapter, pattrib->dst); - ret = wlanhdr_to_ethhdr(prframe); + ret = wlanhdr_to_ethhdr(prframe, llc_hdl); if (ret != _SUCCESS) { if (act & RTW_RX_MSDU_ACT_INDICATE) { #ifdef DBG_RX_DROP_FRAME @@ -3055,7 +3315,7 @@ static int recv_process_mpdu(_adapter *padapter, union recv_frame *prframe) , FUNC_ADPT_ARG(padapter)); #endif } - #ifdef CONFIG_RTW_MESH + #if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) if (act & RTW_RX_MSDU_ACT_FORWARD) { #ifdef DBG_TX_DROP_FRAME RTW_INFO("DBG_TX_DROP_FRAME %s wlanhdr_to_ethhdr fail\n", __func__); @@ -3067,7 +3327,7 @@ static int recv_process_mpdu(_adapter *padapter, union recv_frame *prframe) goto exit; } - #ifdef CONFIG_RTW_MESH + #if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) if (act & RTW_RX_MSDU_ACT_FORWARD) { recv_fwd_pkt_hdl(padapter, prframe->u.hdr.pkt, act, fwd_frame, &b2u_list); if (!(act & RTW_RX_MSDU_ACT_INDICATE)) { @@ -3551,7 +3811,7 @@ int validate_mp_recv_frame(_adapter *adapter, union recv_frame *precv_frame) type = GetFrameType(ptr); subtype = get_frame_sub_type(ptr); /* bit(7)~bit(2) */ - RTW_INFO("hdr len = %d iv_len=%d \n", pattrib->hdrlen , pattrib->iv_len); + RTW_DBG("hdr len = %d iv_len=%d \n", pattrib->hdrlen , pattrib->iv_len); prx_data = ptr + pattrib->hdrlen + pattrib->iv_len; for (i = 0; i < precv_frame->u.hdr.len; i++) { @@ -3617,55 +3877,31 @@ int validate_mp_recv_frame(_adapter *adapter, union recv_frame *precv_frame) static sint MPwlanhdr_to_ethhdr(union recv_frame *precvframe) { sint rmv_len; - u16 eth_type, len; - u8 bsnaphdr; - u8 *psnap_type; + u16 len; u8 mcastheadermac[] = {0x01, 0x00, 0x5e}; - - struct ieee80211_snap_hdr *psnap; - sint ret = _SUCCESS; _adapter *adapter = precvframe->u.hdr.adapter; u8 *ptr = get_recvframe_data(precvframe) ; /* point to frame_ctrl field */ struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; + enum rtw_rx_llc_hdl llc_hdl; if (pattrib->encrypt) recvframe_pull_tail(precvframe, pattrib->icv_len); - psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + pattrib->iv_len); - psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE; - /* convert hdr + possible LLC headers into Ethernet header */ - /* eth_type = (psnap_type[0] << 8) | psnap_type[1]; */ - if ((_rtw_memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) && - (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) == _FALSE) && - (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2) == _FALSE)) || - /* eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || */ - _rtw_memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) { - /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ - bsnaphdr = _TRUE; - } else { - /* Leave Ethernet header part of hdr and full payload */ - bsnaphdr = _FALSE; - } + llc_hdl = rtw_recv_llc_parse(ptr + pattrib->hdrlen + pattrib->iv_len + , precvframe->u.hdr.len - pattrib->hdrlen - pattrib->iv_len); - rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr ? SNAP_SIZE : 0); + rmv_len = pattrib->hdrlen + pattrib->iv_len + (llc_hdl ? SNAP_SIZE : 0); len = precvframe->u.hdr.len - rmv_len; - - _rtw_memcpy(ð_type, ptr + rmv_len, 2); - eth_type = ntohs((unsigned short)eth_type); /* pattrib->ether_type */ - pattrib->eth_type = eth_type; - - { - ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0))); - } + ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (llc_hdl ? 2 : 0))); _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN); _rtw_memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN); - if (!bsnaphdr) { + if (!llc_hdl) { len = htons(len); _rtw_memcpy(ptr + 12, &len, 2); } @@ -3704,7 +3940,7 @@ int mp_recv_frame(_adapter *padapter, union recv_frame *rframe) struct sta_info *psta = NULL; DBG_COUNTER(padapter->rx_logs.core_rx_pre); - if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) { /* &&(padapter->mppriv.check_mp_pkt == 0)) */ + if ((check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) { /* &&(padapter->mppriv.check_mp_pkt == 0)) */ if (pattrib->crc_err == 1) padapter->mppriv.rx_crcerrpktcount++; else { @@ -3744,18 +3980,16 @@ int mp_recv_frame(_adapter *padapter, union recv_frame *rframe) _rtw_memcpy(pattrib->ta, psa, ETH_ALEN); ret = sta2sta_data_frame(padapter, rframe, &psta); break; - case 1: - _rtw_memcpy(pattrib->ra, pda, ETH_ALEN); - _rtw_memcpy(pattrib->ta, pbssid, ETH_ALEN); - ret = ap2sta_data_frame(padapter, rframe, &psta); - break; - - case 2: _rtw_memcpy(pattrib->ra, pbssid, ETH_ALEN); _rtw_memcpy(pattrib->ta, psa, ETH_ALEN); ret = sta2ap_data_frame(padapter, rframe, &psta); break; + case 2: + _rtw_memcpy(pattrib->ra, pda, ETH_ALEN); + _rtw_memcpy(pattrib->ta, pbssid, ETH_ALEN); + ret = ap2sta_data_frame(padapter, rframe, &psta); + break; case 3: _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); _rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN); @@ -3818,333 +4052,34 @@ exit: } #endif -static sint fill_radiotap_hdr(_adapter *padapter, union recv_frame *precvframe, u8 *buf) -{ -#define CHAN2FREQ(a) ((a < 14) ? (2407+5*a) : (5000+5*a)) -#if 0 -#define RTW_RX_RADIOTAP_PRESENT (\ - (1 << IEEE80211_RADIOTAP_TSFT) | \ - (1 << IEEE80211_RADIOTAP_FLAGS) | \ - (1 << IEEE80211_RADIOTAP_RATE) | \ - (1 << IEEE80211_RADIOTAP_CHANNEL) | \ - (0 << IEEE80211_RADIOTAP_FHSS) | \ - (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ - (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \ - (0 << IEEE80211_RADIOTAP_LOCK_QUALITY) | \ - (0 << IEEE80211_RADIOTAP_TX_ATTENUATION) | \ - (0 << IEEE80211_RADIOTAP_DB_TX_ATTENUATION) | \ - (0 << IEEE80211_RADIOTAP_DBM_TX_POWER) | \ - (1 << IEEE80211_RADIOTAP_ANTENNA) | \ - (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \ - (0 << IEEE80211_RADIOTAP_DB_ANTNOISE) | \ - (0 << IEEE80211_RADIOTAP_RX_FLAGS) | \ - (0 << IEEE80211_RADIOTAP_TX_FLAGS) | \ - (0 << IEEE80211_RADIOTAP_RTS_RETRIES) | \ - (0 << IEEE80211_RADIOTAP_DATA_RETRIES) | \ - (0 << IEEE80211_RADIOTAP_MCS) | \ - (0 << IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE)| \ - (0 << IEEE80211_RADIOTAP_VENDOR_NAMESPACE) | \ - (0 << IEEE80211_RADIOTAP_EXT) | \ - 0) - - /* (0 << IEEE80211_RADIOTAP_AMPDU_STATUS) | \ */ - /* (0 << IEEE80211_RADIOTAP_VHT) | \ */ -#endif - -#ifndef IEEE80211_RADIOTAP_RX_FLAGS -#define IEEE80211_RADIOTAP_RX_FLAGS 14 -#endif - -#ifndef IEEE80211_RADIOTAP_MCS -#define IEEE80211_RADIOTAP_MCS 19 -#endif -#ifndef IEEE80211_RADIOTAP_VHT -#define IEEE80211_RADIOTAP_VHT 21 -#endif - -#ifndef IEEE80211_RADIOTAP_F_BADFCS -#define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* bad FCS */ -#endif - - sint ret = _SUCCESS; - struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; - - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); - - u16 tmp_16bit = 0; - - u8 data_rate[] = { - 2, 4, 11, 22, /* CCK */ - 12, 18, 24, 36, 48, 72, 93, 108, /* OFDM */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* HT MCS index */ - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 1 */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 2 */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 3 */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 4 */ - }; - - _pkt *pskb = NULL; - - struct ieee80211_radiotap_header *rtap_hdr = NULL; - u8 *ptr = NULL; - - u8 hdr_buf[64] = {0}; - u16 rt_len = 8; - - /* create header */ - rtap_hdr = (struct ieee80211_radiotap_header *)&hdr_buf[0]; - rtap_hdr->it_version = PKTHDR_RADIOTAP_VERSION; - - /* tsft */ - if (pattrib->tsfl) { - u64 tmp_64bit; - - rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_TSFT); - tmp_64bit = cpu_to_le64(pattrib->tsfl); - memcpy(&hdr_buf[rt_len], &tmp_64bit, 8); - rt_len += 8; - } - - /* flags */ - rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_FLAGS); - if (0) - hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_CFP; - - if (0) - hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_SHORTPRE; - - if ((pattrib->encrypt == 1) || (pattrib->encrypt == 5)) - hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_WEP; - - if (pattrib->mfrag) - hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_FRAG; - - /* always append FCS */ - hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_FCS; - - - if (0) - hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_DATAPAD; - - if (pattrib->crc_err) - hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_BADFCS; - - if (pattrib->sgi) { - /* Currently unspecified but used */ - hdr_buf[rt_len] |= 0x80; - } - rt_len += 1; - - /* rate */ - if (pattrib->data_rate <= DESC_RATE54M) { - rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_RATE); - if (pattrib->data_rate <= DESC_RATE11M) { - /* CCK */ - hdr_buf[rt_len] = data_rate[pattrib->data_rate]; - } else { - /* OFDM */ - hdr_buf[rt_len] = data_rate[pattrib->data_rate]; - } - } - rt_len += 1; /* force padding 1 byte for aligned */ - - /* channel */ - tmp_16bit = 0; - rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_CHANNEL); - tmp_16bit = CHAN2FREQ(rtw_get_oper_ch(padapter)); - /*tmp_16bit = CHAN2FREQ(pHalData->current_channel);*/ - memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); - rt_len += 2; - - /* channel flags */ - tmp_16bit = 0; - if (pHalData->current_band_type == BAND_ON_2_4G) - tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_2GHZ); - else /*BAND_ON_5G*/ - tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_5GHZ); - - if (pattrib->data_rate <= DESC_RATE54M) { - if (pattrib->data_rate <= DESC_RATE11M) { - /* CCK */ - tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_CCK); - } else { - /* OFDM */ - tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_OFDM); - } - } else - tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_DYN); - memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); - rt_len += 2; - - /* dBm Antenna Signal */ - rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); - hdr_buf[rt_len] = pattrib->phy_info.recv_signal_power; - rt_len += 1; - -#if 0 - /* dBm Antenna Noise */ - rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE); - hdr_buf[rt_len] = 0; - rt_len += 1; - - /* Signal Quality */ - rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_LOCK_QUALITY); - hdr_buf[rt_len] = pattrib->phy_info.signal_quality; - rt_len += 1; -#endif - - /* Antenna */ - rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_ANTENNA); - hdr_buf[rt_len] = 0; /* pHalData->rf_type; */ - rt_len += 1; - - /* RX flags */ - rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_RX_FLAGS); -#if 0 - tmp_16bit = cpu_to_le16(0); - memcpy(ptr, &tmp_16bit, 1); -#endif - rt_len += 2; - - /* MCS information */ - if (pattrib->data_rate >= DESC_RATEMCS0 && pattrib->data_rate <= DESC_RATEMCS31) { - rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_MCS); - /* known, flag */ - hdr_buf[rt_len] |= BIT1; /* MCS index known */ - - /* bandwidth */ - hdr_buf[rt_len] |= BIT0; - hdr_buf[rt_len + 1] |= (pattrib->bw & 0x03); - - /* guard interval */ - hdr_buf[rt_len] |= BIT2; - hdr_buf[rt_len + 1] |= (pattrib->sgi & 0x01) << 2; - - /* STBC */ - hdr_buf[rt_len] |= BIT5; - hdr_buf[rt_len + 1] |= (pattrib->stbc & 0x03) << 5; - - rt_len += 2; - - /* MCS rate index */ - hdr_buf[rt_len] = data_rate[pattrib->data_rate]; - rt_len += 1; - } - - /* VHT */ - if (pattrib->data_rate >= DESC_RATEVHTSS1MCS0 && pattrib->data_rate <= DESC_RATEVHTSS4MCS9) { - rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_VHT); - - /* known 16 bit, flag 8 bit */ - tmp_16bit = 0; - - /* Bandwidth */ - tmp_16bit |= BIT6; - - /* Group ID */ - tmp_16bit |= BIT7; - - /* Partial AID */ - tmp_16bit |= BIT8; - - /* STBC */ - tmp_16bit |= BIT0; - hdr_buf[rt_len + 2] |= (pattrib->stbc & 0x01); - - /* Guard interval */ - tmp_16bit |= BIT2; - hdr_buf[rt_len + 2] |= (pattrib->sgi & 0x01) << 2; - - /* LDPC extra OFDM symbol */ - tmp_16bit |= BIT4; - hdr_buf[rt_len + 2] |= (pattrib->ldpc & 0x01) << 4; - - memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); - rt_len += 3; - - /* bandwidth */ - if (pattrib->bw == 0) - hdr_buf[rt_len] |= 0; - else if (pattrib->bw == 1) - hdr_buf[rt_len] |= 1; - else if (pattrib->bw == 2) - hdr_buf[rt_len] |= 4; - else if (pattrib->bw == 3) - hdr_buf[rt_len] |= 11; - rt_len += 1; - - /* mcs_nss */ - if (pattrib->data_rate >= DESC_RATEVHTSS1MCS0 && pattrib->data_rate <= DESC_RATEVHTSS1MCS9) { - hdr_buf[rt_len] |= 1; - hdr_buf[rt_len] |= data_rate[pattrib->data_rate] << 4; - } else if (pattrib->data_rate >= DESC_RATEVHTSS2MCS0 && pattrib->data_rate <= DESC_RATEVHTSS2MCS9) { - hdr_buf[rt_len + 1] |= 2; - hdr_buf[rt_len + 1] |= data_rate[pattrib->data_rate] << 4; - } else if (pattrib->data_rate >= DESC_RATEVHTSS3MCS0 && pattrib->data_rate <= DESC_RATEVHTSS3MCS9) { - hdr_buf[rt_len + 2] |= 3; - hdr_buf[rt_len + 2] |= data_rate[pattrib->data_rate] << 4; - } else if (pattrib->data_rate >= DESC_RATEVHTSS4MCS0 && pattrib->data_rate <= DESC_RATEVHTSS4MCS9) { - hdr_buf[rt_len + 3] |= 4; - hdr_buf[rt_len + 3] |= data_rate[pattrib->data_rate] << 4; - } - rt_len += 4; - - /* coding */ - hdr_buf[rt_len] = 0; - rt_len += 1; - - /* group_id */ - hdr_buf[rt_len] = 0; - rt_len += 1; - - /* partial_aid */ - tmp_16bit = 0; - memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); - rt_len += 2; - } - - /* push to skb */ - pskb = (_pkt *)buf; - if (skb_headroom(pskb) < rt_len) { - RTW_INFO("%s:%d %s headroom is too small.\n", __FILE__, __LINE__, __func__); - ret = _FAIL; - return ret; - } - - ptr = skb_push(pskb, rt_len); - if (ptr) { - rtap_hdr->it_len = cpu_to_le16(rt_len); - rtap_hdr->it_present = cpu_to_le32(rtap_hdr->it_present); - memcpy(ptr, rtap_hdr, rt_len); - } else - ret = _FAIL; - - return ret; - -} #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)) int recv_frame_monitor(_adapter *padapter, union recv_frame *rframe) { int ret = _SUCCESS; _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; + +#ifdef CONFIG_WIFI_MONITOR + struct net_device *ndev = padapter->pnetdev; _pkt *pskb = NULL; + if (rframe == NULL) + goto exit; + /* read skb information from recv frame */ pskb = rframe->u.hdr.pkt; pskb->len = rframe->u.hdr.len; pskb->data = rframe->u.hdr.rx_data; skb_set_tail_pointer(pskb, rframe->u.hdr.len); -#ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL - /* fill radiotap header */ - if (fill_radiotap_hdr(padapter, rframe, (u8 *)pskb) == _FAIL) { - ret = _FAIL; - rtw_free_recvframe(rframe, pfree_recv_queue); /* free this recv_frame */ - goto exit; + if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) { + /* fill radiotap header */ + if (rtw_fill_radiotap_hdr(padapter, &rframe->u.hdr.attrib, (u8 *)pskb) == _FAIL) { + ret = _FAIL; + goto exit; + } } -#endif + /* write skb information to recv frame */ skb_reset_mac_header(pskb); rframe->u.hdr.len = pskb->len; @@ -4156,18 +4091,15 @@ int recv_frame_monitor(_adapter *padapter, union recv_frame *rframe) if (!RTW_CANNOT_RUN(padapter)) { /* indicate this recv_frame */ ret = rtw_recv_monitor(padapter, rframe); - if (ret != _SUCCESS) { - ret = _FAIL; - rtw_free_recvframe(rframe, pfree_recv_queue); /* free this recv_frame */ - goto exit; - } - } else { + } else ret = _FAIL; - rtw_free_recvframe(rframe, pfree_recv_queue); /* free this recv_frame */ - goto exit; - } exit: +#endif /* CONFIG_WIFI_MONITOR */ + + if (rframe) /* free this recv_frame */ + rtw_free_recvframe(rframe, pfree_recv_queue); + return ret; } #endif @@ -4323,19 +4255,23 @@ int recv_func(_adapter *padapter, union recv_frame *rframe) struct recv_priv *recvpriv = &padapter->recvpriv; struct security_priv *psecuritypriv = &padapter->securitypriv; struct mlme_priv *mlmepriv = &padapter->mlmepriv; + u8 *ptr = rframe->u.hdr.rx_data; #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL u8 type; - u8 *ptr = rframe->u.hdr.rx_data; #endif - if (check_fwstate(mlmepriv, WIFI_MONITOR_STATE)) { - /* monitor mode */ + + if (check_fwstate(mlmepriv, WIFI_MONITOR_STATE) +#ifdef RTW_SIMPLE_CONFIG + || (check_fwstate(mlmepriv, WIFI_AP_STATE) && padapter->rtw_simple_config == _TRUE && IS_MCAST(get_ra(ptr))) +#endif + ) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)) recv_frame_monitor(padapter, rframe); #endif ret = _SUCCESS; goto exit; - } else - {} + } + #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL type = GetFrameType(ptr); if ((type == WIFI_DATA_TYPE)&& check_fwstate(mlmepriv, WIFI_STATION_STATE)) { @@ -4472,17 +4408,18 @@ static void rtw_signal_stat_timer_hdl(void *ctx) goto set_timer; } - if (check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == _TRUE - || check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _FALSE + if (check_fwstate(&adapter->mlmepriv, WIFI_UNDER_SURVEY) == _TRUE + || check_fwstate(&adapter->mlmepriv, WIFI_ASOC_STATE) == _FALSE ) goto set_timer; #ifdef CONFIG_CONCURRENT_MODE - if (rtw_mi_buddy_check_fwstate(adapter, _FW_UNDER_SURVEY) == _TRUE) + if (rtw_mi_buddy_check_fwstate(adapter, WIFI_UNDER_SURVEY) == _TRUE) goto set_timer; #endif - - if (RTW_SIGNAL_STATE_CALC_PROFILE < SIGNAL_STAT_CALC_PROFILE_MAX) + if (adapter->registrypriv.mp_mode == 1) + ratio_profile = SIGNAL_STAT_CALC_PROFILE_2; + else if (RTW_SIGNAL_STATE_CALC_PROFILE < SIGNAL_STAT_CALC_PROFILE_MAX) ratio_profile = RTW_SIGNAL_STATE_CALC_PROFILE; ratio_pre_stat = signal_stat_calc_profile[ratio_profile][0]; @@ -4726,7 +4663,9 @@ void rx_query_phy_status( pkt_info.is_packet_beacon = pkt_info.is_packet_match_bssid && (get_frame_sub_type(wlanhdr) == WIFI_BEACON); - if (psta && IsFrameTypeData(wlanhdr)) { + if (psta && IsFrameTypeData(wlanhdr) + && !(get_frame_sub_type(wlanhdr) & BIT(6)) /* don't count NULL data */ + ) { if (is_ra_bmc) psta->curr_rx_rate_bmc = pattrib->data_rate; else @@ -4740,7 +4679,7 @@ void rx_query_phy_status( if (pattrib->bw == CHANNEL_WIDTH_MAX) pattrib->bw = p_phy_info->band_width; - { + if (p_phy_info->physts_rpt_valid == _TRUE) { precvframe->u.hdr.psta = NULL; if (padapter->registrypriv.mp_mode != 1) { if ((!MLME_IS_MESH(padapter) && pkt_info.is_packet_match_bssid) @@ -4805,6 +4744,12 @@ u8 adapter_allow_bmc_data_rx(_adapter *adapter) if (check_fwstate(&adapter->mlmepriv, WIFI_MONITOR_STATE | WIFI_MP_STATE) == _TRUE) return 1; +#ifdef RTW_SIMPLE_CONFIG + /* allow AP to receive multicast packet for RtwSimpleConfigV4 */ + if (MLME_IS_AP(adapter) && adapter->rtw_simple_config) + return 1; +#endif + if (MLME_IS_AP(adapter)) return 0; @@ -4818,44 +4763,89 @@ s32 pre_recv_entry(union recv_frame *precvframe, u8 *pphy_status) { s32 ret = _SUCCESS; u8 *pbuf = precvframe->u.hdr.rx_data; - u8 *pda = get_ra(pbuf); - u8 ra_is_bmc = IS_MCAST(pda); + u8 *ra = get_ra(pbuf); + u8 ra_is_bmc = IS_MCAST(ra); + bool phy_queried = 0; _adapter *primary_padapter = precvframe->u.hdr.adapter; -#ifdef CONFIG_CONCURRENT_MODE _adapter *iface = NULL; - #ifdef CONFIG_MP_INCLUDED +#ifdef CONFIG_MP_INCLUDED if (rtw_mp_mode_check(primary_padapter)) - goto bypass_concurrent_hdl; - #endif + goto query_phy_status; +#endif +#ifdef CONFIG_WIFI_MONITOR + if (MLME_IS_MONITOR(primary_padapter)) + goto query_phy_status; +#endif - if (ra_is_bmc == _FALSE) { /*unicast packets*/ - iface = rtw_get_iface_by_macddr(primary_padapter , pda); - if (NULL == iface) { - #ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI - if (_rtw_memcmp(pda, adapter_pno_mac_addr(primary_padapter), - ETH_ALEN) != _TRUE) - #endif - RTW_INFO("%s [WARN] Cannot find appropriate adapter - mac_addr : "MAC_FMT"\n", __func__, MAC_ARG(pda)); - /*rtw_warn_on(1);*/ - } else + if (ra_is_bmc == _FALSE) { + /* UC frame */ + iface = rtw_get_iface_by_macddr(primary_padapter , ra); + if (!iface) { + #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND) + if (_rtw_memcmp(ra, adapter_pno_mac_addr(primary_padapter), ETH_ALEN)) + goto query_phy_status; + #endif + + #ifdef CONFIG_RTW_MULTI_AP + /* unasoc STA RCPI */ + if (rtw_unassoc_sta_src_chk(primary_padapter, UNASOC_STA_SRC_RX_NMY_UC)) { + if (pphy_status) { + rx_query_phy_status(precvframe, pphy_status); + rtw_rx_add_unassoc_sta(primary_padapter, UNASOC_STA_SRC_RX_NMY_UC, get_ta(pbuf) + , precvframe->u.hdr.attrib.phy_info.recv_signal_power); + } + } else + #endif + RTW_INFO("%s [WARN] Cannot find appropriate adapter - mac_addr : "MAC_FMT"\n" + , __func__, MAC_ARG(ra)); + + rtw_free_recvframe(precvframe, &precvframe->u.hdr.adapter->recvpriv.free_recv_queue); + goto exit; + } + #ifdef CONFIG_CONCURRENT_MODE + else precvframe->u.hdr.adapter = iface; - } else /* Handle BC/MC Packets */ + #endif + + } else { + /* BMC frame */ + #ifdef CONFIG_CONCURRENT_MODE rtw_mi_buddy_clone_bcmc_packet(primary_padapter, precvframe, pphy_status); -bypass_concurrent_hdl: -#endif /* CONFIG_CONCURRENT_MODE */ - if (primary_padapter->registrypriv.mp_mode != 1) { - /* skip unnecessary bmc data frame for primary adapter */ - if (ra_is_bmc == _TRUE && GetFrameType(pbuf) == WIFI_DATA_TYPE + #endif + + #ifdef CONFIG_RTW_MULTI_AP + /* unasoc STA RCPI */ + if (pphy_status + && rtw_unassoc_sta_src_chk(primary_padapter, UNASOC_STA_SRC_RX_BMC) + ) { + phy_queried = 1; + rx_query_phy_status(precvframe, pphy_status); + rtw_rx_add_unassoc_sta(primary_padapter, UNASOC_STA_SRC_RX_BMC, get_ta(pbuf) + , precvframe->u.hdr.attrib.phy_info.recv_signal_power); + } + #endif + + /* skip unnecessary BMC data frame for primary adapter */ + if (GetFrameType(pbuf) == WIFI_DATA_TYPE && !adapter_allow_bmc_data_rx(precvframe->u.hdr.adapter) ) { rtw_free_recvframe(precvframe, &precvframe->u.hdr.adapter->recvpriv.free_recv_queue); goto exit; } } +#if defined(CONFIG_MP_INCLUDED) || defined(CONFIG_WIFI_MONITOR) || defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND) +query_phy_status: +#endif + if (pphy_status) { + if (!phy_queried) + rx_query_phy_status(precvframe, pphy_status); + #ifdef CONFIG_WIFI_MONITOR + if (MLME_IS_MONITOR(primary_padapter)) + rx_query_moinfo(&precvframe->u.hdr.attrib, pphy_status); + #endif + } - if (pphy_status) - rx_query_phy_status(precvframe, pphy_status); ret = rtw_recv_entry(precvframe); exit: diff --git a/core/rtw_rf.c b/core/rtw_rf.c index fe1053b..60c95c7 100644 --- a/core/rtw_rf.c +++ b/core/rtw_rf.c @@ -26,6 +26,8 @@ u8 center_ch_2g[CENTER_CH_2G_NUM] = { /* G05 */14 }; +#define ch_to_cch_2g_idx(ch) ((ch) - 1) + u8 center_ch_2g_40m[CENTER_CH_2G_40M_NUM] = { 3, 4, @@ -94,6 +96,13 @@ u8 center_ch_5g_20m[CENTER_CH_5G_20M_NUM] = { /* G13 */173, 177 }; +#define ch_to_cch_5g_20m_idx(ch) \ + ( \ + ((ch) >= 36 && (ch) <= 64) ? (((ch) - 36) >> 2) : \ + ((ch) >= 100 && (ch) <= 144) ? 8 + (((ch) - 100) >> 2) : \ + ((ch) >= 149 && (ch) <= 177) ? 20 + (((ch) - 149) >> 2) : 255 \ + ) + u8 center_ch_5g_40m[CENTER_CH_5G_40M_NUM] = { /* G00 */38, /* G01 */46, @@ -304,7 +313,7 @@ inline u8 center_chs_2g(u8 bw, u8 id) inline u8 center_chs_5g_num(u8 bw) { - if (bw > CHANNEL_WIDTH_80) + if (bw > CHANNEL_WIDTH_160) return 0; return center_chs_5g_by_bw[bw].ch_num; @@ -312,7 +321,7 @@ inline u8 center_chs_5g_num(u8 bw) inline u8 center_chs_5g(u8 bw, u8 id) { - if (bw > CHANNEL_WIDTH_80) + if (bw > CHANNEL_WIDTH_160) return 0; if (id >= center_chs_5g_num(bw)) @@ -368,6 +377,131 @@ exit: return valid; } +u8 rtw_get_offset_by_chbw(u8 ch, u8 bw, u8 *r_offset) +{ + u8 valid = 1; + u8 offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + if (bw == CHANNEL_WIDTH_20) + goto exit; + + if (bw >= CHANNEL_WIDTH_80 && ch <= 14) { + valid = 0; + goto exit; + } + + if (ch >= 1 && ch <= 4) + offset = HAL_PRIME_CHNL_OFFSET_LOWER; + else if (ch >= 5 && ch <= 9) { + if (*r_offset == HAL_PRIME_CHNL_OFFSET_LOWER || *r_offset == HAL_PRIME_CHNL_OFFSET_UPPER) + offset = *r_offset; /* both lower and upper is valid, obey input value */ + else + offset = HAL_PRIME_CHNL_OFFSET_UPPER; /* default use upper */ + } else if (ch >= 10 && ch <= 13) + offset = HAL_PRIME_CHNL_OFFSET_UPPER; + else if (ch == 14) { + valid = 0; /* ch14 doesn't support 40MHz bandwidth */ + goto exit; + } else if (ch >= 36 && ch <= 177) { + switch (ch) { + case 36: + case 44: + case 52: + case 60: + case 100: + case 108: + case 116: + case 124: + case 132: + case 140: + case 149: + case 157: + case 165: + case 173: + offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + case 40: + case 48: + case 56: + case 64: + case 104: + case 112: + case 120: + case 128: + case 136: + case 144: + case 153: + case 161: + case 169: + case 177: + offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + default: + valid = 0; + break; + } + } else + valid = 0; + +exit: + if (valid && r_offset) + *r_offset = offset; + return valid; +} + +u8 rtw_get_center_ch(u8 ch, u8 bw, u8 offset) +{ + u8 cch = ch; + + if (bw == CHANNEL_WIDTH_160) { + if (ch % 4 == 0) { + if (ch >= 36 && ch <= 64) + cch = 50; + else if (ch >= 100 && ch <= 128) + cch = 114; + } else if (ch % 4 == 1) { + if (ch >= 149 && ch <= 177) + cch = 163; + } + + } else if (bw == CHANNEL_WIDTH_80) { + if (ch <= 14) + cch = 7; /* special case for 2.4G */ + else if (ch % 4 == 0) { + if (ch >= 36 && ch <= 48) + cch = 42; + else if (ch >= 52 && ch <= 64) + cch = 58; + else if (ch >= 100 && ch <= 112) + cch = 106; + else if (ch >= 116 && ch <= 128) + cch = 122; + else if (ch >= 132 && ch <= 144) + cch = 138; + } else if (ch % 4 == 1) { + if (ch >= 149 && ch <= 161) + cch = 155; + else if (ch >= 165 && ch <= 177) + cch = 171; + } + + } else if (bw == CHANNEL_WIDTH_40) { + if (offset == HAL_PRIME_CHNL_OFFSET_LOWER) + cch = ch + 2; + else if (offset == HAL_PRIME_CHNL_OFFSET_UPPER) + cch = ch - 2; + + } else if (bw == CHANNEL_WIDTH_20 + || bw == CHANNEL_WIDTH_10 + || bw == CHANNEL_WIDTH_5 + ) + ; /* same as ch */ + else + rtw_warn_on(1); + + return cch; +} + u8 rtw_get_ch_group(u8 ch, u8 *group, u8 *cck_group) { BAND_TYPE band = BAND_MAX; @@ -504,7 +638,10 @@ bool rtw_chbw_to_freq_range(u8 ch, u8 bw, u8 offset, u32 *hi, u32 *lo) goto exit; } - if (bw == CHANNEL_WIDTH_80) { + if (bw == CHANNEL_WIDTH_160) { + hi_ret = freq + 80; + lo_ret = freq - 80; + } else if (bw == CHANNEL_WIDTH_80) { hi_ret = freq + 40; lo_ret = freq - 40; } else if (bw == CHANNEL_WIDTH_40) { @@ -528,23 +665,23 @@ exit: } const char *const _ch_width_str[CHANNEL_WIDTH_MAX] = { - "20MHz", - "40MHz", - "80MHz", - "160MHz", - "80_80MHz", - "5MHz", - "10MHz", + [CHANNEL_WIDTH_20] = "20MHz", + [CHANNEL_WIDTH_40] = "40MHz", + [CHANNEL_WIDTH_80] = "80MHz", + [CHANNEL_WIDTH_160] = "160MHz", + [CHANNEL_WIDTH_80_80] = "80_80MHz", + [CHANNEL_WIDTH_5] = "5MHz", + [CHANNEL_WIDTH_10] = "10MHz", }; const u8 _ch_width_to_bw_cap[CHANNEL_WIDTH_MAX] = { - BW_CAP_20M, - BW_CAP_40M, - BW_CAP_80M, - BW_CAP_160M, - BW_CAP_80_80M, - BW_CAP_5M, - BW_CAP_10M, + [CHANNEL_WIDTH_20] = BW_CAP_20M, + [CHANNEL_WIDTH_40] = BW_CAP_40M, + [CHANNEL_WIDTH_80] = BW_CAP_80M, + [CHANNEL_WIDTH_160] = BW_CAP_160M, + [CHANNEL_WIDTH_80_80] = BW_CAP_80_80M, + [CHANNEL_WIDTH_5] = BW_CAP_5M, + [CHANNEL_WIDTH_10] = BW_CAP_10M, }; const char *const _band_str[] = { @@ -559,89 +696,779 @@ const u8 _band_to_band_cap[] = { 0, }; -const u8 _rf_type_to_rf_tx_cnt[] = { - 1, /*RF_1T1R*/ - 1, /*RF_1T2R*/ - 2, /*RF_2T2R*/ - 2, /*RF_2T3R*/ - 2, /*RF_2T4R*/ - 3, /*RF_3T3R*/ - 3, /*RF_3T4R*/ - 4, /*RF_4T4R*/ - 1, /*RF_TYPE_MAX*/ +const char *const _opc_bw_str[OPC_BW_NUM] = { + "20M ", /* OPC_BW20 */ + "40M+", /* OPC_BW40PLUS */ + "40M-", /* OPC_BW40MINUS */ + "80M ", /* OPC_BW80 */ + "160M ", /* OPC_BW160 */ + "80+80M ", /* OPC_BW80P80 */ }; -const u8 _rf_type_to_rf_rx_cnt[] = { - 1, /*RF_1T1R*/ - 2, /*RF_1T2R*/ - 2, /*RF_2T2R*/ - 3, /*RF_2T3R*/ - 4, /*RF_2T4R*/ - 3, /*RF_3T3R*/ - 4, /*RF_3T4R*/ - 4, /*RF_4T4R*/ - 1, /*RF_TYPE_MAX*/ +const u8 _opc_bw_to_ch_width[OPC_BW_NUM] = { + CHANNEL_WIDTH_20, /* OPC_BW20 */ + CHANNEL_WIDTH_40, /* OPC_BW40PLUS */ + CHANNEL_WIDTH_40, /* OPC_BW40MINUS */ + CHANNEL_WIDTH_80, /* OPC_BW80 */ + CHANNEL_WIDTH_160, /* OPC_BW160 */ + CHANNEL_WIDTH_80_80, /* OPC_BW80P80 */ }; -const char *const _rf_type_to_rfpath_str[] = { - "RF_1T1R", - "RF_1T2R", - "RF_2T2R", - "RF_2T3R", - "RF_2T4R", - "RF_3T3R", - "RF_3T4R", - "RF_4T4R", - "RF_TYPE_MAX" +/* global operating class database */ + +struct op_class_t { + u8 class_id; + BAND_TYPE band; + enum opc_bw bw; + u8 *len_ch_attr; +}; + +#define OPC_CH_LIST_LEN(_opc) (_opc.len_ch_attr[0]) +#define OPC_CH_LIST_CH(_opc, _i) (_opc.len_ch_attr[_i + 1]) + +#define OP_CLASS_ENT(_class, _band, _bw, _len, arg...) \ + {.class_id = _class, .band = _band, .bw = _bw, .len_ch_attr = (uint8_t[_len + 1]) {_len, ##arg},} + +/* 802.11-2016 Table E-4, partial */ +static const struct op_class_t global_op_class[] = { + /* 2G ch1~13, 20M */ + OP_CLASS_ENT(81, BAND_ON_2_4G, OPC_BW20, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), + /* 2G ch14, 20M */ + OP_CLASS_ENT(82, BAND_ON_2_4G, OPC_BW20, 1, 14), + /* 2G, 40M */ + OP_CLASS_ENT(83, BAND_ON_2_4G, OPC_BW40PLUS, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9), + OP_CLASS_ENT(84, BAND_ON_2_4G, OPC_BW40MINUS, 9, 5, 6, 7, 8, 9, 10, 11, 12, 13), + /* 5G band 1, 20M & 40M */ + OP_CLASS_ENT(115, BAND_ON_5G, OPC_BW20, 4, 36, 40, 44, 48), + OP_CLASS_ENT(116, BAND_ON_5G, OPC_BW40PLUS, 2, 36, 44), + OP_CLASS_ENT(117, BAND_ON_5G, OPC_BW40MINUS, 2, 40, 48), + /* 5G band 2, 20M & 40M */ + OP_CLASS_ENT(118, BAND_ON_5G, OPC_BW20, 4, 52, 56, 60, 64), + OP_CLASS_ENT(119, BAND_ON_5G, OPC_BW40PLUS, 2, 52, 60), + OP_CLASS_ENT(120, BAND_ON_5G, OPC_BW40MINUS, 2, 56, 64), + /* 5G band 3, 20M & 40M */ + OP_CLASS_ENT(121, BAND_ON_5G, OPC_BW20, 12, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144), + OP_CLASS_ENT(122, BAND_ON_5G, OPC_BW40PLUS, 6, 100, 108, 116, 124, 132, 140), + OP_CLASS_ENT(123, BAND_ON_5G, OPC_BW40MINUS, 6, 104, 112, 120, 128, 136, 144), + /* 5G band 4, 20M & 40M */ + OP_CLASS_ENT(124, BAND_ON_5G, OPC_BW20, 4, 149, 153, 157, 161), + OP_CLASS_ENT(125, BAND_ON_5G, OPC_BW20, 6, 149, 153, 157, 161, 165, 169), + OP_CLASS_ENT(126, BAND_ON_5G, OPC_BW40PLUS, 2, 149, 157), + OP_CLASS_ENT(127, BAND_ON_5G, OPC_BW40MINUS, 2, 153, 161), + /* 5G, 80M & 160M */ + OP_CLASS_ENT(128, BAND_ON_5G, OPC_BW80, 24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161), + OP_CLASS_ENT(129, BAND_ON_5G, OPC_BW160, 16, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128), + #if 0 /* TODO */ + /* 5G, 80+80M */ + {130, BAND_ON_5G, OPC_BW80P80, 0x0FFFFFF}, + #endif +}; + +static const int global_op_class_num = sizeof(global_op_class) / sizeof(struct op_class_t); + +static const struct op_class_t *get_global_op_class_by_id(u8 gid) +{ + int i; + + for (i = 0; i < global_op_class_num; i++) + if (global_op_class[i].class_id == gid) + break; + + return i < global_op_class_num ? &global_op_class[i] : NULL; +} + +bool is_valid_global_op_class_id(u8 gid) +{ + return get_global_op_class_by_id(gid) ? 1 : 0; +} + +static bool is_valid_global_op_class_ch(const struct op_class_t *opc, u8 ch) +{ + int array_idx; + int i; + + if (opc < global_op_class + || (((u8 *)opc) - ((u8 *)global_op_class)) % sizeof(struct op_class_t) + ) { + RTW_ERR("Invalid opc pointer:%p (global_op_class:%p, sizeof(struct op_class_t):%zu, %zu)\n" + , opc, global_op_class, sizeof(struct op_class_t), (((u8 *)opc) - ((u8 *)global_op_class)) % sizeof(struct op_class_t)); + return 0; + } + + array_idx = (((u8 *)opc) - ((u8 *)global_op_class)) / sizeof(struct op_class_t); + + for (i = 0; i < OPC_CH_LIST_LEN(global_op_class[array_idx]); i++) + if (OPC_CH_LIST_CH(global_op_class[array_idx], i) == ch) + break; + + return i < OPC_CH_LIST_LEN(global_op_class[array_idx]); +} + +static enum opc_bw get_global_opc_bw_by_id(u8 gid) +{ + int i; + + for (i = 0; i < global_op_class_num; i++) + if (global_op_class[i].class_id == gid) + break; + + return i < global_op_class_num ? global_op_class[i].bw : OPC_BW_NUM; +} + +/* -2: logic error, -1: error, 0: is already BW20 */ +s16 get_sub_op_class(u8 gid, u8 ch) +{ + const struct op_class_t *opc = get_global_op_class_by_id(gid); + int i; + enum channel_width bw; + + if (!opc) + return -1; + + if (!is_valid_global_op_class_ch(opc, ch)) { + return -1; + } + + if (opc->bw == OPC_BW20) + return 0; + + bw = opc_bw_to_ch_width(opc->bw); + + for (i = 0; i < global_op_class_num; i++) { + if (bw != opc_bw_to_ch_width(global_op_class[i].bw) + 1) + continue; + if (is_valid_global_op_class_ch(&global_op_class[i], ch)) + break; + } + + return i < global_op_class_num ? global_op_class[i].class_id : -2; +} + +static void dump_op_class_ch_title(void *sel) +{ + RTW_PRINT_SEL(sel, "%-5s %-4s %-7s ch_list\n" + , "class", "band", "bw"); +} + +static void dump_global_op_class_ch_single(void *sel, u8 gid) +{ + u8 i; + char buf[100]; + char *pos = buf; + + for (i = 0; i < OPC_CH_LIST_LEN(global_op_class[gid]); i++) + pos += snprintf(pos, 100 - (pos - buf), " %u", OPC_CH_LIST_CH(global_op_class[gid], i)); + + RTW_PRINT_SEL(sel, "%5u %4s %7s%s\n" + , global_op_class[gid].class_id + , band_str(global_op_class[gid].band) + , opc_bw_str(global_op_class[gid].bw), buf); +} + +#ifdef CONFIG_RTW_DEBUG +static bool dbg_global_op_class_validate(u8 gid) +{ + u8 i; + u8 ch, bw, offset, cch; + bool ret = 1; + + switch (global_op_class[gid].bw) { + case OPC_BW20: + bw = CHANNEL_WIDTH_20; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case OPC_BW40PLUS: + bw = CHANNEL_WIDTH_40; + offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + case OPC_BW40MINUS: + bw = CHANNEL_WIDTH_40; + offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + case OPC_BW80: + bw = CHANNEL_WIDTH_80; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case OPC_BW160: + bw = CHANNEL_WIDTH_160; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case OPC_BW80P80: /* TODO */ + default: + RTW_ERR("%s class:%u unsupported opc_bw:%u\n" + , __func__, global_op_class[gid].class_id, global_op_class[gid].bw); + ret = 0; + goto exit; + } + + for (i = 0; i < OPC_CH_LIST_LEN(global_op_class[gid]); i++) { + u8 *op_chs; + u8 op_ch_num; + u8 k; + + ch = OPC_CH_LIST_CH(global_op_class[gid], i); + cch = rtw_get_center_ch(ch ,bw, offset); + if (!cch) { + RTW_ERR("%s can't get cch from class:%u ch:%u\n" + , __func__, global_op_class[gid].class_id, ch); + ret = 0; + continue; + } + + if (!rtw_get_op_chs_by_cch_bw(cch, bw, &op_chs, &op_ch_num)) { + RTW_ERR("%s can't get op chs from class:%u cch:%u\n" + , __func__, global_op_class[gid].class_id, cch); + ret = 0; + continue; + } + + for (k = 0; k < op_ch_num; k++) { + if (*(op_chs + k) == ch) + break; + } + if (k >= op_ch_num) { + RTW_ERR("%s can't get ch:%u from op_chs class:%u cch:%u\n" + , __func__, ch, global_op_class[i].class_id, cch); + ret = 0; + } + } + +exit: + return ret; +} +#endif /* CONFIG_RTW_DEBUG */ + +void dump_global_op_class(void *sel) +{ + u8 i; + + dump_op_class_ch_title(sel); + + for (i = 0; i < global_op_class_num; i++) + dump_global_op_class_ch_single(sel, i); +} + +u8 rtw_get_op_class_by_chbw(u8 ch, u8 bw, u8 offset) +{ + BAND_TYPE band = BAND_MAX; + int i; + u8 gid = 0; /* invalid */ + + if (rtw_is_2g_ch(ch)) + band = BAND_ON_2_4G; + else if (rtw_is_5g_ch(ch)) + band = BAND_ON_5G; + else + goto exit; + + switch (bw) { + case CHANNEL_WIDTH_20: + case CHANNEL_WIDTH_40: + case CHANNEL_WIDTH_80: + case CHANNEL_WIDTH_160: + #if 0 /* TODO */ + case CHANNEL_WIDTH_80_80: + #endif + break; + default: + goto exit; + } + + for (i = 0; i < global_op_class_num; i++) { + if (band != global_op_class[i].band) + continue; + + if (opc_bw_to_ch_width(global_op_class[i].bw) != bw) + continue; + + if ((global_op_class[i].bw == OPC_BW40PLUS + && offset != HAL_PRIME_CHNL_OFFSET_LOWER) + || (global_op_class[i].bw == OPC_BW40MINUS + && offset != HAL_PRIME_CHNL_OFFSET_UPPER) + ) + continue; + + if (is_valid_global_op_class_ch(&global_op_class[i], ch)) + goto get; + } + +get: + if (i < global_op_class_num) { + #if 0 /* TODO */ + if (bw == CHANNEL_WIDTH_80_80) { + /* search another ch */ + if (!is_valid_global_op_class_ch(&global_op_class[i], ch2)) + goto exit; + } + #endif + + gid = global_op_class[i].class_id; + } + +exit: + return gid; +} + +u8 rtw_get_bw_offset_by_op_class_ch(u8 gid, u8 ch, u8 *bw, u8 *offset) +{ + enum opc_bw opc_bw; + u8 valid = 0; + int i; + + opc_bw = get_global_opc_bw_by_id(gid); + if (opc_bw == OPC_BW_NUM) + goto exit; + + *bw = opc_bw_to_ch_width(opc_bw); + + if (opc_bw == OPC_BW40PLUS) + *offset = HAL_PRIME_CHNL_OFFSET_LOWER; + else if (opc_bw == OPC_BW40MINUS) + *offset = HAL_PRIME_CHNL_OFFSET_UPPER; + + if (rtw_get_offset_by_chbw(ch, *bw, offset)) + valid = 1; + +exit: + return valid; +} + +static struct op_class_pref_t *opc_pref_alloc(u8 class_id) +{ + int i, j; + struct op_class_pref_t *opc_pref = NULL; + + for (i = 0; i < global_op_class_num; i++) + if (global_op_class[i].class_id == class_id) + break; + + if (i >= global_op_class_num) + goto exit; + + opc_pref = rtw_zmalloc(sizeof(*opc_pref)); + if (!opc_pref) + goto exit; + + opc_pref->class_id = global_op_class[i].class_id; + opc_pref->band = global_op_class[i].band; + opc_pref->bw = global_op_class[i].bw; + + for (j = 0; j < OPC_CH_LIST_LEN(global_op_class[i]); j++) { + opc_pref->chs[j].ch = OPC_CH_LIST_CH(global_op_class[i], j); + opc_pref->chs[j].static_non_op = 1; + opc_pref->chs[j].no_ir = 1; + opc_pref->chs[j].max_txpwr = UNSPECIFIED_MBM; + } + opc_pref->ch_num = OPC_CH_LIST_LEN(global_op_class[i]); + +exit: + return opc_pref; +} + +static void opc_pref_free(struct op_class_pref_t *opc_pref) +{ + rtw_mfree(opc_pref, sizeof(*opc_pref)); +} + +int op_class_pref_init(_adapter *adapter) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + struct registry_priv *regsty = adapter_to_regsty(adapter); + u8 bw; + struct op_class_pref_t *opc_pref; + int i; + u8 op_class_num = 0; + u8 band_bmp = 0; + u8 bw_bmp[BAND_MAX] = {0}; + int ret = _FAIL; + + rfctl->spt_op_class_ch = rtw_zmalloc(sizeof(struct op_class_pref_t *) * global_op_class_num); + if (!rfctl->spt_op_class_ch) { + RTW_ERR("%s alloc rfctl->spt_op_class_ch fail\n", __func__); + goto exit; + } + + if (IsSupported24G(regsty->wireless_mode) && hal_chk_band_cap(adapter, BAND_CAP_2G)) + band_bmp |= BAND_CAP_2G; + if (is_supported_5g(regsty->wireless_mode) && hal_chk_band_cap(adapter, BAND_CAP_5G)) + band_bmp |= BAND_CAP_5G; + + bw_bmp[BAND_ON_2_4G] = (ch_width_to_bw_cap(REGSTY_BW_2G(regsty) + 1) - 1) & (GET_HAL_SPEC(adapter)->bw_cap); + bw_bmp[BAND_ON_5G] = (ch_width_to_bw_cap(REGSTY_BW_5G(regsty) + 1) - 1) & (GET_HAL_SPEC(adapter)->bw_cap); + if (!REGSTY_IS_11AC_ENABLE(regsty) + || !is_supported_vht(regsty->wireless_mode) + ) + bw_bmp[BAND_ON_5G] &= ~(BW_CAP_80M | BW_CAP_160M); + + if (0) { + RTW_INFO("REGSTY_BW_2G(regsty):%u\n", REGSTY_BW_2G(regsty)); + RTW_INFO("REGSTY_BW_5G(regsty):%u\n", REGSTY_BW_5G(regsty)); + RTW_INFO("GET_HAL_SPEC(adapter)->bw_cap:0x%x\n", GET_HAL_SPEC(adapter)->bw_cap); + RTW_INFO("band_bmp:0x%x\n", band_bmp); + RTW_INFO("bw_bmp[2G]:0x%x\n", bw_bmp[BAND_ON_2_4G]); + RTW_INFO("bw_bmp[5G]:0x%x\n", bw_bmp[BAND_ON_5G]); + } + + for (i = 0; i < global_op_class_num; i++) { + #ifdef CONFIG_RTW_DEBUG + rtw_warn_on(!dbg_global_op_class_validate(i)); + #endif + + if (!(band_bmp & band_to_band_cap(global_op_class[i].band))) + continue; + + bw = opc_bw_to_ch_width(global_op_class[i].bw); + if (bw == CHANNEL_WIDTH_MAX + || bw == CHANNEL_WIDTH_80_80 /* TODO */ + ) + continue; + + if (!(bw_bmp[global_op_class[i].band] & ch_width_to_bw_cap(bw))) + continue; + + opc_pref = opc_pref_alloc(global_op_class[i].class_id); + if (!opc_pref) { + RTW_ERR("%s opc_pref_alloc(%u) fail\n", __func__, global_op_class[i].class_id); + goto exit; + } + + if (opc_pref->ch_num) { + rfctl->spt_op_class_ch[i] = opc_pref; + op_class_num++; + } else + opc_pref_free(opc_pref); + } + + rfctl->cap_spt_op_class_num = op_class_num; + ret = _SUCCESS; + +exit: + return ret; +} + +void op_class_pref_deinit(_adapter *adapter) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + int i; + + if (!rfctl->spt_op_class_ch) + return; + + for (i = 0; i < global_op_class_num; i++) { + if (rfctl->spt_op_class_ch[i]) { + opc_pref_free(rfctl->spt_op_class_ch[i]); + rfctl->spt_op_class_ch[i] = NULL; + } + } + + rtw_mfree(rfctl->spt_op_class_ch, sizeof(struct op_class_pref_t *) * global_op_class_num); + rfctl->spt_op_class_ch = NULL; +} + +void op_class_pref_apply_regulatory(_adapter *adapter, u8 reason) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + RT_CHANNEL_INFO *chset = rfctl->channel_set; + struct registry_priv *regsty = adapter_to_regsty(adapter); + u8 ch, bw, offset, cch; + struct op_class_pref_t *opc_pref; + int i, j; + u8 reg_op_class_num = 0; + u8 op_class_num = 0; + + for (i = 0; i < global_op_class_num; i++) { + if (!rfctl->spt_op_class_ch[i]) + continue; + opc_pref = rfctl->spt_op_class_ch[i]; + + /* reset all channel */ + for (j = 0; opc_pref->chs[j].ch != 0; j++) { + if (reason >= REG_CHANGE) + opc_pref->chs[j].static_non_op = 1; + if (reason != REG_TXPWR_CHANGE) + opc_pref->chs[j].no_ir = 1; + if (reason >= REG_TXPWR_CHANGE) + opc_pref->chs[j].max_txpwr = UNSPECIFIED_MBM; + } + if (reason >= REG_CHANGE) + opc_pref->op_ch_num = 0; + if (reason != REG_TXPWR_CHANGE) + opc_pref->ir_ch_num = 0; + + switch (opc_pref->bw) { + case OPC_BW20: + bw = CHANNEL_WIDTH_20; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case OPC_BW40PLUS: + bw = CHANNEL_WIDTH_40; + offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + case OPC_BW40MINUS: + bw = CHANNEL_WIDTH_40; + offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + case OPC_BW80: + bw = CHANNEL_WIDTH_80; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case OPC_BW160: + bw = CHANNEL_WIDTH_160; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case OPC_BW80P80: /* TODO */ + default: + continue; + } + + if (rfctl->country_ent && !COUNTRY_CHPLAN_EN_11AC(rfctl->country_ent) + && (bw == CHANNEL_WIDTH_80 || bw == CHANNEL_WIDTH_160)) + continue; + + for (j = 0; opc_pref->chs[j].ch != 0; j++) { + u8 *op_chs; + u8 op_ch_num; + u8 k, l; + int chset_idx; + + ch = opc_pref->chs[j].ch; + + if (reason >= REG_TXPWR_CHANGE) + opc_pref->chs[j].max_txpwr = rtw_rfctl_get_reg_max_txpwr_mbm(rfctl, ch, bw, offset, 1); + + if (reason == REG_TXPWR_CHANGE) + continue; + + cch = rtw_get_center_ch(ch ,bw, offset); + if (!cch) + continue; + + if (!rtw_get_op_chs_by_cch_bw(cch, bw, &op_chs, &op_ch_num)) + continue; + + for (k = 0, l = 0; k < op_ch_num; k++) { + chset_idx = rtw_chset_search_ch(chset, *(op_chs + k)); + if (chset_idx == -1) + break; + if (bw >= CHANNEL_WIDTH_40) { + if ((chset[chset_idx].flags & RTW_CHF_NO_HT40U) && k % 2 == 0) + break; + if ((chset[chset_idx].flags & RTW_CHF_NO_HT40L) && k % 2 == 1) + break; + } + if (bw >= CHANNEL_WIDTH_80 && (chset[chset_idx].flags & RTW_CHF_NO_80MHZ)) + break; + if (bw >= CHANNEL_WIDTH_160 && (chset[chset_idx].flags & RTW_CHF_NO_160MHZ)) + break; + if ((chset[chset_idx].flags & RTW_CHF_DFS) && rtw_rfctl_dfs_domain_unknown(rfctl)) + continue; + if (chset[chset_idx].flags & RTW_CHF_NO_IR) + continue; + l++; + } + if (k < op_ch_num) + continue; + + if (reason >= REG_CHANGE) { + opc_pref->chs[j].static_non_op = 0; + opc_pref->op_ch_num++; + } + + if (l >= op_ch_num) { + opc_pref->chs[j].no_ir = 0; + opc_pref->ir_ch_num++; + } + } + + if (opc_pref->op_ch_num) + reg_op_class_num++; + if (opc_pref->ir_ch_num) + op_class_num++; + } + + rfctl->reg_spt_op_class_num = reg_op_class_num; + rfctl->cur_spt_op_class_num = op_class_num; +} + +static void dump_opc_pref_single(void *sel, struct op_class_pref_t *opc_pref, bool show_snon_ocp, bool show_no_ir, bool detail) +{ + u8 i; + u8 ch_num = 0; + char buf[256]; + char *pos = buf; + + if (!show_snon_ocp && !opc_pref->op_ch_num) + return; + if (!show_no_ir && !opc_pref->ir_ch_num) + return; + + for (i = 0; opc_pref->chs[i].ch != 0; i++) { + if ((show_snon_ocp || !opc_pref->chs[i].static_non_op) + && (show_no_ir || !opc_pref->chs[i].no_ir) + ) { + if (detail) + pos += snprintf(pos, 256 - (pos - buf), " %4u", opc_pref->chs[i].ch); + else + pos += snprintf(pos, 256 - (pos - buf), " %u", opc_pref->chs[i].ch); + } + } + + RTW_PRINT_SEL(sel, "%5u %4s %7s%s\n" + , opc_pref->class_id + , band_str(opc_pref->band) + , opc_bw_str(opc_pref->bw), buf); + + if (!detail) + return; + + pos = buf; + for (i = 0; opc_pref->chs[i].ch != 0; i++) { + if ((show_snon_ocp || !opc_pref->chs[i].static_non_op) + && (show_no_ir || !opc_pref->chs[i].no_ir) + ) { + pos += snprintf(pos, 256 - (pos - buf), " %c%c" + , opc_pref->chs[i].no_ir ? ' ' : 'I' + , opc_pref->chs[i].static_non_op ? ' ' : 'E' + ); + } + } + RTW_PRINT_SEL(sel, " %s\n", buf); + + pos = buf; + for (i = 0; opc_pref->chs[i].ch != 0; i++) { + if ((show_snon_ocp || !opc_pref->chs[i].static_non_op) + && (show_no_ir || !opc_pref->chs[i].no_ir) + ) { + if (opc_pref->chs[i].max_txpwr == UNSPECIFIED_MBM) + pos += snprintf(pos, 256 - (pos - buf), " "); + else + pos += snprintf(pos, 256 - (pos - buf), " %4d", opc_pref->chs[i].max_txpwr); + } + } + RTW_PRINT_SEL(sel, " %s\n", buf); +} + +void dump_cap_spt_op_class_ch(void *sel, struct rf_ctl_t *rfctl, bool detail) +{ + u8 i; + + dump_op_class_ch_title(sel); + + for (i = 0; i < global_op_class_num; i++) { + if (!rfctl->spt_op_class_ch[i]) + continue; + dump_opc_pref_single(sel, rfctl->spt_op_class_ch[i], 1, 1, detail); + } + + RTW_PRINT_SEL(sel, "op_class number:%d\n", rfctl->cap_spt_op_class_num); +} + +void dump_reg_spt_op_class_ch(void *sel, struct rf_ctl_t *rfctl, bool detail) +{ + u8 i; + + dump_op_class_ch_title(sel); + + for (i = 0; i < global_op_class_num; i++) { + if (!rfctl->spt_op_class_ch[i]) + continue; + dump_opc_pref_single(sel, rfctl->spt_op_class_ch[i], 0, 1, detail); + } + + RTW_PRINT_SEL(sel, "op_class number:%d\n", rfctl->reg_spt_op_class_num); +} + +void dump_cur_spt_op_class_ch(void *sel, struct rf_ctl_t *rfctl, bool detail) +{ + u8 i; + + dump_op_class_ch_title(sel); + + for (i = 0; i < global_op_class_num; i++) { + if (!rfctl->spt_op_class_ch[i]) + continue; + dump_opc_pref_single(sel, rfctl->spt_op_class_ch[i], 0, 0, detail); + } + + RTW_PRINT_SEL(sel, "op_class number:%d\n", rfctl->cur_spt_op_class_num); +} + +const u8 _rf_type_to_rf_tx_cnt[RF_TYPE_MAX] = { + [RF_1T1R] = 1, + [RF_1T2R] = 1, + [RF_1T3R] = 1, + [RF_1T4R] = 1, + [RF_2T1R] = 2, + [RF_2T2R] = 2, + [RF_2T3R] = 2, + [RF_2T4R] = 2, + [RF_3T1R] = 3, + [RF_3T2R] = 3, + [RF_3T3R] = 3, + [RF_3T4R] = 3, + [RF_4T1R] = 4, + [RF_4T2R] = 4, + [RF_4T3R] = 4, + [RF_4T4R] = 4, +}; + +const u8 _rf_type_to_rf_rx_cnt[RF_TYPE_MAX] = { + [RF_1T1R] = 1, + [RF_1T2R] = 2, + [RF_1T3R] = 3, + [RF_1T4R] = 4, + [RF_2T1R] = 1, + [RF_2T2R] = 2, + [RF_2T3R] = 3, + [RF_2T4R] = 4, + [RF_3T1R] = 1, + [RF_3T2R] = 2, + [RF_3T3R] = 3, + [RF_3T4R] = 4, + [RF_4T1R] = 1, + [RF_4T2R] = 2, + [RF_4T3R] = 3, + [RF_4T4R] = 4, +}; + +const char *const _rf_type_to_rfpath_str[RF_TYPE_MAX] = { + [RF_1T1R] = "RF_1T1R", + [RF_1T2R] = "RF_1T2R", + [RF_1T3R] = "RF_1T3R", + [RF_1T4R] = "RF_1T4R", + [RF_2T1R] = "RF_2T1R", + [RF_2T2R] = "RF_2T2R", + [RF_2T3R] = "RF_2T3R", + [RF_2T4R] = "RF_2T4R", + [RF_3T1R] = "RF_3T1R", + [RF_3T2R] = "RF_3T2R", + [RF_3T3R] = "RF_3T3R", + [RF_3T4R] = "RF_3T4R", + [RF_4T1R] = "RF_4T1R", + [RF_4T2R] = "RF_4T2R", + [RF_4T3R] = "RF_4T3R", + [RF_4T4R] = "RF_4T4R", }; void rf_type_to_default_trx_bmp(enum rf_type rf, enum bb_path *tx, enum bb_path *rx) { - switch (rf) { - case RF_1T1R: - *tx = BB_PATH_A; - *rx = BB_PATH_A; - break; - case RF_1T2R: - *tx = BB_PATH_A; - *rx = BB_PATH_AB; - break; - case RF_2T2R: - *tx = BB_PATH_AB; - *rx = BB_PATH_AB; - break; - case RF_2T3R: - *tx = BB_PATH_AB; - *rx = BB_PATH_ABC; - break; - case RF_2T4R: - *tx = BB_PATH_AB; - *rx = BB_PATH_ABCD; - break; - case RF_3T3R: - *tx = BB_PATH_ABC; - *rx = BB_PATH_ABC; - break; - case RF_3T4R: - *tx = BB_PATH_ABC; - *rx = BB_PATH_ABCD; - break; - case RF_4T4R: - *tx = BB_PATH_ABCD; - *rx = BB_PATH_ABCD; - break; - default: - *tx = BB_PATH_A; - *rx = BB_PATH_A; - break; - } + u8 tx_num = rf_type_to_rf_tx_cnt(rf); + u8 rx_num = rf_type_to_rf_rx_cnt(rf); + int i; + + *tx = *rx = 0; + + for (i = 0; i < tx_num; i++) + *tx |= BIT(i); + for (i = 0; i < rx_num; i++) + *rx |= BIT(i); } static const u8 _trx_num_to_rf_type[RF_PATH_MAX][RF_PATH_MAX] = { - {RF_1T1R, RF_1T2R, RF_TYPE_MAX, RF_TYPE_MAX}, - {RF_TYPE_MAX, RF_2T2R, RF_2T3R, RF_2T4R}, - {RF_TYPE_MAX, RF_TYPE_MAX, RF_3T3R, RF_3T4R}, - {RF_TYPE_MAX, RF_TYPE_MAX, RF_TYPE_MAX, RF_4T4R}, + {RF_1T1R, RF_1T2R, RF_1T3R, RF_1T4R}, + {RF_2T1R, RF_2T2R, RF_2T3R, RF_2T4R}, + {RF_3T1R, RF_3T2R, RF_3T3R, RF_3T4R}, + {RF_4T1R, RF_4T2R, RF_4T3R, RF_4T4R}, }; enum rf_type trx_num_to_rf_type(u8 tx_num, u8 rx_num) @@ -685,12 +1512,11 @@ static void rtw_path_bmp_limit_from_higher(u8 *bmp, u8 *bmp_bit_cnt, u8 bit_cnt_ } } -u8 rtw_restrict_trx_path_bmp_by_rftype(u8 trx_path_bmp, enum rf_type type, u8 *tx_num, u8 *rx_num) +u8 rtw_restrict_trx_path_bmp_by_trx_num_lmt(u8 trx_path_bmp, u8 tx_num_lmt, u8 rx_num_lmt, u8 *tx_num, u8 *rx_num) { u8 bmp_tx = (trx_path_bmp & 0xF0) >> 4; u8 bmp_rx = trx_path_bmp & 0x0F; u8 bmp_tx_num = 0, bmp_rx_num = 0; - u8 tx_num_lmt, rx_num_lmt; enum rf_type ret_type = RF_TYPE_MAX; int i, j; @@ -702,10 +1528,10 @@ u8 rtw_restrict_trx_path_bmp_by_rftype(u8 trx_path_bmp, enum rf_type type, u8 *t } /* limit higher bit first according to input type */ - tx_num_lmt = rf_type_to_rf_tx_cnt(type); - rx_num_lmt = rf_type_to_rf_rx_cnt(type); - rtw_path_bmp_limit_from_higher(&bmp_tx, &bmp_tx_num, tx_num_lmt); - rtw_path_bmp_limit_from_higher(&bmp_rx, &bmp_rx_num, rx_num_lmt); + if (tx_num_lmt) + rtw_path_bmp_limit_from_higher(&bmp_tx, &bmp_tx_num, tx_num_lmt); + if (rx_num_lmt) + rtw_path_bmp_limit_from_higher(&bmp_rx, &bmp_rx_num, rx_num_lmt); /* search for valid rf_type (larger RX prefer) */ for (j = bmp_rx_num; j > 0; j--) { @@ -727,6 +1553,12 @@ exit: return RF_TYPE_VALID(ret_type) ? ((bmp_tx << 4) | bmp_rx) : 0x00; } +u8 rtw_restrict_trx_path_bmp_by_rftype(u8 trx_path_bmp, enum rf_type type, u8 *tx_num, u8 *rx_num) +{ + return rtw_restrict_trx_path_bmp_by_trx_num_lmt(trx_path_bmp + , rf_type_to_rf_tx_cnt(type), rf_type_to_rf_rx_cnt(type), tx_num, rx_num); +} + /* config to non N-TX value, path with lower index prefer */ void tx_path_nss_set_default(enum bb_path txpath_nss[], u8 txpath_num_nss[], u8 txpath) { @@ -770,9 +1602,12 @@ const char *const _regd_str[] = { "ETSI", "IC", "KCC", + "NCC", "ACMA", "CHILE", + "UKRAINE", "MEXICO", + "CN", "WW", }; @@ -1477,7 +2312,8 @@ exit: void rtw_rf_set_tx_gain_offset(_adapter *adapter, u8 path, s8 offset) { -#if !defined(CONFIG_RTL8814A) && !defined(CONFIG_RTL8822B) && !defined(CONFIG_RTL8821C) && !defined(CONFIG_RTL8822C) +#if !defined(CONFIG_RTL8814A) && !defined(CONFIG_RTL8822B) && !defined(CONFIG_RTL8821C) && !defined(CONFIG_RTL8822C) \ + && !defined(CONFIG_RTL8723F) u8 write_value; #endif u8 target_path = 0; @@ -1537,15 +2373,17 @@ void rtw_rf_set_tx_gain_offset(_adapter *adapter, u8 path, s8 offset) rtw_hal_write_rfreg(adapter, target_path, 0x55, 0x0f8000, write_value); break; #endif /* CONFIG_RTL8821A */ -#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8822C) +#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8822C) \ + || defined(CONFIG_RTL8723F) case RTL8814A: case RTL8822B: case RTL8822C: case RTL8821C: case RTL8192F: + case RTL8723F: RTW_INFO("\nkfree by PhyDM on the sw CH. path %d\n", path); break; -#endif /* CONFIG_RTL8814A || CONFIG_RTL8822B || CONFIG_RTL8821C */ +#endif /* CONFIG_RTL8814A || CONFIG_RTL8822B || CONFIG_RTL8821C || CONFIG_RTL8723F */ default: rtw_warn_on(1); @@ -1565,7 +2403,7 @@ void rtw_rf_set_tx_gain_offset(_adapter *adapter, u8 path, s8 offset) void rtw_rf_apply_tx_gain_offset(_adapter *adapter, u8 ch) { - HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); s8 kfree_offset = 0; s8 tx_pwr_track_offset = 0; /* TODO: 8814A should consider tx pwr track when setting tx gain offset */ s8 total_offset; @@ -1574,7 +2412,7 @@ void rtw_rf_apply_tx_gain_offset(_adapter *adapter, u8 ch) if (IS_HARDWARE_TYPE_8723D(adapter)) total = 2; /* S1 and S0 */ else - total = hal_data->NumTotalRFPath; + total = hal_spec->rf_reg_path_num; for (i = 0; i < total; i++) { kfree_offset = rtw_rf_get_kfree_tx_gain_offset(adapter, i, ch); @@ -1585,7 +2423,7 @@ void rtw_rf_apply_tx_gain_offset(_adapter *adapter, u8 ch) bool rtw_is_long_cac_range(u32 hi, u32 lo, u8 dfs_region) { - return (dfs_region == PHYDM_DFS_DOMAIN_ETSI && rtw_is_range_overlap(hi, lo, 5650, 5600)) ? _TRUE : _FALSE; + return (dfs_region == RTW_DFS_REGD_ETSI && rtw_is_range_overlap(hi, lo, 5650, 5600)) ? _TRUE : _FALSE; } bool rtw_is_long_cac_ch(u8 ch, u8 bw, u8 offset, u8 dfs_region) diff --git a/core/rtw_rm.c b/core/rtw_rm.c index 10e149b..38ceb2e 100644 --- a/core/rtw_rm.c +++ b/core/rtw_rm.c @@ -21,6 +21,9 @@ #endif #define pstr(s) s+strlen(s) +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif u8 rm_post_event_hdl(_adapter *padapter, u8 *pbuf) { @@ -191,8 +194,6 @@ int rm_en_cap_chk_and_set(struct rm_obj *prm, enum rm_cap_en en) /* for caller outside rm */ u8 rm_add_nb_req(_adapter *padapter, struct sta_info *psta) { - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct rm_obj *prm; @@ -205,16 +206,9 @@ u8 rm_add_nb_req(_adapter *padapter, struct sta_info *psta) prm->psta = psta; prm->q.category = RTW_WLAN_CATEGORY_RADIO_MEAS; - do { - pmlmeinfo->dialogToken++; - } while (pmlmeinfo->dialogToken == 0); - - prm->q.diag_token = pmlmeinfo->dialogToken; - prm->q.m_token = 1; - - prm->rmid = psta->cmn.aid << 16 - | prm->q.diag_token << 8 - | RM_MASTER; + prm->q.diag_token = rm_gen_dialog_token(padapter); + prm->q.m_token = rm_gen_meas_token(padapter); + prm->rmid = rm_gen_rmid(padapter, prm, RM_MASTER); prm->q.action_code = RM_ACT_NB_REP_REQ; @@ -370,8 +364,8 @@ int ready_for_scan(struct rm_obj *prm) int rm_sitesurvey(struct rm_obj *prm) { - int meas_ch_num=0; - u8 ch_num=0, op_class=0, val8; + int meas_ch_amount=0; + u8 op_class=0, val8; struct rtw_ieee80211_channel *pch_set; struct sitesurvey_parm parm; @@ -381,33 +375,40 @@ int rm_sitesurvey(struct rm_obj *prm) pch_set = &prm->q.ch_set[0]; _rtw_memset(pch_set, 0, - sizeof(struct rtw_ieee80211_channel) * MAX_OP_CHANNEL_SET_NUM); + sizeof(struct rtw_ieee80211_channel) * RTW_CHANNEL_SCAN_AMOUNT); + op_class = prm->q.op_class; if (prm->q.ch_num == 0) { /* ch_num=0 : scan all ch in operating class */ - op_class = prm->q.op_class; + meas_ch_amount = rm_get_ch_set(pch_set, + op_class, prm->q.ch_num); } else if (prm->q.ch_num == 255) { - /* 802.11 p.499 */ - /* ch_num=255 : scan all ch in current operating class */ - op_class = rm_get_oper_class_via_ch( - (u8)prm->psta->padapter->mlmeextpriv.cur_channel); + /* 802.11 p.1066 */ + /* ch_num=255 : If the Channel Number is 255 and includes + * AP Channel Report subelements + */ + meas_ch_amount = rm_get_ch_set_from_bcn_req_opt(pch_set, &prm->q.opt.bcn); } else - ch_num = prm->q.ch_num; + meas_ch_amount = rm_get_ch_set(pch_set, op_class, prm->q.ch_num); /* get means channel */ - meas_ch_num = rm_get_ch_set(pch_set, op_class, ch_num); - prm->q.ch_set_ch_amount = meas_ch_num; + prm->q.ch_set_ch_amount = meas_ch_amount; + +#if (RM_MORE_DBG_MSG) + RTW_INFO("survey (%d) chaannels\n", meas_ch_amount); +#endif _rtw_memset(&parm, 0, sizeof(struct sitesurvey_parm)); _rtw_memcpy(parm.ch, pch_set, - sizeof(struct rtw_ieee80211_channel) * MAX_OP_CHANNEL_SET_NUM); + sizeof(struct rtw_ieee80211_channel) * + MIN(meas_ch_amount, RTW_CHANNEL_SCAN_AMOUNT)); _rtw_memcpy(&parm.ssid[0], &prm->q.opt.bcn.ssid, IW_ESSID_MAX_SIZE); parm.ssid_num = 1; parm.scan_mode = prm->q.m_mode; - parm.ch_num = meas_ch_num; + parm.ch_num = meas_ch_amount; parm.igi = 0; parm.token = prm->rmid; parm.duration = prm->q.meas_dur; @@ -501,6 +502,8 @@ static int rm_parse_bcn_req_s_elem(struct rm_obj *prm, u8 *pbody, int req_len) u8 *popt_id; int i, p=0; /* position */ int len = req_len; + int ap_ch_rpt_idx = 0; + struct _RT_OPERATING_CLASS *op; /* opt length,2:pbody[0]+ pbody[1] */ @@ -534,7 +537,6 @@ static int rm_parse_bcn_req_s_elem(struct rm_obj *prm, u8 *pbody, int req_len) &pbody[p+2], pbody[p+1]); #endif #endif - RTW_INFO("RM: bcn_req_ssid=%s\n", prm->q.opt.bcn.ssid.Ssid); @@ -587,11 +589,32 @@ static int rm_parse_bcn_req_s_elem(struct rm_obj *prm, u8 *pbody, int req_len) popt_id[prm->q.opt.bcn.opt_id_num++] = pbody[p]; break; - case bcn_req_ac_ch_rep: + case bcn_req_ap_ch_rep: #if (RM_MORE_DBG_MSG) - RTW_INFO("RM: bcn_req_ac_ch_rep\n"); + RTW_INFO("RM: bcn_req_ap_ch_rep\n"); #endif + if (ap_ch_rpt_idx > BCN_REQ_OPT_AP_CH_RPT_MAX_NUM) { + RTW_ERR("RM: bcn_req_ap_ch_rep over size\n"); + break; + } + popt_id[prm->q.opt.bcn.opt_id_num++] = pbody[p]; + /* get channel list + * EID:len:op-class:ch-list + */ + op = rtw_malloc(sizeof (*op)); + op->global_op_class = pbody[p + 2]; + i = pbody[p + 1] - 1; /* ch list len; (-1) is op class */ + +#if (RM_MORE_DBG_MSG) + RTW_INFO("%d op class %d has %d ch\n", + ap_ch_rpt_idx,op->global_op_class,i); +#endif + op->Len = i; + memcpy(op->Channel, &pbody[p + 3], + MIN(i, MAX_CH_NUM_IN_OP_CLASS)); + prm->q.opt.bcn.ap_ch_rpt[ap_ch_rpt_idx++] = op; + prm->q.opt.bcn.ap_ch_rpt_num = ap_ch_rpt_idx; break; default: @@ -703,10 +726,7 @@ int rm_recv_radio_mens_req(_adapter *padapter, prm->q.m_token = pmeas_body[2]; prm->q.m_mode = pmeas_body[3]; prm->q.m_type = pmeas_body[4]; - - prm->rmid = psta->cmn.aid << 16 - | prm->q.diag_token << 8 - | RM_SLAVE; + prm->rmid = rm_gen_rmid(padapter, prm, RM_SLAVE); RTW_INFO("RM: rmid=%x, bssid " MAC_FMT "\n", prm->rmid, MAC_ARG(prm->psta->cmn.mac_addr)); @@ -766,7 +786,7 @@ done: int rm_recv_radio_mens_rep(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *psta) { - int ret = _FALSE; + int len, ret = _FALSE; struct rm_obj *prm; u32 rmid; u8 *pdiag_body = (u8 *)(precv_frame->u.hdr.rx_data + @@ -779,8 +799,11 @@ int rm_recv_radio_mens_rep(_adapter *padapter, | RM_MASTER; prm = rm_get_rmobj(padapter, rmid); - if (prm == NULL) - return _FALSE; + if (prm == NULL) { + /* not belong to us, report to upper */ + rtw_cfg80211_rx_rrm_action(psta->padapter, precv_frame); + return _TRUE; + } prm->p.action_code = pdiag_body[1]; prm->p.diag_token = pdiag_body[2]; @@ -807,6 +830,13 @@ int rm_recv_radio_mens_rep(_adapter *padapter, RTW_INFO("RM: recv %s\n", rm_type_rep_name(prm->p.m_type)); rm_post_event(padapter, prm->rmid, RM_EV_recv_rep); + /* report to upper via ioctl */ + if ((prm->from_ioctl == true) && + prm->q.m_type == bcn_req) { + len = pmeas_body[1] + 2; /* 2 : EID(1B) length(1B) */ + indicate_beacon_report(prm->psta->cmn.mac_addr, + 1, len, pmeas_body); + } return ret; } @@ -840,10 +870,7 @@ int rm_recv_link_mens_req(_adapter *padapter, prm->q.rx_rate = hw_rate_to_m_rate(precv_frame->u.hdr.attrib.data_rate); prm->q.rx_bw = precv_frame->u.hdr.attrib.bw; prm->q.rx_rsni = rm_get_frame_rsni(prm, precv_frame); - - prm->rmid = psta->cmn.aid << 16 - | prm->q.diag_token << 8 - | RM_SLAVE; + prm->rmid = rm_gen_rmid(padapter, prm, RM_SLAVE); RTW_INFO("RM: rmid=%x, bssid" MAC_FMT " rx_pwr=%ddBm, rate=%s\n", prm->rmid, MAC_ARG(prm->psta->cmn.mac_addr), prm->q.rx_pwr, @@ -879,8 +906,9 @@ int rm_recv_link_mens_rep(_adapter *padapter, prm = rm_get_rmobj(padapter, rmid); if (prm == NULL) { - RTW_ERR("RM: rmid 0x%08x not found\n", rmid); - return ret; + /* not belong to us, report to upper */ + rtw_cfg80211_rx_rrm_action(psta->padapter, precv_frame); + return _TRUE; } RTW_INFO("RM: rmid=%x, bssid " MAC_FMT "\n", prm->rmid, @@ -922,8 +950,12 @@ int rm_radio_mens_nb_rep(_adapter *padapter, | RM_MASTER; prm = rm_get_rmobj(padapter, rmid); - if (prm == NULL) - return _FALSE; + + if (prm == NULL) { + /* not belong to us, report to upper */ + rtw_cfg80211_rx_rrm_action(psta->padapter, precv_frame); + return _TRUE; + } prm->p.action_code = pdiag_body[1]; prm->p.diag_token = pdiag_body[2]; @@ -1108,6 +1140,9 @@ static u8 *rm_gen_bcn_detail_elem(_adapter *padapter, u8 *pframe, continue; #if (RM_MORE_DBG_MSG) switch (eid) { + case EID_SsId: + RTW_INFO("RM: EID_SSID\n"); + break; case EID_QBSSLoad: RTW_INFO("RM: EID_QBSSLoad\n"); break; @@ -1117,16 +1152,24 @@ static u8 *rm_gen_bcn_detail_elem(_adapter *padapter, u8 *pframe, case _MDIE_: RTW_INFO("RM: EID_MobilityDomain\n"); break; + case EID_Vendor: + RTW_INFO("RM: EID_Vendor\n"); + break; default: RTW_INFO("RM: EID %d todo\n",eid); break; } #endif pframe = rtw_set_ie(pframe, eid, - len,ptr+2, &my_len); + len, ptr+2, &my_len); } /* for() */ break; - case bcn_req_ac_ch_rep: + case bcn_req_rep_detail: + RTW_INFO("RM: bcn_req_rep_detail\n"); + break; + case bcn_req_ap_ch_rep: + RTW_INFO("RM: bcn_req_ap_ch_rep\n"); + break; default: RTW_INFO("RM: OPT %d TODO\n",prm->q.opt.bcn.opt_id[j]); break; @@ -1236,7 +1279,10 @@ static u8 *rm_gen_bcn_rep_ie (struct rm_obj *prm, pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len); /* ParentTSF */ - val32 = prm->meas_start_time + pnetwork->network.PhyInfo.free_cnt; + val32 = pnetwork->network.PhyInfo.free_cnt; + if (prm->free_run_counter_valid) + val32 += prm->meas_start_time; + pframe = rtw_set_fixed_ie(pframe, 4, (u8 *)&val32, &my_len); /* Generate Beacon detail */ @@ -1255,6 +1301,99 @@ static u8 *rm_gen_bcn_rep_ie (struct rm_obj *prm, return pframe; } +#if 0 /* check MBO logo */ +static int rm_match_sub_elem(_adapter *padapter, + struct rm_obj *prm, struct wlan_network *pnetwork) +{ + WLAN_BSSID_EX *pbss = &pnetwork->network; + unsigned int my_len; + int j, k, len; + u8 *plen; + u8 *ptr; + u8 val8, eid; + + + my_len = 0; + /* Reporting Detail values + * 0: No fixed length fields or elements + * 1: All fixed length fields and any requested elements + * in the Request info element if present + * 2: All fixed length fields and elements + * 3-255: Reserved + */ + + /* report_detail != 1 */ + if (prm->q.opt.bcn.rep_detail != 1) + return _TRUE; + + /* report_detail = 1 */ + + for (j = 0; j < prm->q.opt.bcn.opt_id_num; j++) { + switch (prm->q.opt.bcn.opt_id[j]) { + case bcn_req_ssid: + /* SSID */ +#if (RM_MORE_DBG_MSG) + RTW_INFO("RM: bcn_req_ssid\n"); +#endif + if (pbss->Ssid.SsidLength == 0) + return _FALSE; + break; + case bcn_req_req: + if (prm->q.opt.bcn.req_start == NULL) + break; +#if (RM_MORE_DBG_MSG) + RTW_INFO("RM: bcn_req_req"); +#endif + for (k=0; kq.opt.bcn.req_len; k++) { + eid = prm->q.opt.bcn.req_start[k]; + + val8 = pbss->IELength - _FIXED_IE_LENGTH_; + ptr = rtw_get_ie(pbss->IEs + _FIXED_IE_LENGTH_, + eid, &len, val8); + +#if (RM_MORE_DBG_MSG) + switch (eid) { + case EID_SsId: + RTW_INFO("RM: EID_SSID\n"); + break; + case EID_QBSSLoad: + RTW_INFO("RM: EID_QBSSLoad\n"); + break; + case EID_HTCapability: + RTW_INFO("RM: EID_HTCapability\n"); + break; + case _MDIE_: + RTW_INFO("RM: EID_MobilityDomain\n"); + break; + case EID_Vendor: + RTW_INFO("RM: EID_Vendor\n"); + break; + default: + RTW_INFO("RM: EID %d todo\n",eid); + break; + } +#endif + if (!ptr) { + RTW_INFO("RM: EID %d not found\n",eid); + return _FALSE; + } + } /* for() */ + break; + case bcn_req_rep_detail: + RTW_INFO("RM: bcn_req_rep_detail\n"); + break; + case bcn_req_ap_ch_rep: + RTW_INFO("RM: bcn_req_ap_ch_rep\n"); + break; + default: + RTW_INFO("RM: OPT %d TODO\n",prm->q.opt.bcn.opt_id[j]); + break; + } + } + return _TRUE; +} +#endif + static int retrieve_scan_result(struct rm_obj *prm) { _irqL irqL; @@ -1264,7 +1403,7 @@ static int retrieve_scan_result(struct rm_obj *prm) struct rtw_ieee80211_channel *pch_set; struct wlan_network *pnetwork = NULL; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - int i, meas_ch_num=0; + int i; PWLAN_BSSID_EX pbss; unsigned int matched_network; int len, my_len; @@ -1287,7 +1426,6 @@ static int retrieve_scan_result(struct rm_obj *prm) /* get requested measurement channel set */ pch_set = prm->q.ch_set; - meas_ch_num = prm->q.ch_set_ch_amount; /* search scan queue to find requested SSID */ while (1) { @@ -1298,88 +1436,98 @@ static int retrieve_scan_result(struct rm_obj *prm) pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); pbss = &pnetwork->network; +#if 0 + RTW_INFO("RM: ooo ch %u ssid %s bssid "MAC_FMT"\n", + pbss->Configuration.DSConfig, pbss->Ssid.Ssid, + MAC_ARG(pbss->MacAddress)); /* * report network if requested channel set contains * the channel matchs selected network */ if (rtw_chset_search_ch(adapter_to_chset(padapter), - pbss->Configuration.DSConfig) == 0) + pbss->Configuration.DSConfig) < 0) /* not match */ goto next; if (rtw_mlme_band_check(padapter, pbss->Configuration.DSConfig) == _FALSE) goto next; - +#endif if (rtw_validate_ssid(&(pbss->Ssid)) == _FALSE) goto next; + /* match bssid */ + if (is_wildcard_bssid(prm->q.bssid) == FALSE) + if (_rtw_memcmp(prm->q.bssid, + pbss->MacAddress, 6) == _FALSE) + //continue; + goto next; + /* + * default wildcard SSID. wildcard SSID: + * A SSID value (null) used to represent all SSIDs + */ + + /* match ssid */ + if ((prm->q.opt.bcn.ssid.SsidLength > 0) && + _rtw_memcmp(prm->q.opt.bcn.ssid.Ssid, + pbss->Ssid.Ssid, + prm->q.opt.bcn.ssid.SsidLength) == _FALSE) + goto next; + /* go through measurement requested channels */ - for (i = 0; i < meas_ch_num; i++) { + for (i = 0; i < prm->q.ch_set_ch_amount; i++) { + if ((pch_set[i].hw_value) == + (pbss->Configuration.DSConfig)) /* match ch */ + break; + } + if (i >= prm->q.ch_set_ch_amount) /* channel mismatch */ + goto next; - /* match channel */ - if (pch_set[i].hw_value != pbss->Configuration.DSConfig) - continue; - - /* match bssid */ - if (is_wildcard_bssid(prm->q.bssid) == FALSE) - if (_rtw_memcmp(prm->q.bssid, - pbss->MacAddress, 6) == _FALSE) { - continue; - } - /* - * default wildcard SSID. wildcard SSID: - * A SSID value (null) used to represent all SSIDs - */ - - /* match ssid */ - if ((prm->q.opt.bcn.ssid.SsidLength > 0) && - _rtw_memcmp(prm->q.opt.bcn.ssid.Ssid, - pbss->Ssid.Ssid, - prm->q.opt.bcn.ssid.SsidLength) == _FALSE) - continue; - - /* match condition */ - if (rm_bcn_req_cond_mach(prm, pnetwork) == _FALSE) { - RTW_INFO("RM: condition mismatch ch %u ssid %s bssid "MAC_FMT"\n", - pch_set[i].hw_value, pbss->Ssid.Ssid, - MAC_ARG(pbss->MacAddress)); - RTW_INFO("RM: condition %u:%u\n", - prm->q.opt.bcn.rep_cond.cond, - prm->q.opt.bcn.rep_cond.threshold); - continue; - } - - /* Found a matched SSID */ - matched_network++; - - RTW_INFO("RM: ch %u Found %s bssid "MAC_FMT"\n", - pch_set[i].hw_value, pbss->Ssid.Ssid, + /* match condition */ + if (rm_bcn_req_cond_mach(prm, pnetwork) == _FALSE) { + RTW_INFO("RM: condition mismatch ch %u ssid %s bssid "MAC_FMT"\n", + pbss->Configuration.DSConfig, pbss->Ssid.Ssid, MAC_ARG(pbss->MacAddress)); + RTW_INFO("RM: condition %u:%u\n", + prm->q.opt.bcn.rep_cond.cond, + prm->q.opt.bcn.rep_cond.threshold); + goto next; + //continue; + } +#if 0 /* check MBO logo */ + /* match subelement */ + if (rm_match_sub_elem(padapter, prm, pnetwork) == _FALSE) + goto next; +#endif + /* Found a matched SSID */ + matched_network++; - len = 0; - _rtw_memset(tmp_buf, 0, MAX_XMIT_EXTBUF_SZ); - rm_gen_bcn_rep_ie(prm, tmp_buf, pnetwork, &len); + RTW_INFO("RM: ch %u Found %s bssid "MAC_FMT"\n", + pbss->Configuration.DSConfig, pbss->Ssid.Ssid, + MAC_ARG(pbss->MacAddress)); + + len = 0; + _rtw_memset(tmp_buf, 0, MAX_XMIT_EXTBUF_SZ); + rm_gen_bcn_rep_ie(prm, tmp_buf, pnetwork, &len); new_packet: - if (my_len == 0) { - pbuf = rtw_malloc(MAX_XMIT_EXTBUF_SZ); - if (pbuf == NULL) - goto fail; - prm->buf[buf_idx].pbuf = pbuf; - } + if (my_len == 0) { + pbuf = rtw_malloc(MAX_XMIT_EXTBUF_SZ); + if (pbuf == NULL) + goto fail; + prm->buf[buf_idx].pbuf = pbuf; + } - if ((MAX_XMIT_EXTBUF_SZ - (my_len+len+24+4)) > 0) { - pbuf = rtw_set_fixed_ie(pbuf, - len, tmp_buf, &my_len); - prm->buf[buf_idx].len = my_len; - } else { - if (my_len == 0) /* not enough space */ - goto fail; + if ((MAX_XMIT_EXTBUF_SZ - (my_len+len+24+4)) > 0) { + pbuf = rtw_set_fixed_ie(pbuf, + len, tmp_buf, &my_len); + prm->buf[buf_idx].len = my_len; + } else { + if (my_len == 0) /* not enough space */ + goto fail; - my_len = 0; - buf_idx++; - goto new_packet; - } - } /* for() */ + my_len = 0; + buf_idx++; + goto new_packet; + } next: plist = get_next(plist); } /* while() */ @@ -1647,17 +1795,96 @@ int issue_link_meas_rep(struct rm_obj *prm) } static u8 *rm_gen_bcn_req_s_elem(_adapter *padapter, - u8 *pframe, unsigned int *fr_len) + struct rm_obj *prm, u8 *pframe, unsigned int *fr_len) { - u8 val8; + u8 val8, l; + int i; unsigned int my_len = 0; - u8 bssid[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - + struct _RT_OPERATING_CLASS *op; + /* meas mode */ val8 = bcn_req_active; /* measurement mode T8-64 */ pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len); - pframe = rtw_set_fixed_ie(pframe, 6, bssid, &my_len); + /* bssid */ + pframe = rtw_set_fixed_ie(pframe, 6, prm->q.bssid, &my_len); + + /* + * opt ssid (0) + */ + l = MIN(32, (int)prm->q.opt.bcn.ssid.SsidLength); + + l = (int)prm->q.opt.bcn.ssid.SsidLength; + + if (l > 32) + RTW_ERR("RM: %s SSID len over size %d! skip it!\n",__func__, l); + + if (l > 0 && l <= 32) { + /* Type */ + val8 = bcn_req_ssid; + pframe = rtw_set_fixed_ie(pframe, 1, + &val8, &my_len); + /* Len */ + pframe = rtw_set_fixed_ie(pframe, 1, + &l, &my_len); + /* Value */ + pframe = rtw_set_fixed_ie(pframe, l, + prm->q.opt.bcn.ssid.Ssid, &my_len); + } + + /* + * opt reporting detail (2) + */ + /* Type */ + val8 = bcn_req_rep_detail; + pframe = rtw_set_fixed_ie(pframe, 1, + &val8, &my_len); + /* Len */ + l = 1; + pframe = rtw_set_fixed_ie(pframe, 1, + &l, &my_len); + /* Value */ + pframe = rtw_set_fixed_ie(pframe, l, + &prm->q.opt.bcn.rep_detail, &my_len); + + /* + * opt request (10) + */ + + if (prm->q.opt.bcn.req_id_num > 0) { + /* Type */ + val8 = bcn_req_req; + pframe = rtw_set_fixed_ie(pframe, 1, + &val8, &my_len); + /* Len */ + l = prm->q.opt.bcn.req_id_num; + pframe = rtw_set_fixed_ie(pframe, 1, + &l, &my_len); + /* Value */ + pframe = rtw_set_fixed_ie(pframe, l, + prm->q.opt.bcn.req_id, &my_len); + } + + /* + * opt ap channel report (51) + */ + for (i = 0; i < prm->q.opt.bcn.ap_ch_rpt_num; i++) { + op = prm->q.opt.bcn.ap_ch_rpt[i]; + if (op == NULL) + break; + /* Type */ + val8 = bcn_req_ap_ch_rep; + pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len); + l = (u8)op->Len + 1; + /* length */ + pframe = rtw_set_fixed_ie(pframe, 1, &l, &my_len); + + /* op class */ + val8 = op->global_op_class; + pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len); + /* channel */ + pframe = rtw_set_fixed_ie(pframe, op->Len, op->Channel, &my_len); + } /* update length to caller */ *fr_len += my_len; @@ -1738,6 +1965,8 @@ int issue_radio_meas_req(struct rm_obj *prm) } pattr = &pmgntframe->attrib; pframe = build_wlan_hdr(padapter, pmgntframe, prm->psta, WIFI_ACTION); + + /* Category, Action code, Dialog token */ pframe = rtw_set_fixed_ie(pframe, 3, &prm->q.category, &pattr->pktlen); /* repeat */ @@ -1747,22 +1976,21 @@ int issue_radio_meas_req(struct rm_obj *prm) my_len = 0; plen = pframe + 1; + /* Element ID, Length, Meas token, Meas Mode, Meas type, op class, ch */ pframe = rtw_set_fixed_ie(pframe, 7, &prm->q.e_id, &my_len); /* random interval */ - val16 = 100; /* 100 TU */ - val16 = cpu_to_le16(val16); + val16 = cpu_to_le16(prm->q.rand_intvl); /* TU */ pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&val16, &my_len); /* measurement duration */ - val16 = 100; - val16 = cpu_to_le16(val16); + val16 = cpu_to_le16(prm->q.meas_dur); pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&val16, &my_len); /* optional subelement */ switch (prm->q.m_type) { case bcn_req: - pframe = rm_gen_bcn_req_s_elem(padapter, pframe, &my_len); + pframe = rm_gen_bcn_req_s_elem(padapter, prm, pframe, &my_len); break; case ch_load_req: pframe = rm_gen_ch_load_req_s_elem(padapter, pframe, &my_len); @@ -1804,9 +2032,11 @@ int rm_radio_meas_report_cond(struct rm_obj *prm) case ch_load_cond_anpi_equal_greater: if (val8 >= prm->q.opt.clm.rep_cond.threshold) return _SUCCESS; + break; case ch_load_cond_anpi_equal_less: if (val8 <= prm->q.opt.clm.rep_cond.threshold) return _SUCCESS; + break; default: break; } @@ -2116,7 +2346,6 @@ done: static int rm_dbg_modify_meas(_adapter *padapter, char *s) { struct rm_priv *prmpriv = &padapter->rmpriv; - struct mlme_ext_info *pmlmeinfo = &padapter->mlmeextpriv.mlmext_info; struct rm_obj *prm; struct sta_info *psta; char *pmac, *ptr, *paid, *prpt, *pnbp, *pclm, *pnhm, *pbcn, *plnk; @@ -2147,7 +2376,7 @@ static int rm_dbg_modify_meas(_adapter *padapter, char *s) } } prm = (struct rm_obj *)prmpriv->prm_sel; - prm->q.m_token = 1; + prm->q.m_token = rm_gen_meas_token(padapter); psta = prm->psta; if (paid) { /* find sta_info according to aid */ @@ -2166,26 +2395,16 @@ static int rm_dbg_modify_meas(_adapter *padapter, char *s) if (psta) { prm->psta = psta; - -#if 0 - prm->q.diag_token = psta->rm_diag_token++; -#else - /* TODO dialog should base on sta_info */ - do { - pmlmeinfo->dialogToken++; - } while (pmlmeinfo->dialogToken == 0); - - prm->q.diag_token = pmlmeinfo->dialogToken; -#endif - prm->rmid = psta->cmn.aid << 16 - | prm->q.diag_token << 8 - | RM_MASTER; + prm->q.diag_token = rm_gen_dialog_token(padapter); + prm->rmid = rm_gen_rmid(padapter, prm, RM_MASTER); } else return _FAIL; prm->q.action_code = RM_ACT_RADIO_MEAS_REQ; if (pbcn) { prm->q.m_type = bcn_req; + prm->q.rand_intvl = le16_to_cpu(100); + prm->q.meas_dur = le16_to_cpu(100); } else if (pnhm) { prm->q.m_type = noise_histo_req; } else if (pclm) { @@ -2242,6 +2461,108 @@ static void rm_dbg_activate_meas(_adapter *padapter, char *s) prmpriv->prm_sel = NULL; } +/* for ioctl */ +int rm_send_bcn_reqs(_adapter *padapter, u8 *sta_addr, u8 op_class, u8 ch, + u16 measure_duration, u8 measure_mode, u8 *bssid, u8 *ssid, + u8 reporting_detail, + u8 n_ap_ch_rpt, struct _RT_OPERATING_CLASS *rpt, + u8 n_elem_id, u8 *elem_id_list) + +{ + struct rm_obj *prm; + char *pact; + struct sta_info *psta; + struct _RT_OPERATING_CLASS *prpt; + void *ptr; + int i,j,sz; + u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + + if (n_ap_ch_rpt > BCN_REQ_OPT_AP_CH_RPT_MAX_NUM) { + RTW_ERR("RM: chset num %d > %d\n", + n_ap_ch_rpt, BCN_REQ_OPT_AP_CH_RPT_MAX_NUM); + return -1; + } + /* dest sta */ + psta = rtw_get_stainfo(&padapter->stapriv, sta_addr); + if (!psta) { + RTW_ERR("RM: psta not found\n"); + return -2; + } + prm = rm_alloc_rmobj(padapter); + if (prm == NULL) { + RTW_ERR("RM: unable to alloc rm obj for requeset\n"); + return -3; + } + + prm->psta = psta; + prm->q.meas_dur = measure_duration; + + /* Figure 8-104 Measurement Requested format */ + prm->q.category = RTW_WLAN_CATEGORY_RADIO_MEAS; + prm->q.action_code = RM_ACT_RADIO_MEAS_REQ; + prm->q.m_mode = measure_mode; + prm->q.m_type = bcn_req; + prm->q.diag_token = rm_gen_dialog_token(padapter); + prm->q.m_token = rm_gen_meas_token(padapter); + prm->rmid = rm_gen_rmid(padapter, prm, RM_MASTER); + + prm->q.e_id = _MEAS_REQ_IE_; /* 38 */ + prm->q.ch_num = ch; + prm->q.op_class = op_class; + prm->from_ioctl = true; + + if (bssid != NULL) + memcpy(prm->q.bssid, bssid, ETH_ALEN); + else + memcpy(prm->q.bssid, bcast, ETH_ALEN); + + if (ssid != NULL) { + i = MIN(32, strlen(ssid)); + prm->q.opt.bcn.ssid.SsidLength = i; + memcpy(prm->q.opt.bcn.ssid.Ssid, ssid, i); + } + + if (n_ap_ch_rpt > 0) { + prm->q.opt.bcn.ap_ch_rpt_num = n_ap_ch_rpt; + j = 0; + for (i = 0; i < n_ap_ch_rpt; i++) { + prpt = rpt++; + if (prpt == NULL) + break; + + sz = sizeof(struct _RT_OPERATING_CLASS) * prpt->Len; + ptr = rtw_malloc(sz); + _rtw_memcpy(ptr, prpt, sz); + prm->q.opt.bcn.ap_ch_rpt[i] = (struct _RT_OPERATING_CLASS *)ptr; + } + } + prm->q.opt.bcn.rep_detail = reporting_detail; + + if ((n_elem_id > 0) && (n_elem_id < BCN_REQ_REQ_OPT_MAX_NUM)) { + prm->q.opt.bcn.req_id_num = n_elem_id; + _rtw_memcpy(prm->q.opt.bcn.req_id, elem_id_list, n_elem_id); + } + /* enquee rmobj */ + rm_enqueue_rmobj(padapter, prm, _FALSE); + + RTW_INFO("\nAdd rmid=%x, meas_type=%s ok\n", + prm->rmid, rm_type_req_name(prm->q.m_type)); + + if (prm->psta) + RTW_INFO("mac="MAC_FMT"\n", MAC_ARG(prm->psta->cmn.mac_addr)); + return 0; +} + +void indicate_beacon_report(u8 *sta_addr, + u8 n_measure_rpt, u32 elem_len, u8 *elem) +{ + RTW_INFO("RM: recv bcn reprot from mac="MAC_FMT"\n", MAC_ARG(sta_addr)); +#ifdef CONFIG_PLATFORM_CMAP_INTFS + cmap_intfs_nl_beacon_report_event(sta_addr, n_measure_rpt, elem_len, elem); +#endif +} + static void rm_dbg_add_meas(_adapter *padapter, char *s) { struct rm_priv *prmpriv = &(padapter->rmpriv); @@ -2411,6 +2732,37 @@ static void rm_dbg_list_meas(_adapter *padapter, char *s) } #endif /* RM_SUPPORT_IWPRIV_DBG */ +int verify_bcn_req(_adapter *padapter, struct sta_info *psta) +{ + char *bssid = NULL; + char ssid[] = "RealKungFu"; + u8 op_class = 0; + u8 ch = 255; + u16 measure_duration = 100; + u8 reporting_detaial = 0; + u8 n_ap_ch_rpt = 6; + u8 measure_mode = bcn_req_active; + u8 req[] = {1,2,3}; + u8 req_len = sizeof(req); + + + static RT_OPERATING_CLASS US[] = { + /* 0, OP_CLASS_NULL */ //{ 0, 0, {}}, + /* 1, OP_CLASS_1 */ {115, 4, {36, 40, 44, 48}}, + /* 2, OP_CLASS_2 */ {118, 4, {52, 56, 60, 64}}, + /* 3, OP_CLASS_3 */ {124, 4, {149, 153, 157, 161}}, + /* 4, OP_CLASS_4 */ {121, 11, {100, 104, 108, 112, 116, 120, 124, + 128, 132, 136, 140}}, + /* 5, OP_CLASS_5 */ {125, 5, {149, 153, 157, 161, 165}}, + /* 6, OP_CLASS_12 */ { 81, 11, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}} + }; + + rm_send_bcn_reqs(padapter, psta->cmn.mac_addr, op_class, ch, + measure_duration, measure_mode, bssid, ssid, + reporting_detaial, n_ap_ch_rpt, US, req_len, req); + return 0; +} + void rm_dbg_cmd(_adapter *padapter, char *s) { unsigned val; @@ -2421,6 +2773,19 @@ void rm_dbg_cmd(_adapter *padapter, char *s) if (_rtw_memcmp(s, "help", 4)) { rm_dbg_help(padapter, s); + } else if (_rtw_memcmp(s, "send_bcn_req", 12)) { + + /* rtwpriv wls1 rrm send_bcn_req aid=1 */ + paid = strstr(s, "aid="); + if (paid) { /* find sta_info according to aid */ + paid += 4; /* skip aid= */ + sscanf(paid, "%u", &val); /* aid=x */ + psta = rm_get_sta(padapter, val, NULL); + + if (psta) + verify_bcn_req(padapter, psta); + } + } else if (_rtw_memcmp(s, "list_sta", 8)) { rm_dbg_list_sta(padapter, s); diff --git a/core/rtw_rm_fsm.c b/core/rtw_rm_fsm.c index 9bc2493..244b799 100644 --- a/core/rtw_rm_fsm.c +++ b/core/rtw_rm_fsm.c @@ -122,6 +122,7 @@ int rtw_init_rm(_adapter *padapter) padapter, rm_timer_callback, padapter); _set_timer(&prmpriv->rm_timer, CLOCK_UNIT); + prmpriv->meas_token = 1; return _SUCCESS; } @@ -387,7 +388,7 @@ u8 rtw_rm_post_envent_cmd(_adapter *padapter, u32 rmid, u8 evid) pev->rmid = rmid; pev->evid = evid; - init_h2fwcmd_w_parm_no_rsp(pcmd, pev, GEN_CMD_CODE(_RM_POST_EVENT)); + init_h2fwcmd_w_parm_no_rsp(pcmd, pev, CMD_RM_POST_EVENT); res = rtw_enqueue_cmd(pcmdpriv, pcmd); exit: return res; @@ -668,8 +669,9 @@ static int rm_state_do_meas(struct rm_obj *prm, enum RM_EV_ID evid) switch (prm->q.m_type) { case bcn_req: val8 = 1; /* Enable free run counter */ - rtw_hal_set_hwreg(padapter, - HW_VAR_FREECNT, &val8); + prm->free_run_counter_valid = rtw_hal_set_hwreg( + padapter, HW_VAR_FREECNT, &val8); + rm_sitesurvey(prm); break; case ch_load_req: diff --git a/core/rtw_rm_util.c b/core/rtw_rm_util.c index 7e49c88..b0c2428 100644 --- a/core/rtw_rm_util.c +++ b/core/rtw_rm_util.c @@ -65,6 +65,29 @@ done: return ch_amount; } +u8 rm_get_ch_set_from_bcn_req_opt( + struct rtw_ieee80211_channel *pch_set, struct bcn_req_opt *opt) +{ + int i,j,k,sz; + struct _RT_OPERATING_CLASS *ap_ch_rpt; + u8 ch_amount = 0; + + k = 0; + for (i = 0; i < opt->ap_ch_rpt_num; i++) { + if (opt->ap_ch_rpt[i] == NULL) + break; + ap_ch_rpt = opt->ap_ch_rpt[i]; + for (j = 0; j < ap_ch_rpt->Len; j++) { + pch_set[k].hw_value = + ap_ch_rpt->Channel[j]; + RTW_INFO("RM: meas_ch[%d].hw_value = %u\n", + j, pch_set[k].hw_value); + k++; + } + } + return k; +} + u8 rm_get_oper_class_via_ch(u8 ch) { int i,j,sz; @@ -124,16 +147,20 @@ u8 rm_get_bcn_rcpi(struct rm_obj *prm, struct wlan_network *pnetwork) u8 rm_get_frame_rsni(struct rm_obj *prm, union recv_frame *pframe) { int i; - u8 val8, snr; - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(prm->psta->padapter); + u8 val8, snr, rx_num; + struct hal_spec_t *hal_spec = GET_HAL_SPEC(prm->psta->padapter); if (IS_CCK_RATE((hw_rate_to_m_rate(pframe->u.hdr.attrib.data_rate)))) val8 = 255; else { - snr = 0; - for (i = 0; i < pHalData->NumTotalRFPath; i++) - snr += pframe->u.hdr.attrib.phy_info.rx_snr[i]; - snr = snr / pHalData->NumTotalRFPath; + snr = rx_num = 0; + for (i = 0; i < hal_spec->rf_reg_path_num; i++) { + if (GET_HAL_RX_PATH_BMP(prm->psta->padapter) & BIT(i)) { + snr += pframe->u.hdr.attrib.phy_info.rx_snr[i]; + rx_num++; + } + } + snr = snr / rx_num; val8 = (u8)(snr + 10)*2; } return val8; @@ -142,20 +169,22 @@ u8 rm_get_frame_rsni(struct rm_obj *prm, union recv_frame *pframe) u8 rm_get_bcn_rsni(struct rm_obj *prm, struct wlan_network *pnetwork) { int i; - u8 val8, snr; - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(prm->psta->padapter); - + u8 val8, snr, rx_num; + struct hal_spec_t *hal_spec = GET_HAL_SPEC(prm->psta->padapter); if (pnetwork->network.PhyInfo.is_cck_rate) { /* current HW doesn't have CCK RSNI */ /* 255 indicates RSNI is unavailable */ val8 = 255; } else { - snr = 0; - for (i = 0; i < pHalData->NumTotalRFPath; i++) { - snr += pnetwork->network.PhyInfo.rx_snr[i]; + snr = rx_num = 0; + for (i = 0; i < hal_spec->rf_reg_path_num; i++) { + if (GET_HAL_RX_PATH_BMP(prm->psta->padapter) & BIT(i)) { + snr += pnetwork->network.PhyInfo.rx_snr[i]; + rx_num++; + } } - snr = snr / pHalData->NumTotalRFPath; + snr = snr / rx_num; val8 = (u8)(snr + 10)*2; } return val8; @@ -425,4 +454,48 @@ int rm_get_path_a_max_tx_power(_adapter *adapter, s8 *path_a) return 0; } +u8 rm_gen_dialog_token(_adapter *padapter) +{ + struct rm_priv *prmpriv = &(padapter->rmpriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + + do { + pmlmeinfo->dialogToken++; + } while (pmlmeinfo->dialogToken == 0); + + return pmlmeinfo->dialogToken; +} + +u8 rm_gen_meas_token(_adapter *padapter) +{ + struct rm_priv *prmpriv = &(padapter->rmpriv); + + do { + prmpriv->meas_token++; + } while (prmpriv->meas_token == 0); + + return prmpriv->meas_token; +} + +u32 rm_gen_rmid(_adapter *padapter, struct rm_obj *prm, u8 role) +{ + u32 rmid; + + if (prm->psta == NULL) + goto err; + + if (prm->q.diag_token == 0) + goto err; + + rmid = prm->psta->cmn.aid << 16 + | prm->q.diag_token << 8 + | role; + + return rmid; +err: + RTW_ERR("RM: unable to gen rmid\n"); + return 0; +} + #endif /* CONFIG_RTW_80211K */ diff --git a/core/rtw_roch.c b/core/rtw_roch.c new file mode 100644 index 0000000..2674fe6 --- /dev/null +++ b/core/rtw_roch.c @@ -0,0 +1,591 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2020 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#include + +#ifdef CONFIG_IOCTL_CFG80211 +u8 rtw_roch_stay_in_cur_chan(_adapter *padapter) +{ + int i; + _adapter *iface; + struct mlme_priv *pmlmepriv; + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + u8 rst = _FALSE; + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (iface) { + pmlmepriv = &iface->mlmepriv; + + if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS | WIFI_UNDER_KEY_HANDSHAKE) == _TRUE) { + RTW_INFO(ADPT_FMT"- WIFI_UNDER_LINKING |WIFI_UNDER_WPS | WIFI_UNDER_KEY_HANDSHAKE (mlme state:0x%x)\n", + ADPT_ARG(iface), get_fwstate(&iface->mlmepriv)); + rst = _TRUE; + break; + } + #ifdef CONFIG_AP_MODE + if (MLME_IS_AP(iface) || MLME_IS_MESH(iface)) { + if (rtw_ap_sta_states_check(iface) == _TRUE) { + rst = _TRUE; + break; + } + } + #endif + } + } + + return rst; +} + +static int rtw_ro_ch_handler(_adapter *adapter, u8 *buf) +{ + int ret = H2C_SUCCESS; + struct rtw_roch_parm *roch_parm = (struct rtw_roch_parm *)buf; + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); + struct roch_info *prochinfo = &adapter->rochinfo; +#ifdef CONFIG_CONCURRENT_MODE + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; +#endif + u8 ready_on_channel = _FALSE; + u8 remain_ch; + unsigned int duration; + + _enter_critical_mutex(&pwdev_priv->roch_mutex, NULL); + + if (rtw_cfg80211_get_is_roch(adapter) != _TRUE) + goto exit; + + remain_ch = (u8)ieee80211_frequency_to_channel(roch_parm->ch.center_freq); + duration = roch_parm->duration; + + RTW_INFO(FUNC_ADPT_FMT" ch:%u duration:%d, cookie:0x%llx\n" + , FUNC_ADPT_ARG(adapter), remain_ch, roch_parm->duration, roch_parm->cookie); + + if (roch_parm->wdev && roch_parm->cookie) { + if (prochinfo->ro_ch_wdev != roch_parm->wdev) { + RTW_WARN(FUNC_ADPT_FMT" ongoing wdev:%p, wdev:%p\n" + , FUNC_ADPT_ARG(adapter), prochinfo->ro_ch_wdev, roch_parm->wdev); + rtw_warn_on(1); + } + + if (prochinfo->remain_on_ch_cookie != roch_parm->cookie) { + RTW_WARN(FUNC_ADPT_FMT" ongoing cookie:0x%llx, cookie:0x%llx\n" + , FUNC_ADPT_ARG(adapter), prochinfo->remain_on_ch_cookie, roch_parm->cookie); + rtw_warn_on(1); + } + } + + if (rtw_roch_stay_in_cur_chan(adapter) == _TRUE) { + remain_ch = rtw_mi_get_union_chan(adapter); + RTW_INFO(FUNC_ADPT_FMT" stay in union ch:%d\n", FUNC_ADPT_ARG(adapter), remain_ch); + } + + #ifdef CONFIG_CONCURRENT_MODE + if (rtw_mi_check_status(adapter, MI_LINKED) && (0 != rtw_mi_get_union_chan(adapter))) { + if ((remain_ch != rtw_mi_get_union_chan(adapter)) && !check_fwstate(&adapter->mlmepriv, WIFI_ASOC_STATE)) { + if (remain_ch != pmlmeext->cur_channel + #ifdef RTW_ROCH_BACK_OP + || ATOMIC_READ(&pwdev_priv->switch_ch_to) == 1 + #endif + ) { + rtw_leave_opch(adapter); + + #ifdef RTW_ROCH_BACK_OP + RTW_INFO("%s, set switch ch timer, duration=%d\n", __func__, prochinfo->max_away_dur); + ATOMIC_SET(&pwdev_priv->switch_ch_to, 0); + /* remain_ch is not same as union channel. duration is max_away_dur to + * back to AP's channel. + */ + _set_timer(&prochinfo->ap_roch_ch_switch_timer, prochinfo->max_away_dur); + #endif + } + } + ready_on_channel = _TRUE; + } else + #endif /* CONFIG_CONCURRENT_MODE */ + { + if (remain_ch != rtw_get_oper_ch(adapter)) + ready_on_channel = _TRUE; + } + + if (ready_on_channel == _TRUE) { + #ifndef RTW_SINGLE_WIPHY + if (!check_fwstate(&adapter->mlmepriv, WIFI_ASOC_STATE)) + #endif + { + #ifdef CONFIG_CONCURRENT_MODE + if (rtw_get_oper_ch(adapter) != remain_ch) + #endif + { + /* if (!padapter->mlmepriv.LinkDetectInfo.bBusyTraffic) */ + set_channel_bwmode(adapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + } + } + } + + #ifdef CONFIG_BT_COEXIST + rtw_btcoex_ScanNotify(adapter, _TRUE); + #endif + + RTW_INFO("%s, set ro ch timer, duration=%d\n", __func__, duration); + _set_timer(&prochinfo->remain_on_ch_timer, duration); + +exit: + _exit_critical_mutex(&pwdev_priv->roch_mutex, NULL); + + return ret; +} + +static int rtw_cancel_ro_ch_handler(_adapter *padapter, u8 *buf) +{ + int ret = H2C_SUCCESS; + struct rtw_roch_parm *roch_parm = (struct rtw_roch_parm *)buf; + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); + struct roch_info *prochinfo = &padapter->rochinfo; + struct wireless_dev *wdev; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; +#endif + u8 ch, bw, offset; + + _enter_critical_mutex(&pwdev_priv->roch_mutex, NULL); + + if (rtw_cfg80211_get_is_roch(padapter) != _TRUE) + goto exit; + + if (roch_parm->wdev && roch_parm->cookie) { + if (prochinfo->ro_ch_wdev != roch_parm->wdev) { + RTW_WARN(FUNC_ADPT_FMT" ongoing wdev:%p, wdev:%p\n" + , FUNC_ADPT_ARG(padapter), prochinfo->ro_ch_wdev, roch_parm->wdev); + rtw_warn_on(1); + } + + if (prochinfo->remain_on_ch_cookie != roch_parm->cookie) { + RTW_WARN(FUNC_ADPT_FMT" ongoing cookie:0x%llx, cookie:0x%llx\n" + , FUNC_ADPT_ARG(padapter), prochinfo->remain_on_ch_cookie, roch_parm->cookie); + rtw_warn_on(1); + } + } + +#if defined(RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE) + _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer); + ATOMIC_SET(&pwdev_priv->switch_ch_to, 1); +#endif + + if (rtw_mi_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { + if (0) + RTW_INFO(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); +#ifdef CONFIG_P2P + } else if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->listen_channel) { + ch = pwdinfo->listen_channel; + bw = CHANNEL_WIDTH_20; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + if (0) + RTW_INFO(FUNC_ADPT_FMT" back to listen ch - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); +#endif + } else { + ch = prochinfo->restore_channel; + bw = CHANNEL_WIDTH_20; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + if (0) + RTW_INFO(FUNC_ADPT_FMT" back to restore ch - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); + } + + set_channel_bwmode(padapter, ch, offset, bw); + rtw_back_opch(padapter); +#ifdef CONFIG_P2P + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); +#ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo)); +#endif +#endif + + wdev = prochinfo->ro_ch_wdev; + + rtw_cfg80211_set_is_roch(padapter, _FALSE); + prochinfo->ro_ch_wdev = NULL; + rtw_cfg80211_set_last_ro_ch_time(padapter); + + rtw_cfg80211_remain_on_channel_expired(wdev + , prochinfo->remain_on_ch_cookie + , &prochinfo->remain_on_ch_channel + , prochinfo->remain_on_ch_type, GFP_KERNEL); + + RTW_INFO("cfg80211_remain_on_channel_expired cookie:0x%llx\n" + , prochinfo->remain_on_ch_cookie); + +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_ScanNotify(padapter, _FALSE); +#endif + +exit: + _exit_critical_mutex(&pwdev_priv->roch_mutex, NULL); + + return ret; +} + +static void rtw_ro_ch_timer_process(void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + + rtw_cancel_roch_cmd(adapter, 0, NULL, 0); +} +#endif /* CONFIG_IOCTL_CFG80211 */ + +#if (defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)) || defined(CONFIG_IOCTL_CFG80211) +s32 rtw_roch_wk_hdl(_adapter *padapter, int intCmdType, u8 *buf) +{ + int ret = H2C_SUCCESS; + + switch (intCmdType) { + +#ifdef CONFIG_IOCTL_CFG80211 + case ROCH_RO_CH_WK: + ret = rtw_ro_ch_handler(padapter, buf); + break; + case ROCH_CANCEL_RO_CH_WK: + ret = rtw_cancel_ro_ch_handler(padapter, buf); + break; +#endif + +#ifdef CONFIG_CONCURRENT_MODE + case ROCH_AP_ROCH_CH_SWITCH_PROCESS_WK: + rtw_concurrent_handler(padapter); + break; +#endif + + default: + rtw_warn_on(1); + break; + } + + return ret; +} + +static int get_roch_parm_size(struct rtw_roch_parm *roch_parm) +{ +#ifdef CONFIG_IOCTL_CFG80211 + return (roch_parm ? sizeof(*roch_parm) : 0); +#else + rtw_warn_on(roch_parm); + return 0; +#endif +} + +u8 rtw_roch_wk_cmd(_adapter *padapter, int intCmdType, struct rtw_roch_parm *roch_parm, u8 flags) +{ + struct cmd_obj *ph2c = NULL; + struct drvextra_cmd_parm *pdrvextra_cmd_parm = NULL; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + struct submit_ctx sctx; + u8 res = _SUCCESS; + + if (flags & RTW_CMDF_DIRECTLY) { + /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ + if (H2C_SUCCESS != rtw_roch_wk_hdl(padapter, intCmdType, (u8 *)roch_parm)) + res = _FAIL; + goto free_parm; + } else { + ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); + if (!ph2c) { + res = _FAIL; + goto free_parm; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if (!pdrvextra_cmd_parm) { + res = _FAIL; + goto free_parm; + } + + pdrvextra_cmd_parm->ec_id = ROCH_WK_CID; + pdrvextra_cmd_parm->type = intCmdType; + pdrvextra_cmd_parm->size = get_roch_parm_size(roch_parm); + pdrvextra_cmd_parm->pbuf = (u8 *)roch_parm; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); + + if (flags & RTW_CMDF_WAIT_ACK) { + ph2c->sctx = &sctx; + rtw_sctx_init(&sctx, 10 * 1000); + } + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + + if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) { + rtw_sctx_wait(&sctx, __func__); + _enter_critical_mutex(&pcmdpriv->sctx_mutex, NULL); + if (sctx.status == RTW_SCTX_SUBMITTED) + ph2c->sctx = NULL; + _exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL); + if (sctx.status != RTW_SCTX_DONE_SUCCESS) + res = _FAIL; + } + } + + return res; + +free_parm: + if (roch_parm) + rtw_mfree((u8 *)roch_parm, get_roch_parm_size(roch_parm)); + if (ph2c) + rtw_mfree((u8 *)ph2c, sizeof(*ph2c)); + + return res; +} + +#ifdef CONFIG_CONCURRENT_MODE +void rtw_ap_roch_ch_switch_timer_process(void *ctx) +{ + _adapter *adapter = (_adapter *)ctx; +#ifdef CONFIG_IOCTL_CFG80211 + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); +#endif + +#ifdef CONFIG_IOCTL_CFG80211 + ATOMIC_SET(&pwdev_priv->switch_ch_to, 1); +#endif + + rtw_roch_wk_cmd(adapter, ROCH_AP_ROCH_CH_SWITCH_PROCESS_WK, NULL, 0); +} + +static bool chk_need_stay_in_cur_chan(_adapter *padapter) +{ +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + + /* When CONFIG_FULL_CH_IN_P2P_HANDSHAKE is defined and the + * interface is in the P2P_STATE_GONEGO_OK state, do not let the + * interface switch to the listen channel, because the interface will + * switch to the OP channel after the GO negotiation is successful. + */ + if (padapter->registrypriv.full_ch_in_p2p_handshake == 1 && rtw_p2p_chk_state(pwdinfo , P2P_STATE_GONEGO_OK)) { + RTW_INFO("%s, No linked interface now, but go nego ok, do not back to listen channel\n", __func__); + return _TRUE; + } +#endif + + return _FALSE; +} + +static bool chk_driver_interface(_adapter *padapter, u8 driver_interface) +{ +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + + if (pwdinfo->driver_interface == driver_interface) + return _TRUE; +#elif defined(CONFIG_IOCTL_CFG80211) + if (driver_interface == DRIVER_CFG80211) + return _TRUE; +#endif + + return _FALSE; +} + +static u8 get_remain_ch(_adapter *padapter) +{ + struct roch_info *prochinfo = &padapter->rochinfo; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; +#endif + u8 remain_ch; + +#ifdef CONFIG_P2P + remain_ch = pwdinfo->listen_channel; +#elif defined(CONFIG_IOCTL_CFG80211) + if (chk_driver_interface(padapter, DRIVER_CFG80211)) + remain_ch = ieee80211_frequency_to_channel(prochinfo->remain_on_ch_channel.center_freq); + else + rtw_warn_on(1); +#endif + + return remain_ch; +} + +void rtw_concurrent_handler(_adapter *padapter) +{ +#ifdef CONFIG_IOCTL_CFG80211 + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); +#endif + struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); + struct roch_info *prochinfo = &padapter->rochinfo; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + u8 val8; +#endif + u8 remain_ch = get_remain_ch(padapter); + +#ifdef CONFIG_IOCTL_CFG80211 + if (chk_driver_interface(padapter, DRIVER_CFG80211) + && !rtw_cfg80211_get_is_roch(padapter)) + return; +#endif + + if (rtw_mi_check_status(padapter, MI_LINKED)) { + u8 union_ch = rtw_mi_get_union_chan(padapter); + u8 union_bw = rtw_mi_get_union_bw(padapter); + u8 union_offset = rtw_mi_get_union_offset(padapter); + unsigned int duration; + + #ifdef CONFIG_P2P + pwdinfo->operating_channel = union_ch; + #endif + + if (chk_driver_interface(padapter, DRIVER_CFG80211)) { + #ifdef CONFIG_IOCTL_CFG80211 + _enter_critical_mutex(&pwdev_priv->roch_mutex, NULL); + + if (rtw_get_oper_ch(padapter) != union_ch) { + /* Current channel is not AP's channel - switching to AP's channel */ + RTW_INFO("%s, switch ch back to union=%u,%u, %u\n" + , __func__, union_ch, union_bw, union_offset); + set_channel_bwmode(padapter, union_ch, union_offset, union_bw); + rtw_back_opch(padapter); + + /* Now, the driver stays on AP's channel. We should stay on AP's + * channel for min_home_dur (duration) and next switch channel is + * listen channel. + */ + duration = prochinfo->min_home_dur; + } else { + /* Current channel is AP's channel - switching to listen channel */ + RTW_INFO("%s, switch ch to roch=%u\n" + , __func__, remain_ch); + rtw_leave_opch(padapter); + set_channel_bwmode(padapter, + remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + + /* Now, the driver stays on listen channel. We should stay on listen + * channel for max_away_dur (duration) and next switch channel is AP's + * channel. + */ + duration = prochinfo->max_away_dur; + } + + /* set channel switch timer */ + ATOMIC_SET(&pwdev_priv->switch_ch_to, 0); + _set_timer(&prochinfo->ap_roch_ch_switch_timer, duration); + RTW_INFO("%s, set switch ch timer, duration=%d\n", __func__, duration); + + _exit_critical_mutex(&pwdev_priv->roch_mutex, NULL); + #endif + } + #ifdef CONFIG_P2P + else if (chk_driver_interface(padapter, DRIVER_WEXT)) { + if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) { + /* Now, the driver stays on the AP's channel. */ + /* If the pwdinfo->ext_listen_period = 0, that means the P2P listen state is not available on listen channel. */ + if (pwdinfo->ext_listen_period > 0) { + RTW_INFO("[%s] P2P_STATE_IDLE, ext_listen_period = %d\n", __FUNCTION__, pwdinfo->ext_listen_period); + + if (union_ch != pwdinfo->listen_channel) { + rtw_leave_opch(padapter); + set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + } + + rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); + + if (!rtw_mi_check_mlmeinfo_state(padapter, WIFI_FW_AP_STATE)) { + val8 = 1; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + } + /* Todo: To check the value of pwdinfo->ext_listen_period is equal to 0 or not. */ + _set_timer(&prochinfo->ap_roch_ch_switch_timer, pwdinfo->ext_listen_period); + } + + } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) || + rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL) || + (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _FALSE) || + rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ)) { + /* Now, the driver is in the listen state of P2P mode. */ + RTW_INFO("[%s] P2P_STATE_IDLE, ext_listen_interval = %d\n", __FUNCTION__, pwdinfo->ext_listen_interval); + + /* Commented by Albert 2012/11/01 */ + /* If the AP's channel is the same as the listen channel, we should still be in the listen state */ + /* Other P2P device is still able to find this device out even this device is in the AP's channel. */ + /* So, configure this device to be able to receive the probe request frame and set it to listen state. */ + if (union_ch != pwdinfo->listen_channel) { + + set_channel_bwmode(padapter, union_ch, union_offset, union_bw); + if (!rtw_mi_check_status(padapter, MI_AP_MODE)) { + val8 = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + } + rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE); + rtw_back_opch(padapter); + } + + /* Todo: To check the value of pwdinfo->ext_listen_interval is equal to 0 or not. */ + _set_timer(&prochinfo->ap_roch_ch_switch_timer, pwdinfo->ext_listen_interval); + + } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK)) { + /* The driver had finished the P2P handshake successfully. */ + val8 = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + set_channel_bwmode(padapter, union_ch, union_offset, union_bw); + rtw_back_opch(padapter); + + } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) { + val8 = 1; + set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); + } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _TRUE) { + val8 = 1; + set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); + } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ) && pwdinfo->invitereq_info.benable == _TRUE) { + /* + val8 = 1; + set_channel_bwmode(padapter, , HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + */ + } + } + #endif /* CONFIG_P2P */ + } else if (!chk_need_stay_in_cur_chan(padapter)) { + set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + } +} +#endif /* CONFIG_CONCURRENT_MODE */ + +void rtw_init_roch_info(_adapter *padapter) +{ + struct roch_info *prochinfo = &padapter->rochinfo; + + _rtw_memset(prochinfo, 0x00, sizeof(struct roch_info)); + +#ifdef CONFIG_CONCURRENT_MODE + rtw_init_timer(&prochinfo->ap_roch_ch_switch_timer, padapter, rtw_ap_roch_ch_switch_timer_process, padapter); +#ifdef CONFIG_IOCTL_CFG80211 + prochinfo->min_home_dur = 1500; /* min duration for traffic, home_time */ + prochinfo->max_away_dur = 250; /* max acceptable away duration, home_away_time */ +#endif +#endif + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_init_timer(&prochinfo->remain_on_ch_timer, padapter, rtw_ro_ch_timer_process, padapter); +#endif +} +#endif /* (defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)) || defined(CONFIG_IOCTL_CFG80211) */ \ No newline at end of file diff --git a/core/rtw_rson.c b/core/rtw_rson.c index 39b583a..dba8fb7 100644 --- a/core/rtw_rson.c +++ b/core/rtw_rson.c @@ -285,7 +285,9 @@ void rtw_rson_do_disconnect(_adapter *padapter) pdvobj->rson_data.hopcnt = RTW_RSON_HC_NOTREADY; pdvobj->rson_data.connectible = RTW_RSON_DENYCONNECT; pdvobj->rson_data.loading = 0; + #ifdef CONFIG_AP_MODE rtw_mi_tx_beacon_hdl(padapter); + #endif #endif } @@ -311,7 +313,9 @@ void rtw_rson_join_done(_adapter *padapter) pdvobj->rson_data.hopcnt = rson_data.hopcnt + 1; pdvobj->rson_data.connectible = RTW_RSON_ALLOWCONNECT; pdvobj->rson_data.loading = 0; + #ifdef CONFIG_AP_MODE rtw_mi_tx_beacon_hdl(padapter); + #endif #endif } @@ -497,7 +501,7 @@ u8 rtw_rson_scan_wk_cmd(_adapter *padapter, int op) pdrvextra_cmd_parm->size = 0; pdrvextra_cmd_parm->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, ph2c); @@ -535,13 +539,13 @@ void rtw_rson_scan_cmd_hdl(_adapter *padapter, int op) if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) != _TRUE) { int s_ret; - set_fwstate(pmlmepriv, _FW_UNDER_LINKING); + set_fwstate(pmlmepriv, WIFI_UNDER_LINKING); pmlmepriv->to_join = _FALSE; s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv); if (s_ret == _SUCCESS) _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); else if (s_ret == 2) { - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING); rtw_indicate_connect(padapter); } else { RTW_INFO("try_to_join, but select scanning queue fail, to_roam:%d\n", rtw_to_roam(padapter)); @@ -554,13 +558,13 @@ void rtw_rson_scan_cmd_hdl(_adapter *padapter, int op) pmlmepriv->to_join = _TRUE; } else rtw_indicate_disconnect(padapter, 0, _FALSE); - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING); } } } else { if (rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE)) { if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) - && check_fwstate(pmlmepriv, _FW_LINKED)) { + && check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) { if (rtw_select_roaming_candidate(pmlmepriv) == _SUCCESS) { #ifdef CONFIG_RTW_80211R if (rtw_chk_ft_flags(padapter, RTW_FT_OVER_DS_SUPPORTED)) { diff --git a/core/rtw_security.c b/core/rtw_security.c index ba8da61..639e1e5 100644 --- a/core/rtw_security.c +++ b/core/rtw_security.c @@ -15,6 +15,7 @@ #define _RTW_SECURITY_C_ #include +#include static const char *_security_type_str[] = { "N/A", @@ -24,21 +25,52 @@ static const char *_security_type_str[] = { "AES", "WEP104", "SMS4", - "WEP_WPA", - "BIP", + "GCMP", +}; + +static const char *_security_type_bip_str[] = { + "BIP_CMAC_128", + "BIP_GMAC_128", + "BIP_GMAC_256", + "BIP_CMAC_256", }; const char *security_type_str(u8 value) { #ifdef CONFIG_IEEE80211W - if (value <= _BIP_) -#else - if (value <= _WEP_WPA_MIXED_) + if ((_BIP_MAX_ > value) && (value >= _BIP_CMAC_128_)) + return _security_type_bip_str[value & ~_SEC_TYPE_BIT_]; #endif + + if (_CCMP_256_ == value) + return "CCMP_256"; + if (_GCMP_256_ == value) + return "GCMP_256"; + + if (_SEC_TYPE_MAX_ > value) return _security_type_str[value]; + return NULL; } +#ifdef CONFIG_IEEE80211W +u32 security_type_bip_to_gmcs(enum security_type type) +{ + switch (type) { + case _BIP_CMAC_128_: + return WPA_CIPHER_BIP_CMAC_128; + case _BIP_GMAC_128_: + return WPA_CIPHER_BIP_GMAC_128; + case _BIP_GMAC_256_: + return WPA_CIPHER_BIP_GMAC_256; + case _BIP_CMAC_256_: + return WPA_CIPHER_BIP_CMAC_256; + default: + return 0; + } +} +#endif + #ifdef DBG_SW_SEC_CNT #define WEP_SW_ENC_CNT_INC(sec, ra) do {\ if (is_broadcast_mac_addr(ra)) \ @@ -93,6 +125,24 @@ const char *security_type_str(u8 value) else \ sec->aes_sw_dec_cnt_uc++; \ } while (0) + +#define GCMP_SW_ENC_CNT_INC(sec, ra) do {\ + if (is_broadcast_mac_addr(ra)) \ + sec->gcmp_sw_enc_cnt_bc++; \ + else if (is_multicast_mac_addr(ra)) \ + sec->gcmp_sw_enc_cnt_mc++; \ + else \ + sec->gcmp_sw_enc_cnt_uc++; \ + } while (0) + +#define GCMP_SW_DEC_CNT_INC(sec, ra) do {\ + if (is_broadcast_mac_addr(ra)) \ + sec->gcmp_sw_dec_cnt_bc++; \ + else if (is_multicast_mac_addr(ra)) \ + sec->gcmp_sw_dec_cnt_mc++; \ + else \ + sec->gcmp_sw_dec_cnt_uc++; \ + } while (0) #else #define WEP_SW_ENC_CNT_INC(sec, ra) #define WEP_SW_DEC_CNT_INC(sec, ra) @@ -100,6 +150,8 @@ const char *security_type_str(u8 value) #define TKIP_SW_DEC_CNT_INC(sec, ra) #define AES_SW_ENC_CNT_INC(sec, ra) #define AES_SW_DEC_CNT_INC(sec, ra) +#define GCMP_SW_ENC_CNT_INC(sec, ra) +#define GCMP_SW_DEC_CNT_INC(sec, ra) #endif /* DBG_SW_SEC_CNT */ /* *****WEP related***** */ @@ -725,9 +777,9 @@ u32 rtw_tkip_encrypt(_adapter *padapter, u8 *pxmitframe) /* if (stainfo!=NULL) */ { /* - if(!(stainfo->state &_FW_LINKED)) + if(!(stainfo->state &WIFI_ASOC_STATE)) { - RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state); + RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, stainfo->state); return _FAIL; } */ @@ -901,8 +953,7 @@ exit: /* 3 =====AES related===== */ - - +#if (NEW_CRYPTO == 0) #define MAX_MSG_SIZE 2048 /*****************************/ @@ -1532,11 +1583,89 @@ static sint aes_cipher(u8 *key, uint hdrlen, pframe[payload_index++] = chain_buffer[j];/* for (j=0; j<8;j++) message[payload_index++] = chain_buffer[j]; */ return _SUCCESS; } +#endif /* (NEW_CRYPTO == 0) */ + + +#if NEW_CRYPTO +u32 rtw_aes_encrypt(_adapter *padapter, u8 *pxmitframe) +{ + /* Intermediate Buffers */ + struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + sint curfragnum, plen; + u32 prwskeylen; + u8 *pframe; + u8 *prwskey; + u8 hw_hdr_offset = 0; + + u32 res = _SUCCESS; + + if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL) + return _FAIL; + +#ifdef CONFIG_USB_TX_AGGREGATION + hw_hdr_offset = TXDESC_SIZE + + (((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ); +#else +#ifdef CONFIG_TX_EARLY_MODE + hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE; +#else + hw_hdr_offset = TXDESC_OFFSET; +#endif +#endif + + pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset; + + /* start to encrypt each fragment */ + if ((pattrib->encrypt == _AES_) || + (pattrib->encrypt == _CCMP_256_)) { + + if (IS_MCAST(pattrib->ra)) + prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; + else { + prwskey = pattrib->dot118021x_UncstKey.skey; + } + +#ifdef CONFIG_TDLS + { + /* Swencryption */ + struct sta_info *ptdls_sta; + ptdls_sta = rtw_get_stainfo(&padapter->stapriv, &pattrib->dst[0]); + if ((ptdls_sta != NULL) && (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)) { + RTW_INFO("[%s] for tdls link\n", __FUNCTION__); + prwskey = &ptdls_sta->tpk.tk[0]; + } + } +#endif /* CONFIG_TDLS */ + + prwskeylen = (pattrib->encrypt == _CCMP_256_) ? 32 : 16; + + for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { + + if ((curfragnum + 1) == pattrib->nr_frags) { /* the last fragment */ + plen = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; + + _rtw_ccmp_encrypt(padapter, prwskey, prwskeylen, pattrib->hdrlen, pframe, plen); + } else { + plen = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; + + _rtw_ccmp_encrypt(padapter, prwskey, prwskeylen, pattrib->hdrlen, pframe, plen); + pframe += pxmitpriv->frag_len; + pframe = (u8 *)RND4((SIZE_PTR)(pframe)); + + } + } + + AES_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra); + + } - - + return res; +} +#else u32 rtw_aes_encrypt(_adapter *padapter, u8 *pxmitframe) { /* exclude ICV */ @@ -1575,7 +1704,7 @@ u32 rtw_aes_encrypt(_adapter *padapter, u8 *pxmitframe) pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset; /* 4 start to encrypt each fragment */ - if (pattrib->encrypt == _AES_) { + if ((pattrib->encrypt == _AES_)) { /* if(pattrib->psta) { @@ -1590,9 +1719,9 @@ u32 rtw_aes_encrypt(_adapter *padapter, u8 *pxmitframe) /* if (stainfo!=NULL) */ { /* - if(!(stainfo->state &_FW_LINKED)) + if(!(stainfo->state &WIFI_ASOC_STATE)) { - RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state); + RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, stainfo->state); return _FAIL; } */ @@ -1648,7 +1777,9 @@ u32 rtw_aes_encrypt(_adapter *padapter, u8 *pxmitframe) return res; } +#endif +#if (NEW_CRYPTO == 0) static sint aes_decipher(u8 *key, uint hdrlen, u8 *pframe, uint plen) { @@ -1908,7 +2039,100 @@ static sint aes_decipher(u8 *key, uint hdrlen, } return res; } +#endif /* (NEW_CRYPTO == 0) */ +#if NEW_CRYPTO +u32 rtw_aes_decrypt(_adapter *padapter, u8 *precvframe) +{ + struct sta_info *stainfo; + struct rx_pkt_attrib *prxattrib = &((union recv_frame *)precvframe)->u.hdr.attrib; + struct security_priv *psecuritypriv = &padapter->securitypriv; + u8 *pframe; + u8 *prwskey; + u32 res = _SUCCESS; + + pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data; + /* start to encrypt each fragment */ + if ((prxattrib->encrypt == _AES_) || + (prxattrib->encrypt == _CCMP_256_)) { + + stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]); + if (stainfo != NULL) { + + if (IS_MCAST(prxattrib->ra)) { + static systime start = 0; + static u32 no_gkey_bc_cnt = 0; + static u32 no_gkey_mc_cnt = 0; + + if ((!MLME_IS_MESH(padapter) && psecuritypriv->binstallGrpkey == _FALSE) + #ifdef CONFIG_RTW_MESH + || !(stainfo->gtk_bmp | BIT(prxattrib->key_index)) + #endif + ) { + res = _FAIL; + + if (start == 0) + start = rtw_get_current_time(); + + if (is_broadcast_mac_addr(prxattrib->ra)) + no_gkey_bc_cnt++; + else + no_gkey_mc_cnt++; + + if (rtw_get_passing_time_ms(start) > 1000) { + if (no_gkey_bc_cnt || no_gkey_mc_cnt) { + RTW_PRINT(FUNC_ADPT_FMT" no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n", + FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt); + } + start = rtw_get_current_time(); + no_gkey_bc_cnt = 0; + no_gkey_mc_cnt = 0; + } + + goto exit; + } + + if (no_gkey_bc_cnt || no_gkey_mc_cnt) { + RTW_PRINT(FUNC_ADPT_FMT" gkey installed. no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n", + FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt); + } + start = 0; + no_gkey_bc_cnt = 0; + no_gkey_mc_cnt = 0; + + #ifdef CONFIG_RTW_MESH + if (MLME_IS_MESH(padapter)) { + /* TODO: multiple GK? */ + prwskey = &stainfo->gtk.skey[0]; + } else + #endif + { + prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey; + if (psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) { + RTW_DBG("not match packet_index=%d, install_index=%d\n" + , prxattrib->key_index, psecuritypriv->dot118021XGrpKeyid); + res = _FAIL; + goto exit; + } + } + } else + prwskey = &stainfo->dot118021x_UncstKey.skey[0]; + + res = _rtw_ccmp_decrypt(padapter, prwskey, + prxattrib->encrypt == _CCMP_256_ ? 32 : 16, + prxattrib->hdrlen, pframe, + ((union recv_frame *)precvframe)->u.hdr.len); + + AES_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra); + } else { + res = _FAIL; + } + + } +exit: + return res; +} +#else u32 rtw_aes_decrypt(_adapter *padapter, u8 *precvframe) { /* exclude ICV */ @@ -1930,7 +2154,7 @@ u32 rtw_aes_decrypt(_adapter *padapter, u8 *precvframe) u32 res = _SUCCESS; pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data; /* 4 start to encrypt each fragment */ - if (prxattrib->encrypt == _AES_) { + if ((prxattrib->encrypt == _AES_)) { stainfo = rtw_get_stainfo(&padapter->stapriv , &prxattrib->ta[0]); if (stainfo != NULL) { @@ -2031,1054 +2255,23 @@ u32 rtw_aes_decrypt(_adapter *padapter, u8 *precvframe) exit: return res; } - -#ifdef CONFIG_IEEE80211W -u32 rtw_BIP_verify(_adapter *padapter, u8 *whdr_pos, sint flen - , const u8 *key, u16 keyid, u64* ipn) -{ - u8 *BIP_AAD, *mme; - u32 res = _FAIL; - uint len, ori_len; - u16 pkt_keyid = 0; - u64 pkt_ipn = 0; - struct rtw_ieee80211_hdr *pwlanhdr; - u8 mic[16]; - - mme = whdr_pos + flen - 18; - if (*mme != _MME_IE_) - return RTW_RX_HANDLED; - - /* copy key index */ - _rtw_memcpy(&pkt_keyid, mme + 2, 2); - pkt_keyid = le16_to_cpu(pkt_keyid); - if (pkt_keyid != keyid) { - RTW_INFO("BIP key index error!\n"); - return _FAIL; - } - - /* save packet number */ - _rtw_memcpy(&pkt_ipn, mme + 4, 6); - pkt_ipn = le64_to_cpu(pkt_ipn); - /* BIP packet number should bigger than previous BIP packet */ - if (pkt_ipn <= *ipn) { /* wrap around? */ - RTW_INFO("replay BIP packet\n"); - return _FAIL; - } - - ori_len = flen - WLAN_HDR_A3_LEN + BIP_AAD_SIZE; - BIP_AAD = rtw_zmalloc(ori_len); - if (BIP_AAD == NULL) { - RTW_INFO("BIP AAD allocate fail\n"); - return _FAIL; - } - - /* mapping to wlan header */ - pwlanhdr = (struct rtw_ieee80211_hdr *)whdr_pos; - - /* save the frame body + MME */ - _rtw_memcpy(BIP_AAD + BIP_AAD_SIZE, whdr_pos + WLAN_HDR_A3_LEN, flen - WLAN_HDR_A3_LEN); - - /* point mme to the copy */ - mme = BIP_AAD + ori_len - 18; - - /* clear the MIC field of MME to zero */ - _rtw_memset(mme + 10, 0, 8); - - /* conscruct AAD, copy frame control field */ - _rtw_memcpy(BIP_AAD, &pwlanhdr->frame_ctl, 2); - ClearRetry(BIP_AAD); - ClearPwrMgt(BIP_AAD); - ClearMData(BIP_AAD); - /* conscruct AAD, copy address 1 to address 3 */ - _rtw_memcpy(BIP_AAD + 2, pwlanhdr->addr1, 18); - - if (omac1_aes_128(key, BIP_AAD, ori_len, mic)) - goto BIP_exit; - -#if 0 - /* management packet content */ - { - int pp; - RTW_INFO("pkt: "); - for (pp = 0; pp < flen; pp++) - printk(" %02x ", whdr_pos[pp]); - RTW_INFO("\n"); - /* BIP AAD + management frame body + MME(MIC is zero) */ - RTW_INFO("AAD+PKT: "); - for (pp = 0; pp < ori_len; pp++) - RTW_INFO(" %02x ", BIP_AAD[pp]); - RTW_INFO("\n"); - /* show the MIC result */ - RTW_INFO("mic: "); - for (pp = 0; pp < 16; pp++) - RTW_INFO(" %02x ", mic[pp]); - RTW_INFO("\n"); - } #endif - /* MIC field should be last 8 bytes of packet (packet without FCS) */ - if (_rtw_memcmp(mic, whdr_pos + flen - 8, 8)) { - *ipn = pkt_ipn; - res = _SUCCESS; - } else - RTW_INFO("BIP MIC error!\n"); - -BIP_exit: - - rtw_mfree(BIP_AAD, ori_len); - return res; -} -#endif /* CONFIG_IEEE80211W */ - -#ifndef PLATFORM_FREEBSD -#if defined(CONFIG_TDLS) -/* compress 512-bits */ -static int sha256_compress(struct _sha256_state *md, unsigned char *buf) -{ - u32 S[8], W[64], t0, t1; - u32 t; - int i; - - /* copy state into S */ - for (i = 0; i < 8; i++) - S[i] = md->state[i]; - - /* copy the state into 512-bits into W[0..15] */ - for (i = 0; i < 16; i++) - W[i] = WPA_GET_BE32(buf + (4 * i)); - - /* fill W[16..63] */ - for (i = 16; i < 64; i++) { - W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + - W[i - 16]; - } - - /* Compress */ -#define RND(a, b, c, d, e, f, g, h, i) do {\ - t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ - t1 = Sigma0(a) + Maj(a, b, c); \ - d += t0; \ - h = t0 + t1; \ - } while (0) - - for (i = 0; i < 64; ++i) { - RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); - t = S[7]; - S[7] = S[6]; - S[6] = S[5]; - S[5] = S[4]; - S[4] = S[3]; - S[3] = S[2]; - S[2] = S[1]; - S[1] = S[0]; - S[0] = t; - } - - /* feedback */ - for (i = 0; i < 8; i++) - md->state[i] = md->state[i] + S[i]; - return 0; -} - -/* Initialize the hash state */ -static void sha256_init(struct _sha256_state *md) -{ - md->curlen = 0; - md->length = 0; - md->state[0] = 0x6A09E667UL; - md->state[1] = 0xBB67AE85UL; - md->state[2] = 0x3C6EF372UL; - md->state[3] = 0xA54FF53AUL; - md->state[4] = 0x510E527FUL; - md->state[5] = 0x9B05688CUL; - md->state[6] = 0x1F83D9ABUL; - md->state[7] = 0x5BE0CD19UL; -} - -/** - Process a block of memory though the hash - @param md The hash state - @param in The data to hash - @param inlen The length of the data (octets) - @return CRYPT_OK if successful -*/ -static int sha256_process(struct _sha256_state *md, unsigned char *in, - unsigned long inlen) -{ - unsigned long n; -#define block_size 64 - - if (md->curlen >= sizeof(md->buf)) - return -1; - - while (inlen > 0) { - if (md->curlen == 0 && inlen >= block_size) { - if (sha256_compress(md, (unsigned char *) in) < 0) - return -1; - md->length += block_size * 8; - in += block_size; - inlen -= block_size; - } else { - n = MIN(inlen, (block_size - md->curlen)); - _rtw_memcpy(md->buf + md->curlen, in, n); - md->curlen += n; - in += n; - inlen -= n; - if (md->curlen == block_size) { - if (sha256_compress(md, md->buf) < 0) - return -1; - md->length += 8 * block_size; - md->curlen = 0; - } - } - } - - return 0; -} - - -/** - Terminate the hash to get the digest - @param md The hash state - @param out [out] The destination of the hash (32 bytes) - @return CRYPT_OK if successful -*/ -static int sha256_done(struct _sha256_state *md, unsigned char *out) -{ - int i; - - if (md->curlen >= sizeof(md->buf)) - return -1; - - /* increase the length of the message */ - md->length += md->curlen * 8; - - /* append the '1' bit */ - md->buf[md->curlen++] = (unsigned char) 0x80; - - /* if the length is currently above 56 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if (md->curlen > 56) { - while (md->curlen < 64) - md->buf[md->curlen++] = (unsigned char) 0; - sha256_compress(md, md->buf); - md->curlen = 0; - } - - /* pad upto 56 bytes of zeroes */ - while (md->curlen < 56) - md->buf[md->curlen++] = (unsigned char) 0; - - /* store length */ - WPA_PUT_BE64(md->buf + 56, md->length); - sha256_compress(md, md->buf); - - /* copy output */ - for (i = 0; i < 8; i++) - WPA_PUT_BE32(out + (4 * i), md->state[i]); - - return 0; -} - -/** - * sha256_vector - SHA256 hash for data vector - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for the hash - * Returns: 0 on success, -1 of failure - */ -static int sha256_vector(size_t num_elem, u8 *addr[], size_t *len, - u8 *mac) -{ - struct _sha256_state ctx; - size_t i; - - sha256_init(&ctx); - for (i = 0; i < num_elem; i++) - if (sha256_process(&ctx, addr[i], len[i])) - return -1; - if (sha256_done(&ctx, mac)) - return -1; - return 0; -} - -static u8 os_strlen(const char *s) -{ - const char *p = s; - while (*p) - p++; - return p - s; -} -#endif - -#if defined(CONFIG_TDLS) || defined(CONFIG_RTW_MESH_AEK) -static int os_memcmp(const void *s1, const void *s2, u8 n) -{ - const unsigned char *p1 = s1, *p2 = s2; - - if (n == 0) - return 0; - - while (*p1 == *p2) { - p1++; - p2++; - n--; - if (n == 0) - return 0; - } - - return *p1 - *p2; -} -#endif - -/** - * hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104) - * @key: Key for HMAC operations - * @key_len: Length of the key in bytes - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for the hash (32 bytes) - */ -#if defined(CONFIG_TDLS) -static void hmac_sha256_vector(u8 *key, size_t key_len, size_t num_elem, - u8 *addr[], size_t *len, u8 *mac) -{ - unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */ - unsigned char tk[32]; - u8 *_addr[6]; - size_t _len[6], i; - - if (num_elem > 5) { - /* - * Fixed limit on the number of fragments to avoid having to - * allocate memory (which could fail). - */ - return; - } - - /* if key is longer than 64 bytes reset it to key = SHA256(key) */ - if (key_len > 64) { - sha256_vector(1, &key, &key_len, tk); - key = tk; - key_len = 32; - } - - /* the HMAC_SHA256 transform looks like: - * - * SHA256(K XOR opad, SHA256(K XOR ipad, text)) - * - * where K is an n byte key - * ipad is the byte 0x36 repeated 64 times - * opad is the byte 0x5c repeated 64 times - * and text is the data being protected */ - - /* start out by storing key in ipad */ - _rtw_memset(k_pad, 0, sizeof(k_pad)); - _rtw_memcpy(k_pad, key, key_len); - /* XOR key with ipad values */ - for (i = 0; i < 64; i++) - k_pad[i] ^= 0x36; - - /* perform inner SHA256 */ - _addr[0] = k_pad; - _len[0] = 64; - for (i = 0; i < num_elem; i++) { - _addr[i + 1] = addr[i]; - _len[i + 1] = len[i]; - } - sha256_vector(1 + num_elem, _addr, _len, mac); - - _rtw_memset(k_pad, 0, sizeof(k_pad)); - _rtw_memcpy(k_pad, key, key_len); - /* XOR key with opad values */ - for (i = 0; i < 64; i++) - k_pad[i] ^= 0x5c; - - /* perform outer SHA256 */ - _addr[0] = k_pad; - _len[0] = 64; - _addr[1] = mac; - _len[1] = 32; - sha256_vector(2, _addr, _len, mac); -} -#endif /* CONFIG_TDLS */ -#endif /* PLATFORM_FREEBSD */ -/** - * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2) - * @key: Key for PRF - * @key_len: Length of the key in bytes - * @label: A unique label for each purpose of the PRF - * @data: Extra data to bind into the key - * @data_len: Length of the data - * @buf: Buffer for the generated pseudo-random key - * @buf_len: Number of bytes of key to generate - * - * This function is used to derive new, cryptographically separate keys from a - * given key. - */ -#ifndef PLATFORM_FREEBSD /* Baron */ -#if defined(CONFIG_TDLS) -static void sha256_prf(u8 *key, size_t key_len, char *label, - u8 *data, size_t data_len, u8 *buf, size_t buf_len) -{ - u16 counter = 1; - size_t pos, plen; - u8 hash[SHA256_MAC_LEN]; - u8 *addr[4]; - size_t len[4]; - u8 counter_le[2], length_le[2]; - - addr[0] = counter_le; - len[0] = 2; - addr[1] = (u8 *) label; - len[1] = os_strlen(label); - addr[2] = data; - len[2] = data_len; - addr[3] = length_le; - len[3] = sizeof(length_le); - - WPA_PUT_LE16(length_le, buf_len * 8); - pos = 0; - while (pos < buf_len) { - plen = buf_len - pos; - WPA_PUT_LE16(counter_le, counter); - if (plen >= SHA256_MAC_LEN) { - hmac_sha256_vector(key, key_len, 4, addr, len, - &buf[pos]); - pos += SHA256_MAC_LEN; - } else { - hmac_sha256_vector(key, key_len, 4, addr, len, hash); - _rtw_memcpy(&buf[pos], hash, plen); - break; - } - counter++; - } -} -#endif -#endif /* PLATFORM_FREEBSD Baron */ - -/* AES tables*/ -const u32 Te0[256] = { - 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, - 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, - 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, - 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, - 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, - 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, - 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, - 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, - 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, - 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, - 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, - 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, - 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, - 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, - 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, - 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, - 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, - 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, - 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, - 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, - 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, - 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, - 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, - 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, - 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, - 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, - 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, - 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, - 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, - 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, - 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, - 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, - 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, - 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, - 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, - 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, - 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, - 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, - 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, - 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, - 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, - 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, - 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, - 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, - 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, - 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, - 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, - 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, - 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, - 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, - 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, - 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, - 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, - 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, - 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, - 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, - 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, - 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, - 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, - 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, - 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, - 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, - 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, - 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, -}; -const u32 Td0[256] = { - 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, - 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, - 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, - 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, - 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, - 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, - 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, - 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, - 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, - 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, - 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, - 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, - 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, - 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, - 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, - 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, - 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, - 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, - 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, - 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, - 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, - 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, - 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, - 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, - 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, - 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, - 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, - 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, - 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, - 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, - 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, - 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, - 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, - 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, - 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, - 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, - 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, - 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, - 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, - 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, - 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, - 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, - 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, - 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, - 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, - 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, - 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, - 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, - 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, - 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, - 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, - 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, - 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, - 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, - 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, - 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, - 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, - 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, - 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, - 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, - 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, - 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, - 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, - 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, -}; -const u8 Td4s[256] = { - 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, - 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, - 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, - 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, - 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, - 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, - 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, - 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, - 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, - 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, - 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, - 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, - 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, - 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, - 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, - 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, - 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, - 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, - 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, - 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, - 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, - 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, - 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, - 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, - 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, - 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, - 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, - 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, - 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, - 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, - 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, - 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, -}; -const u8 rcons[] = { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 - /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ -}; - -/** - * Expand the cipher key into the encryption key schedule. - * - * @return the number of rounds for the given cipher key size. - */ -#ifndef PLATFORM_FREEBSD /* Baron */ -static void rijndaelKeySetupEnc(u32 rk[/*44*/], const u8 cipherKey[]) -{ - int i; - u32 temp; - - rk[0] = GETU32(cipherKey); - rk[1] = GETU32(cipherKey + 4); - rk[2] = GETU32(cipherKey + 8); - rk[3] = GETU32(cipherKey + 12); - for (i = 0; i < 10; i++) { - temp = rk[3]; - rk[4] = rk[0] ^ - TE421(temp) ^ TE432(temp) ^ TE443(temp) ^ TE414(temp) ^ - RCON(i); - rk[5] = rk[1] ^ rk[4]; - rk[6] = rk[2] ^ rk[5]; - rk[7] = rk[3] ^ rk[6]; - rk += 4; - } -} - -static void rijndaelEncrypt(u32 rk[/*44*/], u8 pt[16], u8 ct[16]) -{ - u32 s0, s1, s2, s3, t0, t1, t2, t3; - int Nr = 10; -#ifndef FULL_UNROLL - int r; -#endif /* ?FULL_UNROLL */ - - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(pt) ^ rk[0]; - s1 = GETU32(pt + 4) ^ rk[1]; - s2 = GETU32(pt + 8) ^ rk[2]; - s3 = GETU32(pt + 12) ^ rk[3]; - -#define ROUND(i, d, s) do {\ - d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \ - d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \ - d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \ - d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]; \ - } while (0) - -#ifdef FULL_UNROLL - - ROUND(1, t, s); - ROUND(2, s, t); - ROUND(3, t, s); - ROUND(4, s, t); - ROUND(5, t, s); - ROUND(6, s, t); - ROUND(7, t, s); - ROUND(8, s, t); - ROUND(9, t, s); - - rk += Nr << 2; - -#else /* !FULL_UNROLL */ - - /* Nr - 1 full rounds: */ - r = Nr >> 1; - for (;;) { - ROUND(1, t, s); - rk += 8; - if (--r == 0) - break; - ROUND(0, s, t); - } - -#endif /* ?FULL_UNROLL */ - -#undef ROUND - - /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0]; - PUTU32(ct , s0); - s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1]; - PUTU32(ct + 4, s1); - s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2]; - PUTU32(ct + 8, s2); - s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3]; - PUTU32(ct + 12, s3); -} - -static void *aes_encrypt_init(const u8 *key, size_t len) -{ - u32 *rk; - if (len != 16) - return NULL; - rk = (u32 *)rtw_malloc(AES_PRIV_SIZE); - if (rk == NULL) - return NULL; - rijndaelKeySetupEnc(rk, key); - return rk; -} - -static void aes_128_encrypt(void *ctx, u8 *plain, u8 *crypt) -{ - rijndaelEncrypt(ctx, plain, crypt); -} - - -static void gf_mulx(u8 *pad) -{ - int i, carry; - - carry = pad[0] & 0x80; - for (i = 0; i < AES_BLOCK_SIZE - 1; i++) - pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); - pad[AES_BLOCK_SIZE - 1] <<= 1; - if (carry) - pad[AES_BLOCK_SIZE - 1] ^= 0x87; -} - -static void aes_encrypt_deinit(void *ctx) -{ - _rtw_memset(ctx, 0, AES_PRIV_SIZE); - rtw_mfree(ctx, AES_PRIV_SIZE); -} - - -/** - * omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128 - * @key: 128-bit key for the hash operation - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) - * Returns: 0 on success, -1 on failure - * - * This is a mode for using block cipher (AES in this case) for authentication. - * OMAC1 was standardized with the name CMAC by NIST in a Special Publication - * (SP) 800-38B. - */ -static int omac1_aes_128_vector(const u8 *key, size_t num_elem, - const u8 *addr[], const size_t *len, u8 *mac) -{ - void *ctx; - u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE]; - const u8 *pos, *end; - size_t i, e, left, total_len; - - ctx = aes_encrypt_init(key, 16); - if (ctx == NULL) - return -1; - _rtw_memset(cbc, 0, AES_BLOCK_SIZE); - - total_len = 0; - for (e = 0; e < num_elem; e++) - total_len += len[e]; - left = total_len; - - e = 0; - pos = addr[0]; - end = pos + len[0]; - - while (left >= AES_BLOCK_SIZE) { - for (i = 0; i < AES_BLOCK_SIZE; i++) { - cbc[i] ^= *pos++; - if (pos >= end) { - e++; - pos = addr[e]; - end = pos + len[e]; - } - } - if (left > AES_BLOCK_SIZE) - aes_128_encrypt(ctx, cbc, cbc); - left -= AES_BLOCK_SIZE; - } - - _rtw_memset(pad, 0, AES_BLOCK_SIZE); - aes_128_encrypt(ctx, pad, pad); - gf_mulx(pad); - - if (left || total_len == 0) { - for (i = 0; i < left; i++) { - cbc[i] ^= *pos++; - if (pos >= end) { - e++; - pos = addr[e]; - end = pos + len[e]; - } - } - cbc[left] ^= 0x80; - gf_mulx(pad); - } - - for (i = 0; i < AES_BLOCK_SIZE; i++) - pad[i] ^= cbc[i]; - aes_128_encrypt(ctx, pad, mac); - aes_encrypt_deinit(ctx); - return 0; -} - - -/** - * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC) - * @key: 128-bit key for the hash operation - * @data: Data buffer for which a MAC is determined - * @data_len: Length of data buffer in bytes - * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) - * Returns: 0 on success, -1 on failure - * - * This is a mode for using block cipher (AES in this case) for authentication. - * OMAC1 was standardized with the name CMAC by NIST in a Special Publication - * (SP) 800-38B. - */ /* modify for CONFIG_IEEE80211W */ -int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac) -{ - return omac1_aes_128_vector(key, 1, &data, &data_len, mac); -} -#endif /* PLATFORM_FREEBSD Baron */ - #ifdef CONFIG_RTW_MESH_AEK -/* for AES-SIV */ -#define os_memset _rtw_memset -#define os_memcpy _rtw_memcpy -#define os_malloc rtw_malloc -#define bin_clear_free(bin, len) \ - do { \ - if (bin) { \ - os_memset(bin, 0, len); \ - rtw_mfree(bin, len); \ - } \ - } while (0) - -static const u8 zero[AES_BLOCK_SIZE]; - -static void dbl(u8 *pad) +/* for AES-SIV, wrapper to ase_siv_encrypt and aes_siv_decrypt */ +int rtw_aes_siv_encrypt(const u8 *key, size_t key_len, const u8 *pw, + size_t pwlen, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *out) { - int i, carry; - - carry = pad[0] & 0x80; - for (i = 0; i < AES_BLOCK_SIZE - 1; i++) - pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); - pad[AES_BLOCK_SIZE - 1] <<= 1; - if (carry) - pad[AES_BLOCK_SIZE - 1] ^= 0x87; + return _aes_siv_encrypt(key, key_len, pw, pwlen, + num_elem, addr, len, out); } -static void xor(u8 *a, const u8 *b) +int rtw_aes_siv_decrypt(const u8 *key, size_t key_len, const u8 *iv_crypt, size_t iv_c_len, + size_t num_elem, const u8 *addr[], const size_t *len, u8 *out) { - int i; - - for (i = 0; i < AES_BLOCK_SIZE; i++) - *a++ ^= *b++; -} - -static void xorend(u8 *a, int alen, const u8 *b, int blen) -{ - int i; - - if (alen < blen) - return; - - for (i = 0; i < blen; i++) - a[alen - blen + i] ^= b[i]; -} - -static void pad_block(u8 *pad, const u8 *addr, size_t len) -{ - os_memset(pad, 0, AES_BLOCK_SIZE); - os_memcpy(pad, addr, len); - - if (len < AES_BLOCK_SIZE) - pad[len] = 0x80; -} - -static int aes_s2v(const u8 *key, size_t num_elem, const u8 *addr[], - size_t *len, u8 *mac) -{ - u8 tmp[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE]; - u8 *buf = NULL; - int ret; - size_t i; - - if (!num_elem) { - os_memcpy(tmp, zero, sizeof(zero)); - tmp[AES_BLOCK_SIZE - 1] = 1; - return omac1_aes_128(key, tmp, sizeof(tmp), mac); - } - - ret = omac1_aes_128(key, zero, sizeof(zero), tmp); - if (ret) - return ret; - - for (i = 0; i < num_elem - 1; i++) { - ret = omac1_aes_128(key, addr[i], len[i], tmp2); - if (ret) - return ret; - - dbl(tmp); - xor(tmp, tmp2); - } - if (len[i] >= AES_BLOCK_SIZE) { - buf = os_malloc(len[i]); - if (!buf) - return -ENOMEM; - - os_memcpy(buf, addr[i], len[i]); - xorend(buf, len[i], tmp, AES_BLOCK_SIZE); - ret = omac1_aes_128(key, buf, len[i], mac); - bin_clear_free(buf, len[i]); - return ret; - } - - dbl(tmp); - pad_block(tmp2, addr[i], len[i]); - xor(tmp, tmp2); - - return omac1_aes_128(key, tmp, sizeof(tmp), mac); -} - -/** - * aes_128_ctr_encrypt - AES-128 CTR mode encryption - * @key: Key for encryption (16 bytes) - * @nonce: Nonce for counter mode (16 bytes) - * @data: Data to encrypt in-place - * @data_len: Length of data in bytes - * Returns: 0 on success, -1 on failure - */ -int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, - u8 *data, size_t data_len) -{ - void *ctx; - size_t j, len, left = data_len; - int i; - u8 *pos = data; - u8 counter[AES_BLOCK_SIZE], buf[AES_BLOCK_SIZE]; - - ctx = aes_encrypt_init(key, 16); - if (ctx == NULL) - return -1; - os_memcpy(counter, nonce, AES_BLOCK_SIZE); - - while (left > 0) { - #if 0 - aes_encrypt(ctx, counter, buf); - #else - aes_128_encrypt(ctx, counter, buf); - #endif - - len = (left < AES_BLOCK_SIZE) ? left : AES_BLOCK_SIZE; - for (j = 0; j < len; j++) - pos[j] ^= buf[j]; - pos += len; - left -= len; - - for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) { - counter[i]++; - if (counter[i]) - break; - } - } - aes_encrypt_deinit(ctx); - return 0; -} - -int aes_siv_encrypt(const u8 *key, const u8 *pw, - size_t pwlen, size_t num_elem, - const u8 *addr[], const size_t *len, u8 *out) -{ - const u8 *_addr[6]; - size_t _len[6]; - const u8 *k1 = key, *k2 = key + 16; - u8 v[AES_BLOCK_SIZE]; - size_t i; - u8 *iv, *crypt_pw; - - if (num_elem > ARRAY_SIZE(_addr) - 1) - return -1; - - for (i = 0; i < num_elem; i++) { - _addr[i] = addr[i]; - _len[i] = len[i]; - } - _addr[num_elem] = pw; - _len[num_elem] = pwlen; - - if (aes_s2v(k1, num_elem + 1, _addr, _len, v)) - return -1; - - iv = out; - crypt_pw = out + AES_BLOCK_SIZE; - - os_memcpy(iv, v, AES_BLOCK_SIZE); - os_memcpy(crypt_pw, pw, pwlen); - - /* zero out 63rd and 31st bits of ctr (from right) */ - v[8] &= 0x7f; - v[12] &= 0x7f; - return aes_128_ctr_encrypt(k2, v, crypt_pw, pwlen); -} - -int aes_siv_decrypt(const u8 *key, const u8 *iv_crypt, size_t iv_c_len, - size_t num_elem, const u8 *addr[], const size_t *len, - u8 *out) -{ - const u8 *_addr[6]; - size_t _len[6]; - const u8 *k1 = key, *k2 = key + 16; - size_t crypt_len; - size_t i; - int ret; - u8 iv[AES_BLOCK_SIZE]; - u8 check[AES_BLOCK_SIZE]; - - if (iv_c_len < AES_BLOCK_SIZE || num_elem > ARRAY_SIZE(_addr) - 1) - return -1; - crypt_len = iv_c_len - AES_BLOCK_SIZE; - - for (i = 0; i < num_elem; i++) { - _addr[i] = addr[i]; - _len[i] = len[i]; - } - _addr[num_elem] = out; - _len[num_elem] = crypt_len; - - os_memcpy(iv, iv_crypt, AES_BLOCK_SIZE); - os_memcpy(out, iv_crypt + AES_BLOCK_SIZE, crypt_len); - - iv[8] &= 0x7f; - iv[12] &= 0x7f; - - ret = aes_128_ctr_encrypt(k2, iv, out, crypt_len); - if (ret) - return ret; - - ret = aes_s2v(k1, num_elem + 1, _addr, _len, check); - if (ret) - return ret; - if (os_memcmp(check, iv_crypt, AES_BLOCK_SIZE) == 0) - return 0; - - return -1; + return _aes_siv_decrypt(key, key_len, iv_crypt, + iv_c_len, num_elem, addr, len, out); } #endif /* CONFIG_RTW_MESH_AEK */ @@ -3086,50 +2279,9 @@ int aes_siv_decrypt(const u8 *key, const u8 *iv_crypt, size_t iv_c_len, void wpa_tdls_generate_tpk(_adapter *padapter, void *sta) { struct sta_info *psta = (struct sta_info *)sta; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 *SNonce = psta->SNonce; - u8 *ANonce = psta->ANonce; - - u8 key_input[SHA256_MAC_LEN]; - u8 *nonce[2]; - size_t len[2]; - u8 data[3 * ETH_ALEN]; - - /* IEEE Std 802.11z-2010 8.5.9.1: - * TPK-Key-Input = SHA-256(min(SNonce, ANonce) || max(SNonce, ANonce)) - */ - len[0] = 32; - len[1] = 32; - if (os_memcmp(SNonce, ANonce, 32) < 0) { - nonce[0] = SNonce; - nonce[1] = ANonce; - } else { - nonce[0] = ANonce; - nonce[1] = SNonce; - } - - sha256_vector(2, nonce, len, key_input); - - /* - * TPK-Key-Data = KDF-N_KEY(TPK-Key-Input, "TDLS PMK", - * min(MAC_I, MAC_R) || max(MAC_I, MAC_R) || BSSID || N_KEY) - * TODO: is N_KEY really included in KDF Context and if so, in which - * presentation format (little endian 16-bit?) is it used? It gets - * added by the KDF anyway.. - */ - - if (os_memcmp(adapter_mac_addr(padapter), psta->cmn.mac_addr, ETH_ALEN) < 0) { - _rtw_memcpy(data, adapter_mac_addr(padapter), ETH_ALEN); - _rtw_memcpy(data + ETH_ALEN, psta->cmn.mac_addr, ETH_ALEN); - } else { - _rtw_memcpy(data, psta->cmn.mac_addr, ETH_ALEN); - _rtw_memcpy(data + ETH_ALEN, adapter_mac_addr(padapter), ETH_ALEN); - } - _rtw_memcpy(data + 2 * ETH_ALEN, get_bssid(pmlmepriv), ETH_ALEN); - - sha256_prf(key_input, SHA256_MAC_LEN, "TDLS PMK", data, sizeof(data), (u8 *) &psta->tpk, sizeof(psta->tpk)); - + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _tdls_generate_tpk(psta, adapter_mac_addr(padapter), get_bssid(pmlmepriv)); } /** @@ -3184,7 +2336,8 @@ int wpa_tdls_ftie_mic(u8 *kck, u8 trans_seq, _rtw_memset(_ftie->mic, 0, TDLS_MIC_LEN); pos += 2 + ftie[1]; - ret = omac1_aes_128(kck, buf, pos - buf, mic); + /* ret = omac1_aes_128(kck, buf, pos - buf, mic); */ + ret = _bip_ccmp_protect(kck, 16, buf, pos - buf, mic); rtw_mfree(buf, len); return ret; @@ -3233,7 +2386,8 @@ int wpa_tdls_teardown_ftie_mic(u8 *kck, u8 *lnkid, u16 reason, _rtw_memset(_ftie->mic, 0, TDLS_MIC_LEN); pos += 2 + ftie[1]; - ret = omac1_aes_128(kck, buf, pos - buf, mic); + /* ret = omac1_aes_128(kck, buf, pos - buf, mic); */ + ret = _bip_ccmp_protect(kck, 16, buf, pos - buf, mic); rtw_mfree(buf, len); return ret; @@ -3283,13 +2437,14 @@ int tdls_verify_mic(u8 *kck, u8 trans_seq, _rtw_memset(tmp_ftie, 0, 16); pos += *(ftie + 1); - ret = omac1_aes_128(kck, buf, pos - buf, mic); + /* ret = omac1_aes_128(kck, buf, pos - buf, mic); */ + ret = _bip_ccmp_protect(kck, 16, buf, pos - buf, mic); rtw_mfree(buf, len); - if (ret) + if (ret == _FAIL) return _FAIL; rx_ftie = ftie + 4; - if (os_memcmp(mic, rx_ftie, 16) == 0) { + if (_rtw_memcmp2(mic, rx_ftie, 16) == 0) { /* Valid MIC */ return _SUCCESS; } @@ -3406,3 +2561,312 @@ u16 rtw_calc_crc(u8 *pdata, int length) return crc; } #endif /*CONFIG_WOWLAN*/ + +u32 rtw_calc_crc32(u8 *data, size_t len) +{ + size_t i; + u32 crc = 0xFFFFFFFF; + + if (bcrc32initialized == 0) + crc32_init(); + + for (i = 0; i < len; i++) + crc = crc32_table[(crc ^ data[i]) & 0xff] ^ (crc >> 8); + + /* return 1' complement */ + return ~crc; +} + + +/** + * rtw_gcmp_encrypt - + * @padapter: + * @pxmitframe: + * + */ +u32 rtw_gcmp_encrypt(_adapter *padapter, u8 *pxmitframe) +{ + struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + /* Intermediate Buffers */ + sint curfragnum, plen; + u32 prwskeylen; + u8 *pframe = NULL; + u8 *prwskey = NULL; + u8 hw_hdr_offset = 0; + u32 res = _SUCCESS; + + if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL) + return _FAIL; + +#ifdef CONFIG_USB_TX_AGGREGATION + hw_hdr_offset = TXDESC_SIZE + + (((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ); +#else +#ifdef CONFIG_TX_EARLY_MODE + hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE; +#else + hw_hdr_offset = TXDESC_OFFSET; +#endif +#endif + + pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset; + + /* start to encrypt each fragment */ + if ((pattrib->encrypt == _GCMP_) || + (pattrib->encrypt == _GCMP_256_)) { + + if (IS_MCAST(pattrib->ra)) + prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; + else + prwskey = pattrib->dot118021x_UncstKey.skey; + + prwskeylen = (pattrib->encrypt == _GCMP_256_) ? 32 : 16; + + for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { + if ((curfragnum + 1) == pattrib->nr_frags) { + /* the last fragment */ + plen = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; + + _rtw_gcmp_encrypt(padapter, prwskey, prwskeylen, pattrib->hdrlen, pframe, plen); + } else { + plen = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; + + _rtw_gcmp_encrypt(padapter, prwskey, prwskeylen, pattrib->hdrlen, pframe, plen); + pframe += pxmitpriv->frag_len; + pframe = (u8 *)RND4((SIZE_PTR)(pframe)); + } + } + + GCMP_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra); + } + + return res; +} + +u32 rtw_gcmp_decrypt(_adapter *padapter, u8 *precvframe) +{ + u32 prwskeylen; + u8 * pframe,*prwskey; + struct sta_info *stainfo; + struct rx_pkt_attrib *prxattrib = &((union recv_frame *)precvframe)->u.hdr.attrib; + struct security_priv *psecuritypriv = &padapter->securitypriv; + u32 res = _SUCCESS; + pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data; + + if ((prxattrib->encrypt == _GCMP_) || + (prxattrib->encrypt == _GCMP_256_)) { + stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]); + if (stainfo != NULL) { + if (IS_MCAST(prxattrib->ra)) { + static systime start = 0; + static u32 no_gkey_bc_cnt = 0; + static u32 no_gkey_mc_cnt = 0; + + if ((!MLME_IS_MESH(padapter) && psecuritypriv->binstallGrpkey == _FALSE) + #ifdef CONFIG_RTW_MESH + || !(stainfo->gtk_bmp | BIT(prxattrib->key_index)) + #endif + ) { + res = _FAIL; + + if (start == 0) + start = rtw_get_current_time(); + + if (is_broadcast_mac_addr(prxattrib->ra)) + no_gkey_bc_cnt++; + else + no_gkey_mc_cnt++; + + if (rtw_get_passing_time_ms(start) > 1000) { + if (no_gkey_bc_cnt || no_gkey_mc_cnt) { + RTW_PRINT(FUNC_ADPT_FMT" no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n", + FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt); + } + start = rtw_get_current_time(); + no_gkey_bc_cnt = 0; + no_gkey_mc_cnt = 0; + } + + goto exit; + } + + if (no_gkey_bc_cnt || no_gkey_mc_cnt) { + RTW_PRINT(FUNC_ADPT_FMT" gkey installed. no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n", + FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt); + } + start = 0; + no_gkey_bc_cnt = 0; + no_gkey_mc_cnt = 0; + + #ifdef CONFIG_RTW_MESH + if (MLME_IS_MESH(padapter)) { + /* TODO: multiple GK? */ + prwskey = &stainfo->gtk.skey[0]; + } else + #endif + { + prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey; + if (psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) { + RTW_DBG("not match packet_index=%d, install_index=%d\n" + , prxattrib->key_index, psecuritypriv->dot118021XGrpKeyid); + res = _FAIL; + goto exit; + } + } + } else + prwskey = &stainfo->dot118021x_UncstKey.skey[0]; + + res = _rtw_gcmp_decrypt(padapter, prwskey, + prxattrib->encrypt == _GCMP_256_ ? 32 : 16, + prxattrib->hdrlen, pframe, + ((union recv_frame *)precvframe)->u.hdr.len); + + GCMP_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra); + } else { + res = _FAIL; + } + + } +exit: + return res; +} + + +#ifdef CONFIG_IEEE80211W +u8 rtw_calculate_bip_mic(enum security_type gmcs, u8 *whdr_pos, s32 len, + const u8 *key, const u8 *data, size_t data_len, u8 *mic) +{ + u8 res = _SUCCESS; + + if (gmcs == _BIP_CMAC_128_) { + if (_bip_ccmp_protect(key, 16, data, data_len, mic) == _FALSE) { + res = _FAIL; + RTW_ERR("%s : _bip_ccmp_protect(128) fail!", __func__); + } + } else if (gmcs == _BIP_CMAC_256_) { + if (_bip_ccmp_protect(key, 32, data, data_len, mic) == _FALSE) { + res = _FAIL; + RTW_ERR("%s : _bip_ccmp_protect(256) fail!", __func__); + } + } else if (gmcs == _BIP_GMAC_128_) { + if (_bip_gcmp_protect(whdr_pos, len, key, 16, + data, data_len, mic) == _FALSE) { + res = _FAIL; + RTW_ERR("%s : _bip_gcmp_protect(128) fail!", __func__); + } + } else if (gmcs == _BIP_GMAC_256_) { + if (_bip_gcmp_protect(whdr_pos, len, key, 32, + data, data_len, mic) == _FALSE) { + res = _FAIL; + RTW_ERR("%s : _bip_gcmp_protect(256) fail!", __func__); + } + } else { + res = _FAIL; + RTW_ERR("%s : unsupport dot11wCipher !\n", __func__); + } + + return res; +} + + +u32 rtw_bip_verify(enum security_type gmcs, u16 pkt_len, + u8 *whdr_pos, sint flen, const u8 *key, u16 keyid, u64 *ipn) +{ + u8 * BIP_AAD,*mme; + u32 res = _FAIL; + uint len, ori_len; + u16 pkt_keyid = 0; + u64 pkt_ipn = 0; + struct rtw_ieee80211_hdr *pwlanhdr; + u8 mic[16]; + u8 mic_len, mme_offset; + + mic_len = (gmcs == _BIP_CMAC_128_) ? 8 : 16; + + if (flen < WLAN_HDR_A3_LEN || flen - WLAN_HDR_A3_LEN < mic_len) + return RTW_RX_HANDLED; + + mme_offset = (mic_len == 8) ? 18 : 26; + mme = whdr_pos + flen - mme_offset; + if (*mme != _MME_IE_) + return RTW_RX_HANDLED; + + /* copy key index */ + _rtw_memcpy(&pkt_keyid, mme + 2, 2); + pkt_keyid = le16_to_cpu(pkt_keyid); + if (pkt_keyid != keyid) { + RTW_INFO("BIP key index error!\n"); + return _FAIL; + } + + /* save packet number */ + _rtw_memcpy(&pkt_ipn, mme + 4, 6); + pkt_ipn = le64_to_cpu(pkt_ipn); + /* BIP packet number should bigger than previous BIP packet */ + if (pkt_ipn <= *ipn) { /* wrap around? */ + RTW_INFO("replay BIP packet\n"); + return _FAIL; + } + + ori_len = flen - WLAN_HDR_A3_LEN + BIP_AAD_SIZE; + BIP_AAD = rtw_zmalloc(ori_len); + if (BIP_AAD == NULL) { + RTW_INFO("BIP AAD allocate fail\n"); + return _FAIL; + } + + /* mapping to wlan header */ + pwlanhdr = (struct rtw_ieee80211_hdr *)whdr_pos; + + /* save the frame body + MME (w/o mic) */ + _rtw_memcpy(BIP_AAD + BIP_AAD_SIZE, + whdr_pos + WLAN_HDR_A3_LEN, + flen - WLAN_HDR_A3_LEN - mic_len); + + /* conscruct AAD, copy frame control field */ + _rtw_memcpy(BIP_AAD, &pwlanhdr->frame_ctl, 2); + ClearRetry(BIP_AAD); + ClearPwrMgt(BIP_AAD); + ClearMData(BIP_AAD); + /* conscruct AAD, copy address 1 to address 3 */ + _rtw_memcpy(BIP_AAD + 2, GetAddr1Ptr((u8 *)pwlanhdr), 18); + + if (rtw_calculate_bip_mic(gmcs, whdr_pos, + pkt_len, key, BIP_AAD, ori_len, mic) == _FAIL) + goto BIP_exit; + + /* MIC field should be last 8 bytes of packet (packet without FCS) */ + if (_rtw_memcmp(mic, whdr_pos + flen - mic_len, mic_len)) { + *ipn = pkt_ipn; + res = _SUCCESS; + } else + RTW_INFO("BIP MIC error!\n"); + +#if 0 + /* management packet content */ + { + int pp; + RTW_INFO("pkt: "); + RTW_INFO_DUMP("", whdr_pos, flen); + RTW_INFO("\n"); + /* BIP AAD + management frame body + MME(MIC is zero) */ + RTW_INFO("AAD+PKT: "); + RTW_INFO_DUMP("", BIP_AAD, ori_len); + RTW_INFO("\n"); + /* show the MIC result */ + RTW_INFO("mic: "); + RTW_INFO_DUMP("", mic, mic_len); + RTW_INFO("\n"); + } +#endif + +BIP_exit: + + rtw_mfree(BIP_AAD, ori_len); + return res; +} + +#endif /* CONFIG_IEEE80211W */ + diff --git a/core/rtw_sreset.c b/core/rtw_sreset.c index 19547d1..21cc18b 100644 --- a/core/rtw_sreset.c +++ b/core/rtw_sreset.c @@ -204,10 +204,14 @@ void sreset_restore_network_status(_adapter *padapter) if (check_fwstate(mlmepriv, WIFI_STATION_STATE)) { RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_STATION_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv)); sreset_restore_network_station(padapter); - } else if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) { + } +#ifdef CONFIG_AP_MODE + else if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) { RTW_INFO(FUNC_ADPT_FMT" %s\n", FUNC_ADPT_ARG(padapter), MLME_IS_AP(padapter) ? "AP" : "MESH"); rtw_ap_restore_network(padapter); - } else if (check_fwstate(mlmepriv, WIFI_ADHOC_STATE)) + } +#endif + else if (check_fwstate(mlmepriv, WIFI_ADHOC_STATE)) RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_ADHOC_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv)); else RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - ???\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv)); @@ -232,10 +236,10 @@ void sreset_stop_adapter(_adapter *padapter) tasklet_kill(&pxmitpriv->xmit_tasklet); #endif - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)) rtw_scan_abort(padapter); - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { + if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING)) { rtw_set_to_roam(padapter, 0); rtw_join_timeout_handler(padapter); } @@ -252,7 +256,7 @@ void sreset_start_adapter(_adapter *padapter) RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); - if (check_fwstate(pmlmepriv, _FW_LINKED)) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) sreset_restore_network_status(padapter); /* TODO: OS and HCI independent */ @@ -298,7 +302,7 @@ void sreset_reset(_adapter *padapter) _ips_enter(padapter); _ips_leave(padapter); #endif -#ifdef CONFIG_CONCURRENT_MODE +#if defined(CONFIG_AP_MODE) && defined(CONFIG_CONCURRENT_MODE) rtw_mi_ap_info_restore(padapter); #endif rtw_mi_sreset_adapter_hdl(padapter, _TRUE);/*sreset_start_adapter*/ diff --git a/core/rtw_sta_mgt.c b/core/rtw_sta_mgt.c index 77a335e..c2e27b9 100644 --- a/core/rtw_sta_mgt.c +++ b/core/rtw_sta_mgt.c @@ -203,7 +203,9 @@ void _rtw_init_stainfo(struct sta_info *psta) /* _rtw_init_listhead(&psta->wakeup_list); */ _rtw_init_queue(&psta->sleep_q); - +#ifdef CONFIG_RTW_MGMT_QUEUE + _rtw_init_queue(&psta->mgmt_sleep_q); +#endif _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv); _rtw_init_sta_recv_priv(&psta->sta_recvpriv); @@ -285,6 +287,9 @@ u32 _rtw_init_sta_priv(struct sta_priv *pstapriv) _rtw_spinlock_init(&pstapriv->auth_list_lock); pstapriv->asoc_list_cnt = 0; pstapriv->auth_list_cnt = 0; +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + pstapriv->tbtx_asoc_list_cnt = 0; +#endif pstapriv->auth_to = 3; /* 3*2 = 6 sec */ pstapriv->assoc_to = 3; @@ -300,12 +305,11 @@ u32 _rtw_init_sta_priv(struct sta_priv *pstapriv) #endif pstapriv->max_num_sta = NUM_STA; -#endif - #if CONFIG_RTW_MACADDR_ACL for (i = 0; i < RTW_ACL_PERIOD_NUM; i++) rtw_macaddr_acl_init(adapter, i); #endif +#endif /* CONFIG_AP_MODE */ #if CONFIG_RTW_PRE_LINK_STA rtw_pre_link_sta_ctl_init(pstapriv); @@ -365,6 +369,9 @@ void _rtw_free_sta_xmit_priv_lock(struct sta_xmit_priv *psta_xmitpriv) _rtw_spinlock_free(&(psta_xmitpriv->bk_q.sta_pending.lock)); _rtw_spinlock_free(&(psta_xmitpriv->vi_q.sta_pending.lock)); _rtw_spinlock_free(&(psta_xmitpriv->vo_q.sta_pending.lock)); +#ifdef CONFIG_RTW_MGMT_QUEUE + _rtw_spinlock_free(&(psta_xmitpriv->mgmt_q.sta_pending.lock)); +#endif } static void _rtw_free_sta_recv_priv_lock(struct sta_recv_priv *psta_recvpriv) @@ -381,7 +388,7 @@ void rtw_mfree_stainfo(struct sta_info *psta); void rtw_mfree_stainfo(struct sta_info *psta) { - if (&(psta->lock) != NULL) + if (&psta->lock != NULL) _rtw_spinlock_free(&psta->lock); _rtw_free_sta_xmit_priv_lock(&psta->sta_xmitpriv); @@ -520,7 +527,7 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, const u8 *hwaddr) _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); if (_rtw_queue_empty(pfree_sta_queue) == _TRUE) { /* _exit_critical_bh(&(pfree_sta_queue->lock), &irqL); */ - _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + /* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); */ psta = NULL; } else { psta = LIST_CONTAINOR(get_next(&pfree_sta_queue->queue), struct sta_info, list); @@ -561,6 +568,8 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, const u8 *hwaddr) _rtw_memcpy(&psta->sta_recvpriv.bmc_tid_rxseq[i], &wRxSeqInitialValue, 2); _rtw_memset(&psta->sta_recvpriv.rxcache.iv[i], 0, sizeof(psta->sta_recvpriv.rxcache.iv[i])); } + _rtw_memcpy(&psta->sta_recvpriv.nonqos_bmc_rxseq,&wRxSeqInitialValue,2); + _rtw_memcpy(&psta->sta_recvpriv.nonqos_rxseq,&wRxSeqInitialValue,2); rtw_init_timer(&psta->addba_retry_timer, psta->padapter, addba_timer_hdl, psta); #ifdef CONFIG_IEEE80211W @@ -582,7 +591,6 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, const u8 *hwaddr) , FUNC_ADPT_ARG(pstapriv->padapter), i, preorder_ctrl->indicate_seq); #endif preorder_ctrl->wend_b = 0xffff; - /* preorder_ctrl->wsize_b = (NR_RECVBUFF-2); */ preorder_ctrl->wsize_b = 64;/* 64; */ preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID; @@ -592,7 +600,7 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, const u8 *hwaddr) rtw_clear_bit(RTW_RECV_ACK_OR_TIMEOUT, &preorder_ctrl->rec_abba_rsp_ack); } - + ATOMIC_SET(&psta->keytrack, 0); /* init for DM */ psta->cmn.rssi_stat.rssi = (-1); @@ -601,6 +609,10 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, const u8 *hwaddr) #ifdef CONFIG_ATMEL_RC_PATCH psta->flag_atmel_rc = 0; #endif + +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + psta->tbtx_enable = _FALSE; +#endif /* init for the sequence number of received management frame */ psta->RxMgmtFrameSeqNum = 0xffff; _rtw_memset(&psta->sta_stats, 0, sizeof(struct stainfo_stats)); @@ -629,7 +641,7 @@ u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta) { int i; _irqL irqL0; - _queue *pfree_sta_queue; + _queue *pfree_sta_queue, *pdefrag_q = NULL; struct recv_reorder_ctrl *preorder_ctrl; struct sta_xmit_priv *pstaxmitpriv; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; @@ -637,9 +649,11 @@ u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta) struct hw_xmit *phwxmit; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - int pending_qcnt[4]; u8 is_pre_link_sta = _FALSE; + _list *phead, *plist; + _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; + union recv_frame *prframe; if (psta == NULL) goto exit; @@ -663,7 +677,7 @@ u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta) } _enter_critical_bh(&psta->lock, &irqL0); - psta->state &= ~_FW_LINKED; + psta->state &= ~WIFI_ASOC_STATE; _exit_critical_bh(&psta->lock, &irqL0); pfree_sta_queue = &pstapriv->free_sta_queue; @@ -683,6 +697,11 @@ u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta) rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q); psta->sleepq_len = 0; +#ifdef CONFIG_RTW_MGMT_QUEUE + rtw_free_mgmt_xmitframe_queue(pxmitpriv, &psta->mgmt_sleep_q); + psta->mgmt_sleepq_len = 0; +#endif + /* vo */ /* _enter_critical_bh(&(pxmitpriv->vo_pending.lock), &irqL0); */ rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending); @@ -723,6 +742,15 @@ u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta) pstaxmitpriv->bk_q.qcnt = 0; /* _exit_critical_bh(&(pxmitpriv->bk_pending.lock), &irqL0); */ +#ifdef CONFIG_RTW_MGMT_QUEUE + /* mgmt */ + rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->mgmt_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->mgmt_q.tx_pending)); + phwxmit = pxmitpriv->hwxmits + 4; + phwxmit->accnt -= pstaxmitpriv->mgmt_q.qcnt; + pstaxmitpriv->mgmt_q.qcnt = 0; +#endif + rtw_os_wake_queue_at_free_stainfo(padapter, pending_qcnt); _exit_critical_bh(&pxmitpriv->lock, &irqL0); @@ -743,14 +771,11 @@ u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta) /* for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer */ for (i = 0; i < 16 ; i++) { _irqL irqL; - _list *phead, *plist; - union recv_frame *prframe; _queue *ppending_recvframe_queue; - _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; preorder_ctrl = &psta->recvreorder_ctrl[i]; rtw_clear_bit(RTW_RECV_ACK_OR_TIMEOUT, &preorder_ctrl->rec_abba_rsp_ack); - + _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer); @@ -775,6 +800,20 @@ u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta) } + /* CVE-2020-24586, clear defrag queue */ + pdefrag_q = &psta->sta_recvpriv.defrag_q; + enter_critical_bh(&pdefrag_q->lock); + phead = get_list_head(pdefrag_q); + plist = get_next(phead); + while (!rtw_is_list_empty(phead)) { + prframe = LIST_CONTAINOR(plist, union recv_frame, u); + plist = get_next(plist); + rtw_list_delete(&(prframe->u.hdr.list)); + rtw_free_recvframe(prframe, pfree_recv_queue); + } + exit_critical_bh(&pdefrag_q->lock); + + if (!((psta->state & WIFI_AP_STATE) || MacAddr_isBcst(psta->cmn.mac_addr)) && is_pre_link_sta == _FALSE) rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _FALSE); @@ -828,9 +867,9 @@ u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta) #endif /* CONFIG_NATIVEAP_MLME */ -#ifdef CONFIG_TX_MCAST2UNI +#if !defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && defined(CONFIG_80211N_HT) psta->under_exist_checking = 0; -#endif /* CONFIG_TX_MCAST2UNI */ +#endif #endif /* CONFIG_AP_MODE */ @@ -961,7 +1000,6 @@ u32 rtw_init_bcmc_stainfo(_adapter *padapter) NDIS_802_11_MAC_ADDRESS bcast_addr = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; struct sta_priv *pstapriv = &padapter->stapriv; - /* _queue *pstapending = &padapter->xmitpriv.bm_pending; */ psta = rtw_alloc_stainfo(pstapriv, bcast_addr); diff --git a/core/rtw_swcrypto.c b/core/rtw_swcrypto.c new file mode 100644 index 0000000..2f1c343 --- /dev/null +++ b/core/rtw_swcrypto.c @@ -0,0 +1,296 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +/** + * rtw_ccmp_encrypt - + * @key: the temporal key + * @hdrlen: mac header length + * @frame: the frame including the mac header, pn and payload + * @plen: payload length, i.e., length of the plain text, without PN and MIC + */ +int _rtw_ccmp_encrypt(_adapter *padapter, u8 *key, u32 key_len, uint hdrlen, u8 *frame, uint plen) +{ + u8 *enc = NULL; + size_t enc_len = 0; + + if (key_len == 16) { /* 128 bits */ + enc = ccmp_encrypt(padapter, key, + frame, + hdrlen + plen, + hdrlen, + (hdrlen == 26) ? (frame + hdrlen - 2) : NULL, + NULL, 0, &enc_len); + } else if (key_len == 32) { /* 256 bits */ + enc = ccmp_256_encrypt(padapter, key, + frame, + hdrlen + plen, + hdrlen, + (hdrlen == 26) ? (frame + hdrlen - 2) : NULL, + NULL, 0, &enc_len); + } + + if (enc == NULL) { + RTW_INFO("Failed to encrypt CCMP(%u) frame", key_len); + return _FAIL; + } + + /* Copy @enc back to @frame and free @enc */ + _rtw_memcpy(frame, enc, enc_len); + rtw_mfree(enc, enc_len + AES_BLOCK_SIZE); + + return _SUCCESS; +} + + +/** + * rtw_ccmp_decrypt - + * @key: the temporal key + * @hdrlen: length of the mac header + * @frame: the raw frame (@hdrlen + PN + enc_data + MIC) + * @plen: length of the frame (@hdrlen + PN + enc_data + MIC) + */ +int _rtw_ccmp_decrypt(_adapter * padapter, u8 *key, u32 key_len, uint hdrlen, u8 *frame, + uint plen) +{ + u8 *plain = NULL; + size_t plain_len = 0; + const struct ieee80211_hdr *hdr; + + hdr = (const struct ieee80211_hdr *)frame; + + if (key_len == 16) { /* 128 bits */ + plain = ccmp_decrypt(padapter, key, + hdr, + frame + hdrlen, /* PN + enc_data + MIC */ + plen - hdrlen, /* PN + enc_data + MIC */ + &plain_len); + } else if (key_len == 32) { /* 256 bits */ + plain = ccmp_256_decrypt(padapter, key, + hdr, + frame + hdrlen, /* PN + enc_data + MIC */ + plen - hdrlen, /* PN + enc_data + MIC */ + &plain_len); + } + + if (plain == NULL) { + RTW_INFO("Failed to decrypt CCMP(%u) frame", key_len); + return _FAIL; + } + + /* Copy @plain back to @frame and free @plain */ + _rtw_memcpy(frame + hdrlen + 8, plain, plain_len); + rtw_mfree(plain, plen - hdrlen + AES_BLOCK_SIZE); + + RTW_DBG_DUMP("ccmp_decrypt(): decrypted frame\n", + frame, hdrlen + 8 + plen); + + return _SUCCESS; +} + + +#ifdef CONFIG_RTW_MESH_AEK +/* wrapper to ase_siv_encrypt and aes_siv_decrypt */ +int _aes_siv_encrypt(const u8 *key, size_t key_len, + const u8 *pw, size_t pwlen, + size_t num_elem, const u8 *addr[], const size_t *len, u8 *out) +{ + return aes_siv_encrypt(key, key_len, pw, pwlen, num_elem, addr, len, out); +} +int _aes_siv_decrypt(const u8 *key, size_t key_len, + const u8 *iv_crypt, size_t iv_c_len, + size_t num_elem, const u8 *addr[], const size_t *len, u8 *out) +{ + return aes_siv_decrypt(key, key_len, iv_crypt, iv_c_len, num_elem, addr, len, out); +} +#endif + + +/** + * _rtw_gcmp_encrypt - + * @key: the temporal key + * @hdrlen: mac header length + * @frame: the frame including the mac header, pn and payload + * @plen: payload length, i.e., length of the plain text, without PN and MIC + */ +int _rtw_gcmp_encrypt(_adapter * padapter, u8 *key, u32 key_len, uint hdrlen, u8 *frame, uint plen) +{ + u8 *enc = NULL; + size_t enc_len = 0; + + enc = gcmp_encrypt(padapter, key, key_len, + frame, + hdrlen + plen, + hdrlen, + (hdrlen == 26) ? (frame + hdrlen - 2) : NULL, + NULL, 0, &enc_len); + if (enc == NULL) { + RTW_INFO("Failed to encrypt GCMP frame"); + return _FAIL; + } + + /* Copy @enc back to @frame and free @enc */ + _rtw_memcpy(frame, enc, enc_len); + rtw_mfree(enc, enc_len + AES_BLOCK_SIZE); + + return _SUCCESS; +} + + +/** + * _rtw_gcmp_decrypt - + * @key: the temporal key + * @hdrlen: length of the mac header + * @frame: the raw frame (@hdrlen + PN + enc_data + MIC) + * @plen: length of the frame (@hdrlen + PN + enc_data + MIC) + */ +int _rtw_gcmp_decrypt(_adapter *padapter, u8 *key, u32 key_len, uint hdrlen, u8 *frame, uint plen) +{ + u8 *plain = NULL; + size_t plain_len = 0; + const struct ieee80211_hdr *hdr; + + hdr = (const struct ieee80211_hdr *)frame; + + plain = gcmp_decrypt(padapter, key, key_len, + hdr, + frame + hdrlen, /* PN + enc_data + MIC */ + plen - hdrlen, /* PN + enc_data + MIC */ + &plain_len); + + if (plain == NULL) { + RTW_INFO("Failed to decrypt GCMP(%u) frame", key_len); + return _FAIL; + } + + /* Copy @plain back to @frame and free @plain */ + _rtw_memcpy(frame + hdrlen + 8, plain, plain_len); + rtw_mfree(plain, plen - hdrlen + AES_BLOCK_SIZE); + + RTW_DBG_DUMP("gcmp_decipher(): decrypted frame\n", + frame, hdrlen + 8 + plen); + + return _SUCCESS; +} + + +#if defined(CONFIG_IEEE80211W) | defined(CONFIG_TDLS) +u8 _bip_ccmp_protect(const u8 *key, size_t key_len, + const u8 *data, size_t data_len, u8 *mic) +{ + u8 res = _SUCCESS; + + if (key_len == 16) { + if (omac1_aes_128(key, data, data_len, mic)) { + res = _FAIL; + RTW_ERR("%s : omac1_aes_128 fail!", __func__); + } + } else if (key_len == 32) { + if (omac1_aes_256(key, data, data_len, mic)) { + res = _FAIL; + RTW_ERR("%s : omac1_aes_256 fail!", __func__); + } + } else { + RTW_ERR("%s : key_len not match!", __func__); + res = _FAIL; + } + + return res; +} + + +u8 _bip_gcmp_protect(u8 *whdr_pos, size_t len, + const u8 *key, size_t key_len, + const u8 *data, size_t data_len, u8 *mic) +{ + u8 res = _SUCCESS; + u32 mic_len = 16; + u8 nonce[12], *npos; + const u8 *gcmp_ipn; + + gcmp_ipn = whdr_pos + len - mic_len - 6; + + /* Nonce: A2 | IPN */ + _rtw_memcpy(nonce, get_addr2_ptr(whdr_pos), ETH_ALEN); + npos = nonce + ETH_ALEN; + *npos++ = gcmp_ipn[5]; + *npos++ = gcmp_ipn[4]; + *npos++ = gcmp_ipn[3]; + *npos++ = gcmp_ipn[2]; + *npos++ = gcmp_ipn[1]; + *npos++ = gcmp_ipn[0]; + + if (aes_gmac(key, key_len, nonce, sizeof(nonce), + data, data_len, mic)) { + res = _FAIL; + RTW_ERR("%s : aes_gmac fail!", __func__); + } + + return res; +} +#endif /* CONFIG_IEEE80211W */ + + +#ifdef CONFIG_TDLS +void _tdls_generate_tpk(void *sta, const u8 *own_addr, const u8 *bssid) +{ + struct sta_info *psta = (struct sta_info *)sta; + u8 *SNonce = psta->SNonce; + u8 *ANonce = psta->ANonce; + + u8 key_input[SHA256_MAC_LEN]; + const u8 *nonce[2]; + size_t len[2]; + u8 data[3 * ETH_ALEN]; + + /* IEEE Std 802.11z-2010 8.5.9.1: + * TPK-Key-Input = SHA-256(min(SNonce, ANonce) || max(SNonce, ANonce)) + */ + len[0] = 32; + len[1] = 32; + if (_rtw_memcmp2(SNonce, ANonce, 32) < 0) { + nonce[0] = SNonce; + nonce[1] = ANonce; + } else { + nonce[0] = ANonce; + nonce[1] = SNonce; + } + + sha256_vector(2, nonce, len, key_input); + + /* + * TPK = KDF-Hash-Length(TPK-Key-Input, "TDLS PMK", + * min(MAC_I, MAC_R) || max(MAC_I, MAC_R) || BSSID) + */ + + if (_rtw_memcmp2(own_addr, psta->cmn.mac_addr, ETH_ALEN) < 0) { + _rtw_memcpy(data, own_addr, ETH_ALEN); + _rtw_memcpy(data + ETH_ALEN, psta->cmn.mac_addr, ETH_ALEN); + } else { + _rtw_memcpy(data, psta->cmn.mac_addr, ETH_ALEN); + _rtw_memcpy(data + ETH_ALEN, own_addr, ETH_ALEN); + } + + _rtw_memcpy(data + 2 * ETH_ALEN, bssid, ETH_ALEN); + + sha256_prf(key_input, SHA256_MAC_LEN, "TDLS PMK", data, sizeof(data), (u8 *)&psta->tpk, sizeof(psta->tpk)); +} +#endif /* CONFIG_TDLS */ diff --git a/core/rtw_tdls.c b/core/rtw_tdls.c index 2bb1035..d557234 100644 --- a/core/rtw_tdls.c +++ b/core/rtw_tdls.c @@ -930,6 +930,7 @@ u8 *rtw_tdls_set_ch_sw(u8 *pframe, struct pkt_attrib *pattrib, struct sta_info * void rtw_tdls_set_ch_sw_oper_control(_adapter *padapter, u8 enable) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u8 bcn_early_case; if (enable == _TRUE) { #ifdef CONFIG_TDLS_CH_SW_V2 @@ -939,14 +940,18 @@ void rtw_tdls_set_ch_sw_oper_control(_adapter *padapter, u8 enable) #ifdef CONFIG_TDLS_CH_SW_BY_DRV pHalData->ch_switch_offload = _FALSE; #endif + bcn_early_case = TDLS_BCN_ERLY_ON; } - else + else { pHalData->ch_switch_offload = _FALSE; - + bcn_early_case = TDLS_BCN_ERLY_OFF; + } + if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) != enable) ATOMIC_SET(&padapter->tdlsinfo.chsw_info.chsw_on, enable); - rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_BCN_EARLY_C2H_RPT, &enable); + rtw_hal_set_hwreg(padapter, HW_VAR_BCN_EARLY_C2H_RPT, &enable); + rtw_hal_set_hwreg(padapter, HW_VAR_SET_DRV_ERLY_INT, &bcn_early_case); RTW_INFO("[TDLS] %s Bcn Early C2H Report\n", (enable == _TRUE) ? "Start" : "Stop"); } @@ -962,6 +967,7 @@ void rtw_tdls_ch_sw_back_to_base_chnl(_adapter *padapter) rtw_tdls_cmd(padapter, pchsw_info->addr, TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED); } +#ifndef CONFIG_TDLS_CH_SW_V2 static void rtw_tdls_chsw_oper_init(_adapter *padapter, u32 timeout_ms) { struct submit_ctx *chsw_sctx = &padapter->tdlsinfo.chsw_info.chsw_sctx; @@ -982,6 +988,7 @@ void rtw_tdls_chsw_oper_done(_adapter *padapter) rtw_sctx_done(&chsw_sctx); } +#endif s32 rtw_tdls_do_ch_sw(_adapter *padapter, struct sta_info *ptdls_sta, u8 chnl_type, u8 channel, u8 channel_offset, u16 bwmode, u16 ch_switch_time) { @@ -1814,9 +1821,9 @@ int On_TDLS_Dis_Rsp(_adapter *padapter, union recv_frame *precv_frame) issue_tdls_setup_req(padapter, &txmgmt, _FALSE); } } +exit: #endif /* CONFIG_TDLS_AUTOSETUP */ -exit: return ret; } @@ -2199,7 +2206,7 @@ int On_TDLS_Setup_Rsp(_adapter *padapter, union recv_frame *precv_frame, struct if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE) { ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE; - ptdls_sta->state |= _FW_LINKED; + ptdls_sta->state |= WIFI_ASOC_STATE; _cancel_timer_ex(&ptdls_sta->handshake_timer); } @@ -2316,7 +2323,7 @@ int On_TDLS_Setup_Cfm(_adapter *padapter, union recv_frame *precv_frame, struct if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE) { ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE; - ptdls_sta->state |= _FW_LINKED; + ptdls_sta->state |= WIFI_ASOC_STATE; _cancel_timer_ex(&ptdls_sta->handshake_timer); } @@ -2590,6 +2597,7 @@ sint On_TDLS_Ch_Switch_Req(_adapter *padapter, union recv_frame *precv_frame, st j += (pIE->Length + 2); } +#ifndef CONFIG_TDLS_CH_SW_V2 rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk); if (take_care_iqk == _TRUE) { u8 central_chnl; @@ -2604,6 +2612,7 @@ sint On_TDLS_Ch_Switch_Req(_adapter *padapter, union recv_frame *precv_frame, st return _FAIL; } } +#endif /* cancel ch sw monitor timer for responder */ if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE)) @@ -2768,7 +2777,7 @@ void wfd_ie_tdls(_adapter *padapter, u8 *pframe, u32 *pktlen) /* Value: */ /* Associated BSSID */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) _rtw_memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[0], ETH_ALEN); else _rtw_memset(wfdie + wfdielen, 0x00, ETH_ALEN); diff --git a/core/rtw_vht.c b/core/rtw_vht.c index 71ace12..55b1709 100644 --- a/core/rtw_vht.c +++ b/core/rtw_vht.c @@ -32,6 +32,7 @@ const u8 _vht_sup_ch_width_set_to_bw_cap[] = { 0, }; +#ifdef CONFIG_RTW_DEBUG const char *const _vht_sup_ch_width_set_str[] = { "80MHz", "160MHz", @@ -104,40 +105,47 @@ void dump_vht_op_ie(void *sel, const u8 *ie, u32 ie_len) dump_vht_op_ie_content(sel, vht_op_ie + 2, vht_op_ielen); } +#endif /* 20/40/80, ShortGI, MCS Rate */ -const u16 VHT_MCS_DATA_RATE[3][2][30] = { +const u16 VHT_MCS_DATA_RATE[3][2][40] = { /* unit: 0.5M */ { { 13, 26, 39, 52, 78, 104, 117, 130, 156, 156, 26, 52, 78, 104, 156, 208, 234, 260, 312, 312, - 39, 78, 117, 156, 234, 312, 351, 390, 468, 520 + 39, 78, 117, 156, 234, 312, 351, 390, 468, 520, + 52, 104, 156, 208, 312, 416, 468, 520, 624, 624, }, /* Long GI, 20MHz */ { 14, 29, 43, 58, 87, 116, 130, 144, 173, 173, 29, 58, 87, 116, 173, 231, 260, 289, 347, 347, - 43, 87, 130, 173, 260, 347, 390, 433, 520, 578 + 43, 87, 130, 173, 260, 347, 390, 433, 520, 578, + 58, 116, 173, 231, 347, 462, 520, 578, 693, 693, } }, /* Short GI, 20MHz */ { { 27, 54, 81, 108, 162, 216, 243, 270, 324, 360, 54, 108, 162, 216, 324, 432, 486, 540, 648, 720, - 81, 162, 243, 324, 486, 648, 729, 810, 972, 1080 + 81, 162, 243, 324, 486, 648, 729, 810, 972, 1080, + 108, 216, 324, 432, 648, 864, 972, 1080, 1296, 1440, }, /* Long GI, 40MHz */ { 30, 60, 90, 120, 180, 240, 270, 300, 360, 400, 60, 120, 180, 240, 360, 480, 540, 600, 720, 800, - 90, 180, 270, 360, 540, 720, 810, 900, 1080, 1200 + 90, 180, 270, 360, 540, 720, 810, 900, 1080, 1200, + 120, 240, 360, 480, 720, 960, 1080, 1200, 1440, 1600, } }, /* Short GI, 40MHz */ { { - 59, 117, 176, 234, 351, 468, 527, 585, 702, 780, + 59, 117, 176, 234, 351, 468, 527, 585, 702, 780, 117, 234, 351, 468, 702, 936, 1053, 1170, 1404, 1560, - 176, 351, 527, 702, 1053, 1404, 1580, 1755, 2106, 2340 + 176, 351, 527, 702, 1053, 1404, 1580, 1755, 2106, 2340, + 234, 468, 702, 936, 1404, 1872, 2106, 2340, 2808, 3120, }, /* Long GI, 80MHz */ { 65, 130, 195, 260, 390, 520, 585, 650, 780, 867, 130, 260, 390, 520, 780, 1040, 1170, 1300, 1560, 1734, - 195, 390, 585, 780, 1170, 1560, 1755, 1950, 2340, 2600 + 195, 390, 585, 780, 1170, 1560, 1755, 1950, 2340, 2600, + 260, 520, 780, 1040, 1560, 2080, 2340, 2600, 3120, 3467, } } /* Short GI, 80MHz */ }; @@ -209,8 +217,8 @@ void rtw_vht_nss_to_mcsmap(u8 nss, u8 *target_mcs_map, u8 *cur_mcs_map) u16 rtw_vht_mcs_to_data_rate(u8 bw, u8 short_GI, u8 vht_mcs_rate) { - if (vht_mcs_rate > MGN_VHT3SS_MCS9) - vht_mcs_rate = MGN_VHT3SS_MCS9; + if (vht_mcs_rate > MGN_VHT4SS_MCS9) + vht_mcs_rate = MGN_VHT4SS_MCS9; /* RTW_INFO("bw=%d, short_GI=%d, ((vht_mcs_rate - MGN_VHT1SS_MCS0)&0x3f)=%d\n", bw, short_GI, ((vht_mcs_rate - MGN_VHT1SS_MCS0)&0x3f)); */ return VHT_MCS_DATA_RATE[bw][short_GI][((vht_mcs_rate - MGN_VHT1SS_MCS0) & 0x3f)]; } @@ -264,10 +272,13 @@ void rtw_vht_use_default_setting(_adapter *padapter) CLEAR_FLAGS(pvhtpriv->beamform_cap); #ifdef CONFIG_BEAMFORMING #ifdef RTW_BEAMFORMING_VERSION_2 +#ifdef CONFIG_CONCURRENT_MODE /* only enable beamforming in STA client mode */ - if (MLME_IS_STA(padapter) && !MLME_IS_GC(padapter) - && !MLME_IS_ADHOC(padapter) - && !MLME_IS_MESH(padapter)) + if (MLME_IS_STA(padapter) && !MLME_IS_GC(padapter)) +#else + if ((MLME_IS_AP(padapter) && !MLME_IS_GO(padapter)) || + (MLME_IS_STA(padapter) && !MLME_IS_GC(padapter))) +#endif #endif { rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMER, @@ -336,13 +347,13 @@ u64 rtw_vht_mcs_map_to_bitmap(u8 *mcs_map, u8 nss) switch (tmp) { case 2: - bitmap = bitmap | (0x03ff << j); + bitmap = bitmap | ((u64)0x03ff << j); break; case 1: - bitmap = bitmap | (0x01ff << j); + bitmap = bitmap | ((u64)0x01ff << j); break; case 0: - bitmap = bitmap | (0x00ff << j); + bitmap = bitmap | ((u64)0x00ff << j); break; default: break; @@ -562,7 +573,7 @@ void VHT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, tx_nss = 0; + u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, rx_nss = 0; u16 cur_beamform_cap = 0; u8 *pcap_mcs; @@ -663,8 +674,8 @@ void VHT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) pvhtpriv->ampdu_len = GET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pIE->data); pcap_mcs = GET_VHT_CAPABILITY_ELE_RX_MCS(pIE->data); - tx_nss = GET_HAL_TX_NSS(padapter); - rtw_vht_nss_to_mcsmap(tx_nss, pvhtpriv->vht_mcs_map, pcap_mcs); + rx_nss = GET_HAL_RX_NSS(padapter); + rtw_vht_nss_to_mcsmap(rx_nss, pvhtpriv->vht_mcs_map, pcap_mcs); pvhtpriv->vht_highest_rate = rtw_get_vht_highest_rate(pvhtpriv->vht_mcs_map); } @@ -1057,6 +1068,7 @@ void VHTOnAssocRsp(_adapter *padapter) rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MAX_TIME, (u8 *)(&pvhtpriv->vht_highest_rate)); } +#ifdef CONFIG_AP_MODE void rtw_vht_ies_attach(_adapter *padapter, WLAN_BSSID_EX *pnetwork) { struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); @@ -1125,4 +1137,5 @@ void rtw_check_for_vht20(_adapter *adapter, u8 *ies, int ies_len) } } } +#endif /* CONFIG_AP_MODE */ #endif /* CONFIG_80211AC_VHT */ diff --git a/core/rtw_wlan_util.c b/core/rtw_wlan_util.c index 5455bbb..1a0dd02 100644 --- a/core/rtw_wlan_util.c +++ b/core/rtw_wlan_util.c @@ -473,112 +473,6 @@ inline void rtw_set_oper_choffset(_adapter *adapter, u8 offset) adapter_to_dvobj(adapter)->oper_ch_offset = offset; } -u8 rtw_get_offset_by_chbw(u8 ch, u8 bw, u8 *r_offset) -{ - u8 valid = 1; - u8 offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - - if (bw == CHANNEL_WIDTH_20) - goto exit; - - if (bw >= CHANNEL_WIDTH_80 && ch <= 14) { - valid = 0; - goto exit; - } - - if (ch >= 1 && ch <= 4) - offset = HAL_PRIME_CHNL_OFFSET_LOWER; - else if (ch >= 5 && ch <= 9) { - if (*r_offset == HAL_PRIME_CHNL_OFFSET_LOWER || *r_offset == HAL_PRIME_CHNL_OFFSET_UPPER) - offset = *r_offset; /* both lower and upper is valid, obey input value */ - else - offset = HAL_PRIME_CHNL_OFFSET_UPPER; /* default use upper */ - } else if (ch >= 10 && ch <= 13) - offset = HAL_PRIME_CHNL_OFFSET_UPPER; - else if (ch == 14) { - valid = 0; /* ch14 doesn't support 40MHz bandwidth */ - goto exit; - } else if (ch >= 36 && ch <= 177) { - switch (ch) { - case 36: - case 44: - case 52: - case 60: - case 100: - case 108: - case 116: - case 124: - case 132: - case 140: - case 149: - case 157: - case 165: - case 173: - offset = HAL_PRIME_CHNL_OFFSET_LOWER; - break; - case 40: - case 48: - case 56: - case 64: - case 104: - case 112: - case 120: - case 128: - case 136: - case 144: - case 153: - case 161: - case 169: - case 177: - offset = HAL_PRIME_CHNL_OFFSET_UPPER; - break; - default: - valid = 0; - break; - } - } else - valid = 0; - -exit: - if (valid && r_offset) - *r_offset = offset; - return valid; -} - -u8 rtw_get_center_ch(u8 channel, u8 chnl_bw, u8 chnl_offset) -{ - u8 center_ch = channel; - - if (chnl_bw == CHANNEL_WIDTH_80) { - if (channel == 36 || channel == 40 || channel == 44 || channel == 48) - center_ch = 42; - else if (channel == 52 || channel == 56 || channel == 60 || channel == 64) - center_ch = 58; - else if (channel == 100 || channel == 104 || channel == 108 || channel == 112) - center_ch = 106; - else if (channel == 116 || channel == 120 || channel == 124 || channel == 128) - center_ch = 122; - else if (channel == 132 || channel == 136 || channel == 140 || channel == 144) - center_ch = 138; - else if (channel == 149 || channel == 153 || channel == 157 || channel == 161) - center_ch = 155; - else if (channel == 165 || channel == 169 || channel == 173 || channel == 177) - center_ch = 171; - else if (channel <= 14) - center_ch = 7; - } else if (chnl_bw == CHANNEL_WIDTH_40) { - if (chnl_offset == HAL_PRIME_CHNL_OFFSET_LOWER) - center_ch = channel + 2; - else - center_ch = channel - 2; - } else if (chnl_bw == CHANNEL_WIDTH_20) - center_ch = channel; - else - rtw_warn_on(1); - - return center_ch; -} - inline systime rtw_get_on_oper_ch_time(_adapter *adapter) { return adapter_to_dvobj(adapter)->on_oper_ch_time; @@ -750,26 +644,43 @@ void invalidate_cam_all(_adapter *padapter) { struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + u8 bmc_id = rtw_iface_bcmc_id_get(padapter); _irqL irqL; u8 val8 = 0; rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, &val8); _enter_critical_bh(&cam_ctl->lock, &irqL); + rtw_sec_cam_map_clr_all(&cam_ctl->used); + +#ifndef SEC_DEFAULT_KEY_SEARCH + /* for BMC data TX with force camid */ + if (bmc_id != INVALID_SEC_MAC_CAM_ID) { + rtw_sec_cam_map_set(&cam_ctl->used, bmc_id); + if (_rtw_camctl_chk_cap(padapter, SEC_CAP_CHK_EXTRA_SEC)) + rtw_sec_cam_map_set(&cam_ctl->used, bmc_id + 1); + } +#endif + _rtw_memset(dvobj->cam_cache, 0, sizeof(struct sec_cam_ent) * SEC_CAM_ENT_NUM_SW_LIMIT); _exit_critical_bh(&cam_ctl->lock, &irqL); + +#ifdef SEC_DEFAULT_KEY_SEARCH//!BMC TX force camid + /* clear default key related key search setting */ + rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)_FALSE); +#endif } void _clear_cam_entry(_adapter *padapter, u8 entry) { - unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - unsigned char null_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + unsigned char null_sta[6] = {0}; + unsigned char null_key[32] = {0}; rtw_sec_write_cam_ent(padapter, entry, 0, null_sta, null_key); } -inline void write_cam(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key) +inline void _write_cam(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key) { #ifdef CONFIG_WRITE_CACHE_ONLY write_cam_cache(adapter, id , ctrl, mac, key); @@ -779,6 +690,17 @@ inline void write_cam(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key) #endif } +inline void write_cam(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key) +{ + if (ctrl & BIT(9)) { + _write_cam(adapter, id, ctrl, mac, key); + _write_cam(adapter, (id + 1), ctrl | BIT(5), mac, (key + 16)); + RTW_INFO_DUMP("key-0: ", key, 16); + RTW_INFO_DUMP("key-1: ", (key + 16), 16); + } else + _write_cam(adapter, id, ctrl, mac, key); +} + inline void clear_cam_entry(_adapter *adapter, u8 id) { _clear_cam_entry(adapter, id); @@ -1158,7 +1080,7 @@ s16 rtw_camid_search(_adapter *adapter, u8 *addr, s16 kid, s8 gk) return cam_id; } -s16 rtw_get_camid(_adapter *adapter, u8 *addr, s16 kid, u8 gk) +s16 rtw_get_camid(_adapter *adapter, u8 *addr, s16 kid, u8 gk, bool ext_sec) { struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; @@ -1190,12 +1112,21 @@ s16 rtw_get_camid(_adapter *adapter, u8 *addr, s16 kid, u8 gk) for (i = 0; i < cam_ctl->num; i++) { /* bypass default key which is allocated statically */ -#ifndef CONFIG_CONCURRENT_MODE +#ifdef SEC_DEFAULT_KEY_SEARCH if (((i + start_id) % cam_ctl->num) < 4) continue; #endif - if (_rtw_sec_camid_is_used(cam_ctl, ((i + start_id) % cam_ctl->num)) == _FALSE) - break; + if (_rtw_sec_camid_is_used(cam_ctl, ((i + start_id) % cam_ctl->num)) == _FALSE) { + if (ext_sec) { + /* look out continue slot */ + if (((i + 1) < cam_ctl->num) && + (_rtw_sec_camid_is_used(cam_ctl, (((i + 1) + start_id) % cam_ctl->num)) == _FALSE)) + break; + else + continue; + } else + break; + } } if (i == cam_ctl->num) { @@ -1212,7 +1143,7 @@ _exit: return cam_id; } -s16 rtw_camid_alloc(_adapter *adapter, struct sta_info *sta, u8 kid, u8 gk, bool *used) +s16 rtw_camid_alloc(_adapter *adapter, struct sta_info *sta, u8 kid, u8 gk, bool ext_sec, bool *used) { struct mlme_ext_info *mlmeinfo = &adapter->mlmeextpriv.mlmext_info; struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); @@ -1230,7 +1161,7 @@ s16 rtw_camid_alloc(_adapter *adapter, struct sta_info *sta, u8 kid, u8 gk, bool * 1. non-STA mode WEP key * 2. group TX key */ -#ifndef CONFIG_CONCURRENT_MODE +#ifdef SEC_DEFAULT_KEY_SEARCH /* static alloction to default key by key ID when concurrent is not defined */ if (kid > 3) { RTW_PRINT(FUNC_ADPT_FMT" group key with invalid key id:%u\n" @@ -1242,7 +1173,7 @@ s16 rtw_camid_alloc(_adapter *adapter, struct sta_info *sta, u8 kid, u8 gk, bool #else u8 *addr = adapter_mac_addr(adapter); - cam_id = rtw_get_camid(adapter, addr, kid, gk); + cam_id = rtw_get_camid(adapter, addr, kid, gk, ext_sec); if (1) RTW_PRINT(FUNC_ADPT_FMT" group key with "MAC_FMT" assigned cam_id:%u\n" , FUNC_ADPT_ARG(adapter), MAC_ARG(addr), cam_id); @@ -1262,7 +1193,7 @@ s16 rtw_camid_alloc(_adapter *adapter, struct sta_info *sta, u8 kid, u8 gk, bool } addr = get_bssid(&adapter->mlmepriv);/*A2*/ } - cam_id = rtw_get_camid(adapter, addr, kid, gk); + cam_id = rtw_get_camid(adapter, addr, kid, gk, ext_sec); } @@ -1270,6 +1201,8 @@ bitmap_handle: if (cam_id >= 0) { *used = _rtw_sec_camid_is_used(cam_ctl, cam_id); rtw_sec_cam_map_set(&cam_ctl->used, cam_id); + if (ext_sec) + rtw_sec_cam_map_set(&cam_ctl->used, cam_id + 1); } _exit_critical_bh(&cam_ctl->lock, &irqL); @@ -1320,9 +1253,7 @@ inline void rtw_sec_cam_swap(_adapter *adapter, u8 cam_id_a, u8 cam_id_b) if (cam_id_a == cam_id_b) return; -#ifdef CONFIG_CONCURRENT_MODE rtw_mi_update_ap_bmc_camid(adapter, cam_id_a, cam_id_b); -#endif /*setp-1. backup org cam_info*/ _enter_critical_bh(&cam_ctl->lock, &irqL); @@ -1398,9 +1329,12 @@ void rtw_clean_hw_dk_cam(_adapter *adapter) { int i; - for (i = 0; i < 4; i++) - rtw_sec_clr_cam_ent(adapter, i); - /*_clear_cam_entry(adapter, i);*/ + for (i = 0; i < 4; i++) { + if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_WRITE_CAM_NEW_RULE)) + _clear_cam_entry(adapter, i); + else + rtw_sec_clr_cam_ent(adapter, i); + } } void flush_all_cam_entry(_adapter *padapter) @@ -1422,14 +1356,18 @@ void flush_all_cam_entry(_adapter *padapter) rtw_clearstakey_cmd(padapter, psta, _FALSE); } } else if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) { -#if 1 +#ifdef CONFIG_AP_MODE +#ifndef SEC_DEFAULT_KEY_SEARCH int cam_id = -1; u8 *addr = adapter_mac_addr(padapter); + u8 bmc_id = rtw_iface_bcmc_id_get(padapter); while ((cam_id = rtw_camid_search(padapter, addr, -1, -1)) >= 0) { RTW_PRINT("clear wep or group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(addr), cam_id); clear_cam_entry(padapter, cam_id); - rtw_camid_free(padapter, cam_id); + /* clear cam_ctl.used bit for data BMC TX force camid in rtw_release_macid() */ + if (bmc_id == INVALID_SEC_MAC_CAM_ID || cam_id != bmc_id) + rtw_camid_free(padapter, cam_id); } #else /* clear default key */ @@ -1446,13 +1384,12 @@ void flush_all_cam_entry(_adapter *padapter) /* clear default key related key search setting */ rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)_FALSE); #endif +#endif /* CONFIG_AP_MODE */ } #else /*NON CONFIG_CONCURRENT_MODE*/ invalidate_cam_all(padapter); - /* clear default key related key search setting */ - rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)_FALSE); #endif } @@ -1528,6 +1465,21 @@ int WMM_param_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) } +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT +u8 rtw_is_tbtx_capabilty(u8 *p, u8 len){ + int i; + u8 tbtx_cap_ie[8] = {0x00, 0xe0, 0x4c, 0x01, 0x00, 0x00, 0x00, 0x00}; + + for (i = 0; i < len; i++) { + if (*(p + i) != tbtx_cap_ie[i]) + return _FALSE; + else + continue; + } + return _TRUE; +} +#endif + void WMMOnAssocRsp(_adapter *padapter) { u8 ACI, ACM, AIFS, ECWMin, ECWMax, aSifsTime; @@ -1879,7 +1831,7 @@ void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) #ifdef CONFIG_80211N_HT unsigned int i; u8 max_AMPDU_len, min_MPDU_spacing; - u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, cur_beamform_cap = 0, tx_nss = 0; + u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, cur_beamform_cap = 0, rx_nss = 0; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -1930,9 +1882,9 @@ void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) for (i = 0; i < 16; i++) pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= pmlmeext->default_supported_mcs_set[i]; - tx_nss = GET_HAL_TX_NSS(padapter); + rx_nss = GET_HAL_RX_NSS(padapter); - switch (tx_nss) { + switch (rx_nss) { case 1: set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R); break; @@ -1951,7 +1903,7 @@ void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_4R); break; default: - RTW_WARN("rf_type:%d or tx_nss:%u is not expected\n", GET_HAL_RFPATH(padapter), tx_nss); + RTW_WARN("rf_type:%d or rx_nss:%u is not expected\n", GET_HAL_RFPATH(padapter), rx_nss); } if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { @@ -2272,7 +2224,7 @@ int validate_beacon_len(u8 *pframe, u32 len) return _TRUE; } - +#ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT u8 support_rate_ranges[] = { IEEE80211_CCK_RATE_1MB, IEEE80211_CCK_RATE_2MB, @@ -2283,8 +2235,8 @@ u8 support_rate_ranges[] = { IEEE80211_OFDM_RATE_12MB, IEEE80211_OFDM_RATE_18MB, IEEE80211_PBCC_RATE_22MB, + IEEE80211_FREAK_RATE_22_5MB, IEEE80211_OFDM_RATE_24MB, - IEEE80211_PBCC_RATE_33MB, IEEE80211_OFDM_RATE_36MB, IEEE80211_OFDM_RATE_48MB, IEEE80211_OFDM_RATE_54MB, @@ -2343,6 +2295,7 @@ bool rtw_validate_value(u16 EID, u8 *p, u16 len) }; return _TRUE; } +#endif /* CONFIG_CHECK_SPECIFIC_IE_CONTENT */ bool is_hidden_ssid(char *ssid, int len) { @@ -2369,9 +2322,6 @@ void rtw_absorb_ssid_ifneed(_adapter *padapter, WLAN_BSSID_EX *bssid, u8 *pframe u16 subtype = get_frame_sub_type(pframe); _irqL irqL; - if ((!bssid) || (!pframe)) - return; - if (subtype == WIFI_BEACON) { bssid->Reserved[0] = BSS_TYPE_BCN; ie_offset = _BEACON_IE_OFFSET_; @@ -2530,7 +2480,7 @@ int _rtw_get_bcn_keys(u8 *cap_info, u32 buf_len, u8 def_ch, ADAPTER *adapter recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WPA2; rtw_parse_wpa2_ie(elems.rsn_ie - 2, elems.rsn_ie_len + 2, &recv_beacon->group_cipher, &recv_beacon->pairwise_cipher, - &recv_beacon->akm, NULL); + NULL, &recv_beacon->akm, NULL, NULL); } /* checking WPA secon */ else if (elems.wpa_ie && elems.wpa_ie_len) { @@ -2542,14 +2492,24 @@ int _rtw_get_bcn_keys(u8 *cap_info, u32 buf_len, u8 def_ch, ADAPTER *adapter recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WEP; if (adapter) { - if (elems.tim && elems.tim_len) { - struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + if (elems.tim && elems.tim_len) { #ifdef DBG_RX_BCN _rtw_memcpy(pmlmeext->tim, elems.tim, 4); #endif pmlmeext->dtim = elems.tim[1]; } + + /* checking RTW TBTX */ + #ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (elems.tbtx_cap && elems.tbtx_cap_len) { + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if (rtw_is_tbtx_capabilty(elems.tbtx_cap, elems.tbtx_cap_len)) + RTW_DBG("AP support TBTX\n"); + } + #endif } return _TRUE; @@ -2581,6 +2541,7 @@ int rtw_update_bcn_keys_of_network(struct wlan_network *network) void rtw_dump_bcn_keys(void *sel, struct beacon_keys *recv_beacon) { +#if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG) u8 ssid[IW_ESSID_MAX_SIZE + 1]; _rtw_memcpy(ssid, recv_beacon->ssid, recv_beacon->ssid_len); @@ -2595,6 +2556,18 @@ void rtw_dump_bcn_keys(void *sel, struct beacon_keys *recv_beacon) RTW_PRINT_SEL(sel, "sec = %d, group = 0x%x, pair = 0x%x, akm = 0x%08x\n" , recv_beacon->encryp_protocol, recv_beacon->group_cipher , recv_beacon->pairwise_cipher, recv_beacon->akm); +#endif +} + +void rtw_bcn_key_err_fix(struct beacon_keys *cur, struct beacon_keys *recv) +{ + if ((recv->ch == cur->ch) && (recv->bw == cur->bw) && (recv->bw > CHANNEL_WIDTH_20)) { + if ((recv->offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) + && (cur->offset != HAL_PRIME_CHNL_OFFSET_DONT_CARE)) { + RTW_DBG("recv_bcn offset = %d is invalid, try to use cur_bcn offset = %d to replace it !\n", recv->offset, cur->offset); + recv->offset = cur->offset; + } + } } bool rtw_bcn_key_compare(struct beacon_keys *cur, struct beacon_keys *recv) @@ -2639,6 +2612,11 @@ int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len) struct beacon_keys *cur_beacon = &pmlmepriv->cur_beacon_keys; struct beacon_keys recv_beacon; int ret = 0; + u8 ifbmp_m = rtw_mi_get_ap_mesh_ifbmp(Adapter); + u8 ifbmp_s = rtw_mi_get_ld_sta_ifbmp(Adapter); + struct dvobj_priv *dvobj = adapter_to_dvobj(Adapter); + _adapter *pri_adapter = dvobj_get_primary_adapter(dvobj); + struct mlme_ext_priv *pmlmeext = &pri_adapter->mlmeextpriv; if (is_client_associated_to_ap(Adapter) == _FALSE) goto exit_success; @@ -2656,6 +2634,69 @@ int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len) recv_beacon.ssid_len = cur_beacon->ssid_len; } + if (check_fwstate(pmlmepriv, WIFI_CSA_UPDATE_BEACON)) { + u8 u_ch, u_offset, u_bw; + struct sta_info *psta = NULL; + _rtw_memcpy(cur_beacon, &recv_beacon, sizeof(recv_beacon)); + clr_fwstate(pmlmepriv, WIFI_CSA_UPDATE_BEACON); + rtw_mi_get_ch_setting_union(Adapter, &u_ch, &u_bw, &u_offset); + + /* RTW_INFO("u_ch=%d, u_bw=%d, u_offset=%d \n", u_ch, u_bw, u_offset); + RTW_INFO("recv_beacon.ch=%d, recv_beacon.bw=%d, recv_beacon.offset=%d \n", recv_beacon.ch, recv_beacon.bw, recv_beacon.offset); */ + /* rtw_dump_bcn_keys(RTW_DBGDUMP, &recv_beacon); */ + + /* RTW_INFO("_cancel_timer_async csa_timer\n"); */ + _cancel_timer_async(&pmlmeext->csa_timer); + + /* beacon bw/offset is different from CSA IE */ + if((recv_beacon.bw > u_bw) || + ((recv_beacon.offset != HAL_PRIME_CHNL_OFFSET_DONT_CARE) && ((u_offset != HAL_PRIME_CHNL_OFFSET_DONT_CARE)) + && (recv_beacon.offset != u_offset))) { + + /* update ch, bw, offset for all asoc STA ifaces */ + if (ifbmp_s) { + _adapter *iface; + int i; + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (!iface || !(ifbmp_s & BIT(iface->iface_id))) + continue; + + iface->mlmeextpriv.cur_channel = recv_beacon.ch; + iface->mlmeextpriv.cur_bwmode = recv_beacon.bw; + iface->mlmeextpriv.cur_ch_offset = recv_beacon.offset; + iface->mlmepriv.cur_network.network.Configuration.DSConfig = recv_beacon.ch; + } + } + +#ifdef CONFIG_AP_MODE + if (ifbmp_m) { + rtw_change_bss_chbw_cmd(dvobj_get_primary_adapter(dvobj), 0 + , ifbmp_m, 0, recv_beacon.ch, REQ_BW_ORI, REQ_OFFSET_NONE); + } else +#endif + { + #ifdef CONFIG_DFS_MASTER + rtw_dfs_rd_en_decision(dvobj_get_primary_adapter(dvobj), MLME_OPCH_SWITCH, 0); + #endif + rtw_set_chbw_cmd(Adapter, recv_beacon.ch, recv_beacon.bw, recv_beacon.offset, 0); + } + rtw_mi_get_ch_setting_union(Adapter, &u_ch, &u_bw, &u_offset); + + /* RTW_INFO("u_ch=%d, u_bw=%d, u_offset=%d \n", u_ch, u_bw, u_offset); */ + } else { + RTW_INFO("u_ch=%d, u_bw=%d, u_offset=%d, recv_beacon.ch=%d, recv_beacon.bw=%d, recv_beacon.offset=%d\n" + , u_ch, u_bw, u_offset, recv_beacon.ch, recv_beacon.bw, recv_beacon.offset); + } + + rtw_iqk_cmd(Adapter, 0); + psta = rtw_get_stainfo(&Adapter->stapriv, get_bssid(&Adapter->mlmepriv)); + if (psta) + rtw_dm_ra_mask_wk_cmd(Adapter, (u8 *)psta); + + } + #ifdef CONFIG_BCN_CNT_CONFIRM_HDL if (_rtw_memcmp(&recv_beacon, cur_beacon, sizeof(recv_beacon)) == _TRUE) pmlmepriv->new_beacon_cnts = 0; @@ -2690,6 +2731,8 @@ int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len) RTW_INFO(FUNC_ADPT_FMT" new beacon key:\n", FUNC_ADPT_ARG(Adapter)); rtw_dump_bcn_keys(RTW_DBGDUMP, &recv_beacon); + rtw_bcn_key_err_fix(cur_beacon, &recv_beacon); + if (rtw_bcn_key_compare(cur_beacon, &recv_beacon) == _FALSE) goto exit; @@ -2764,9 +2807,11 @@ void update_beacon_info(_adapter *padapter, u8 *pframe, uint pkt_len, struct sta void process_csa_ie(_adapter *padapter, u8 *ies, uint ies_len) { struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); - unsigned int i; - PNDIS_802_11_VARIABLE_IEs pIE; - u8 ch = 0; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + unsigned int i, j, countdown; + PNDIS_802_11_VARIABLE_IEs pIE, sub_pie; + u8 ch = 0, csa_ch_offset = 0, csa_ch_width = 0, csa_ch_freq_seg0 = 0, csa_ch_freq_seg1 = 0, csa_switch_cnt = 0; /* TODO: compare with scheduling CSA */ if (rfctl->csa_ch) @@ -2778,6 +2823,31 @@ void process_csa_ie(_adapter *padapter, u8 *ies, uint ies_len) switch (pIE->ElementID) { case _CH_SWTICH_ANNOUNCE_: ch = *(pIE->data + 1); + csa_switch_cnt = *(pIE->data + 2); + break; + case WLAN_EID_SECONDARY_CHANNEL_OFFSET: + csa_ch_offset = *(pIE->data); + break; + case WLAN_EID_WIDE_BANDWIDTH_CHANNEL_SWITCH: + csa_ch_width = *(pIE->data); + csa_ch_freq_seg0 = *(pIE->data+1); + csa_ch_freq_seg1 = *(pIE->data+2); + /* RTW_INFO("bw:%02x center_freq_0:%d center_freq_1:%d, ch=%d\n" + , csa_ch_width, csa_ch_freq_seg0, csa_ch_freq_seg1, ch); */ + break; + case WLAN_EID_CHANNEL_SWITCH_WRAPPER: + for(j=0; j + 1 < pIE->Length;) { + sub_pie = (PNDIS_802_11_VARIABLE_IEs)(ies + i + j + 2); + if(sub_pie->ElementID == WLAN_EID_WIDE_BANDWIDTH_CHANNEL_SWITCH) { + csa_ch_width = *(sub_pie->data); + csa_ch_freq_seg0 = *(sub_pie->data+1); + csa_ch_freq_seg1 = *(sub_pie->data+2); + /* RTW_INFO("2. sub_IE:%02x IE_length:%02x bw:%02x center_freq_0:%d center_freq_1:%d, ch=%d\n" + , sub_pie->ElementID, sub_pie->Length, csa_ch_width, csa_ch_freq_seg0, csa_ch_freq_seg1, ch); */ + } + j += (sub_pie->Length + 2); + } + break; default: break; @@ -2787,32 +2857,44 @@ void process_csa_ie(_adapter *padapter, u8 *ies, uint ies_len) } if (ch != 0) { + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + _adapter *pri_adapter = dvobj_get_primary_adapter(dvobj); + rfctl->csa_ch = ch; - if (rtw_set_csa_cmd(padapter) != _SUCCESS) - rfctl->csa_ch = 0; + rfctl->csa_switch_cnt = csa_switch_cnt; + rfctl->csa_ch_offset = csa_ch_offset; + rfctl->csa_ch_width = csa_ch_width; + rfctl->csa_ch_freq_seg0 = csa_ch_freq_seg0; + rfctl->csa_ch_freq_seg1 = csa_ch_freq_seg1; + + countdown = pmlmeinfo->network.Configuration.BeaconPeriod * (csa_switch_cnt+1); /* ms */ + RTW_INFO("csa: set countdown timer to %d ms\n", countdown); + _set_timer(&pri_adapter->mlmeextpriv.csa_timer, countdown); + } } #endif /* CONFIG_DFS */ -void parsing_eapol_packet(_adapter *padapter, u8 *key_payload, struct sta_info *psta, u8 trx_type) +enum eap_type parsing_eapol_packet(_adapter *padapter, u8 *key_payload, struct sta_info *psta, u8 trx_type) { struct security_priv *psecuritypriv = &(padapter->securitypriv); struct ieee802_1x_hdr *hdr; struct wpa_eapol_key *key; u16 key_info, key_data_length; char *trx_msg = trx_type ? "send" : "recv"; + enum eap_type eapol_type; hdr = (struct ieee802_1x_hdr *) key_payload; /* WPS - eapol start packet */ if (hdr->type == 1 && hdr->length == 0) { RTW_INFO("%s eapol start packet\n", trx_msg); - return; + return EAPOL_START; } if (hdr->type == 0) { /* WPS - eapol packet */ RTW_INFO("%s eapol packet\n", trx_msg); - return; + return EAPOL_PACKET; } key = (struct wpa_eapol_key *) (hdr + 1); @@ -2822,24 +2904,32 @@ void parsing_eapol_packet(_adapter *padapter, u8 *key_payload, struct sta_info * if (!(key_info & WPA_KEY_INFO_KEY_TYPE)) { /* WPA group key handshake */ if (key_info & WPA_KEY_INFO_ACK) { RTW_PRINT("%s eapol packet - WPA Group Key 1/2\n", trx_msg); + eapol_type = EAPOL_WPA_GROUP_KEY_1_2; } else { RTW_PRINT("%s eapol packet - WPA Group Key 2/2\n", trx_msg); + eapol_type = EAPOL_WPA_GROUP_KEY_2_2; /* WPA key-handshake has completed */ if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPAPSK) psta->state &= (~WIFI_UNDER_KEY_HANDSHAKE); } } else if (key_info & WPA_KEY_INFO_MIC) { - if (key_data_length == 0) + if (key_data_length == 0) { RTW_PRINT("%s eapol packet 4/4\n", trx_msg); - else if (key_info & WPA_KEY_INFO_ACK) + eapol_type = EAPOL_4_4; + } else if (key_info & WPA_KEY_INFO_ACK) { RTW_PRINT("%s eapol packet 3/4\n", trx_msg); - else + eapol_type = EAPOL_3_4; + } else { RTW_PRINT("%s eapol packet 2/4\n", trx_msg); + eapol_type = EAPOL_2_4; + } } else { RTW_PRINT("%s eapol packet 1/4\n", trx_msg); + eapol_type = EAPOL_1_4; } + return eapol_type; } unsigned int is_ap_in_tkip(_adapter *padapter) @@ -3693,7 +3783,6 @@ void dump_macid_map(void *sel, struct macid_bmp *map, u8 max_num) #endif } - inline bool rtw_macid_is_set(struct macid_bmp *map, u8 id) { if (id < 32) @@ -3837,7 +3926,7 @@ inline u8 rtw_iface_bcmc_id_get(_adapter *padapter) return macid_ctl->iface_bmc[padapter->iface_id]; } -#if defined(DBG_CONFIG_ERROR_RESET) && defined(CONFIG_CONCURRENT_MODE) +#if defined(DBG_CONFIG_ERROR_RESET) void rtw_iface_bcmc_sec_cam_map_restore(_adapter *adapter) { struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); @@ -3872,7 +3961,7 @@ void rtw_alloc_macid(_adapter *padapter, struct sta_info *psta) } if (is_bc_sta - #ifdef CONFIG_CONCURRENT_MODE + #ifndef SEC_DEFAULT_KEY_SEARCH && (MLME_IS_STA(padapter) || MLME_IS_NULL(padapter)) #endif ) { @@ -3896,7 +3985,7 @@ void rtw_alloc_macid(_adapter *padapter, struct sta_info *psta) } #endif /* CONFIG_MCC_MODE */ - #ifdef CONFIG_CONCURRENT_MODE + #ifndef SEC_DEFAULT_KEY_SEARCH /* for BMC data TX with force camid */ if (is_bc_sta && rtw_sec_camid_is_used(dvobj_to_sec_camctl(dvobj), i)) continue; @@ -3910,7 +3999,7 @@ void rtw_alloc_macid(_adapter *padapter, struct sta_info *psta) rtw_macid_map_set(used_map, i); - #ifdef CONFIG_CONCURRENT_MODE + #ifndef SEC_DEFAULT_KEY_SEARCH /* for BMC data TX with force camid */ if (is_bc_sta) { struct cam_ctl_t *cam_ctl = dvobj_to_sec_camctl(dvobj); @@ -3918,6 +4007,8 @@ void rtw_alloc_macid(_adapter *padapter, struct sta_info *psta) rtw_macid_map_set(&macid_ctl->bmc, i); rtw_iface_bcmc_id_set(padapter, i); rtw_sec_cam_map_set(&cam_ctl->used, i); + if (_rtw_camctl_chk_cap(padapter, SEC_CAP_CHK_EXTRA_SEC)) + rtw_sec_cam_map_set(&cam_ctl->used, i + 1); } #endif @@ -3998,8 +4089,11 @@ void rtw_release_macid(_adapter *padapter, struct sta_info *psta) struct cam_ctl_t *cam_ctl = dvobj_to_sec_camctl(dvobj); u8 id = rtw_iface_bcmc_id_get(padapter); - if ((id != INVALID_SEC_MAC_CAM_ID) && (id < cam_ctl->num)) + if ((id != INVALID_SEC_MAC_CAM_ID) && (id < cam_ctl->num)) { rtw_sec_cam_map_clr(&cam_ctl->used, id); + if (_rtw_camctl_chk_cap(padapter, SEC_CAP_CHK_EXTRA_SEC)) + rtw_sec_cam_map_clr(&cam_ctl->used, id + 1); + } rtw_iface_bcmc_id_set(padapter, INVALID_SEC_MAC_CAM_ID); } @@ -4145,6 +4239,7 @@ inline void rtw_macid_ctl_init_drop_reg(struct macid_ctl_t *macid_ctl, u16 reg_c macid_ctl->reg_drop_ctrl = reg_ctrl; macid_ctl->reg_drop_info = reg_info; } + #else inline void rtw_macid_ctl_init_sleep_reg(struct macid_ctl_t *macid_ctl, u16 m0, u16 m1, u16 m2, u16 m3) { @@ -4159,6 +4254,7 @@ inline void rtw_macid_ctl_init_sleep_reg(struct macid_ctl_t *macid_ctl, u16 m0, macid_ctl->reg_sleep_m3 = m3; #endif } + inline void rtw_macid_ctl_init_drop_reg(struct macid_ctl_t *macid_ctl, u16 m0, u16 m1, u16 m2, u16 m3) { macid_ctl->reg_drop_m0 = m0; @@ -4676,10 +4772,12 @@ void rtw_dump_priv_pattern(_adapter *adapter, u8 idx) void rtw_wow_pattern_sw_dump(_adapter *adapter) { - int i; + int i = 0, total = 0; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); + total = pwrpriv->wowlan_pattern_idx; RTW_INFO("********[RTK priv-patterns]*********\n"); - for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) + for (i = 0 ; i < total; i++) rtw_dump_priv_pattern(adapter, i); } @@ -4697,10 +4795,14 @@ void rtw_get_sec_iv(PADAPTER padapter, u8 *pcur_dot11txpn, u8 *StaAddr) StaAddr[3], StaAddr[4], StaAddr[5]); if (psta) { - if (psecpriv->dot11PrivacyAlgrthm == _AES_) + if ((psecpriv->dot11PrivacyAlgrthm == _AES_) || + (psecpriv->dot11PrivacyAlgrthm == _CCMP_256_)) AES_IV(pcur_dot11txpn, psta->dot11txpn, 0); else if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) TKIP_IV(pcur_dot11txpn, psta->dot11txpn, 0); + else if ((psecpriv->dot11PrivacyAlgrthm == _GCMP_) || + (psecpriv->dot11PrivacyAlgrthm == _GCMP_256_)) + GCMP_IV(pcur_dot11txpn, psta->dot11txpn, 0); RTW_INFO("%s(): CurrentIV: %02x %02x %02x %02x %02x %02x %02x %02x\n" , __func__, pcur_dot11txpn[0], pcur_dot11txpn[1], @@ -4708,8 +4810,281 @@ void rtw_get_sec_iv(PADAPTER padapter, u8 *pcur_dot11txpn, u8 *StaAddr) pcur_dot11txpn[5], pcur_dot11txpn[6], pcur_dot11txpn[7]); } } + +#ifdef CONFIG_WAR_OFFLOAD +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) +void rtw_wow_war_mdns_dump_buf(struct seq_file *m, u8 *title, u8 *buf, u32 len) +{ + u32 i; + + RTW_PRINT_SEL(m, "\t%s (%d)\n\t\t", title, len); + for (i = 1; i <= len; i++) + { + RTW_PRINT_SEL(m, "%2.2x-", *(buf + i - 1)); + if( (i%16 == 0) && (len != i) ) RTW_PRINT_SEL(m, "\n\t\t"); + } + RTW_PRINT_SEL(m, "\n\n"); +} + +void rtw_wow_war_mdns_dump_txt(struct seq_file *m, u8 *title, u8 *buf, u32 len) +{ + u16 idx=1, offset=0; /* offset = the location of L in the Length.Value */ + + RTW_PRINT_SEL(m, "\t%s (%d)\n\t", title, len); + for (; offset < len; idx++) + { + int item_len = buf[offset]; + u8 item_buf[256]={0}; + + _rtw_memcpy(item_buf, (buf + offset + 1), item_len); + RTW_PRINT_SEL(m, "\t[%d] => %s (%d)\n\t", idx, item_buf, item_len); + _rtw_memset(item_buf, 0, sizeof(item_buf)); + offset += (1+item_len); + } + RTW_PRINT_SEL(m, "\n\n"); +} + +bool rtw_wow_war_mdns_parser_pattern(u8 *input, char *target, + u32 *target_len, u32 type) +{ + char *cp = NULL, *end = NULL; + size_t len = 0; + int pos = 0, mask_pos = 0, res = 0; + u8 member[2] = {0}; + + /* reset */ + _rtw_memset(target, '\0', type); + (*target_len) = 0; + + cp = strchr(input, '='); + if (cp) { + *cp = 0; + cp++; + input = cp; + } + + while (1) { + cp = strchr(input, ':'); + + if (cp) { + len = strlen(input) - strlen(cp); + *cp = 0; + cp++; + } else + len = 2; + + { + u8 hex,idx=0, pos_in_unit_as_4bit = 0; + + strncpy(member, input, len); + res = sscanf(member, "%02hhx", &hex); + + target[pos] = hex; + + /* RTW_INFO("==> in; input-member = %s, hex = %x, target[%d] = %x\n", member, hex, target[pos], pos); */ + + for(idx = 0; idx<2;idx++) + { + pos_in_unit_as_4bit = pos*2 + (1-idx); + mask_pos = (pos_in_unit_as_4bit /8); + + if(!IsHexDigit(member[idx])) + { + RTW_ERR("%s:[ERROR] pattern is invalid!!(%c)\n",__func__, member[idx]); + goto error; + } + + /* RTW_INFO("==> in; pos = %d, pos_in_unit_as_4bit = %d, mask-pos = %d \n", pos, pos_in_unit_as_4bit, mask_pos); + RTW_INFO("==> in; hex(0x%02x), member(%c%c) \n", pattern[pos], member[1], member[0]); */ + } + /* RTW_INFO_DUMP("Pattern Mask: ",bit_mask, 6); */ + } + + pos++; + if (!cp) + break; + input = cp; + } + + (*target_len) = pos; + + return _TRUE; +error: + return _FALSE; + +} + +static struct war_mdns_service_info default_sinfo[] = { +/* example of default setting */ + RTW_MDNS_SRV_INFO("_ipp", 4, "_tcp", 4, "local", 5, 0x02, 0x77, 7200, "KM1", 3, 0), + RTW_MDNS_SRV_INFO("_ipps", 5, "_tcp", 4, "local", 5, 0x02, 0x77, 7200, "KM2", 3, 0), + RTW_MDNS_SRV_INFO("_http", 5, "_tcp", 4, "local", 5, 0x00, 0x50, 7200, "KM3", 3, 2), + RTW_MDNS_SRV_INFO("_privet", 7, "_tcp", 4, "local", 5, 0x00, 0x50, 7200, "KM4", 3, 3), + RTW_MDNS_SRV_INFO("_https", 6, "_tcp", 4, "local", 5, 0x01, 0xbb, 7200, "KM5", 3, 2), + RTW_MDNS_SRV_INFO("_uscan", 6, "_tcp", 4, "local", 5, 0x1f, 0x91, 7200, "KM6", 3, 4), + RTW_MDNS_SRV_INFO("_printer", 8, "_tcp", 4, "local", 5, 0x23, 0x8c, 7200, "KM7", 3, 1), + RTW_MDNS_SRV_INFO("_pdl-datastream", 15, "_tcp", 4, "local", 5, 0x23, 0x8c, 7200, "KM8", 3, 1) + +}; + +void rtw_wow_war_mdns_parms_reset(_adapter *adapter, u8 is_set_default) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); + u8 i =0; + u16 offset=0; + u8 default_domain_name[] = "Generic"; + //u8 default_machine_name[] = { 0x0a, 0x5f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x04, 0x5f, 0x73, 0x75, 0x62 }; + //u8 default_machine_name_len = 16; + u8 default_machine_name[] = { 0x0a, 0x5f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c}; /* length : 10 name : _universal */ + u8 default_machine_name_len = 11; + + /* set default txt value*/ + char *default_txt_rsp_0_for_serive[2] = { "_ipp", "_ipps" }; + char *default_txt_rsp_0[25] = { + "txtvers=1", "qtotal=1", "usb_MFG=KONICA MINOLTA", "usb_MDL=C754Series", + "rp=ipp/print","priority=54","tr=Generic 35c-4", "product=DriverName", + "pdl=application/postscript,image/urf,application/octet-stream,image/jpeg", + "adminurl=http://KM00D91C.local./wcd/a_network.xml", + "note=Copy Room", "Transparent=T", "Binary=T", "TBCP=T", + "URF=V1,4,w8,SRGB24,ADOBERGB24-48,DEVW8,DEVRGB24,DEVCMYK32,RS150000000,IS19-20-21,MT1-3,OB1,PQ4,DM1,FN3-14,CP255", + "rfo=ipp/faxout", "Fax=T", "Scan=T", "Duplex=T", "Color=T", "air=none", + "Kind=document,envelope,photo", + "PaperMax=tabloid-A3", "UUID=6c183832-69ba-541b-baf6-6d947c144325", "TLS=1.2" + }; + + char *default_txt_rsp_1_for_serive[2] = { "_printer", "_pdl-datastream" }; + char *default_txt_rsp_1[13] = { + "txtvers=1", "qtotal=1", "usb_MFG=KONICA MINOLTA", "usb_MDL=C754Series", + "rp=print","priority=51","tr=Generic 35c-4", "product=DriverName", + "pdl=application/postscript", "note=Copy Room", "Transparent=T", "Binary=T", "TBCP=F" + }; + + char *default_txt_rsp_2_for_serive[2] = { "_http", "_https" }; + char *default_txt_rsp_2[1] = { + "Path=/" + }; + + char *default_txt_rsp_3_for_serive[1] = { "_privet" }; + char *default_txt_rsp_3[5] = { + "txtvers=1", "url=https://www.google.com/cloudprint", + "type=printer", "cs=not-configured","note=Copy Room" + }; + + char *default_txt_rsp_4_for_serive[1] = { "_uscan" }; + char *default_txt_rsp_4[11] = { + "txtvers=1", "vers=2.5", "adminurl=http://KM00D91C.local./wsd/a_network_airprint.xml", + "representation=http://KM00D91C.local./wcd/DeviceIcon_1283png", + "rs=eSCL", "ty=KONICA MINOLTA bishub C287", "note=japan", + "pdl=image/jpeg,image/tiff,application/pdf", + "UUID=dd5454cc-e196-5711-aa1f-35be49a6ca9f", + "cs=color,grayscale,binary", "is=platen,adf,duplex=T" + }; + + + /* reset ===> */ + + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_domain_name, 0, MAX_MDNS_DOMAIN_NAME_LEN); + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_mnane, 0, sizeof(pwrpriv->wowlan_war_offload_mdns_mnane)); + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_service, 0, sizeof(pwrpriv->wowlan_war_offload_mdns_service)); + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_txt_rsp, 0, sizeof(pwrpriv->wowlan_war_offload_mdns_txt_rsp)); + + pwrpriv->wowlan_war_offload_mdns_domain_name_len = 0; + pwrpriv->wowlan_war_offload_mdns_mnane_num = 0; + pwrpriv->wowlan_war_offload_mdns_service_info_num = 0; + pwrpriv->wowlan_war_offload_mdns_txt_rsp_num = 0; + pwrpriv->wowlan_war_offload_mdns_para_cur_size = 0; + pwrpriv->wowlan_war_offload_mdns_rsp_cur_size = 0; + + /* init ===> */ + + if(is_set_default) + { + // domain_name + pwrpriv->wowlan_war_offload_mdns_domain_name_len = strlen(default_domain_name); + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_domain_name, default_domain_name, sizeof(default_domain_name)); + + // machine name + pwrpriv->wowlan_war_offload_mdns_mnane_num = 1; + pwrpriv->wowlan_war_offload_mdns_mnane[0].name_len = default_machine_name_len; + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_mnane[0].name, default_machine_name, default_machine_name_len); + + // service info + pwrpriv->wowlan_war_offload_mdns_service_info_num = 8; + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_service, default_sinfo, sizeof(default_sinfo)); + + // type txt rsp 0~5 + // 0 + for(offset=0, i=0; i<25; i++) + { + pwrpriv->wowlan_war_offload_mdns_txt_rsp[0].txt[offset++] = strlen(default_txt_rsp_0[i]); + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[0].txt + offset, default_txt_rsp_0[i], strlen(default_txt_rsp_0[i])); + offset += strlen(default_txt_rsp_0[i]); + RTW_INFO("==> default_txt_rsp_0[%d]: [%s](%zu), offset(%d)\n", i, default_txt_rsp_0[i], strlen(default_txt_rsp_0[i]), offset); + } + pwrpriv->wowlan_war_offload_mdns_txt_rsp[0].txt_len = offset; + // RTW_INFO("==> offset = %d\n\n", offset); + + + // 1 + for(offset=0, i=0; i<13; i++) + { + pwrpriv->wowlan_war_offload_mdns_txt_rsp[1].txt[offset++] = strlen(default_txt_rsp_1[i]); + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[1].txt + offset, default_txt_rsp_1[i], strlen(default_txt_rsp_1[i])); + offset += strlen(default_txt_rsp_1[i]); + } + pwrpriv->wowlan_war_offload_mdns_txt_rsp[1].txt_len = offset; + // RTW_INFO("==> offset = %d\n\n", offset); + + // 2 + for(offset=0, i=0; i<1; i++) + { + pwrpriv->wowlan_war_offload_mdns_txt_rsp[2].txt[offset++] = strlen(default_txt_rsp_2[i]); + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[2].txt + offset, default_txt_rsp_2[i], strlen(default_txt_rsp_2[i])); + offset += strlen(default_txt_rsp_2[i]); + } + pwrpriv->wowlan_war_offload_mdns_txt_rsp[2].txt_len = offset; + // RTW_INFO("==> offset = %d\n\n", offset); + + // 3 + for(offset=0, i=0; i<5; i++) + { + pwrpriv->wowlan_war_offload_mdns_txt_rsp[3].txt[offset++] = strlen(default_txt_rsp_3[i]); + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[3].txt + offset, default_txt_rsp_3[i], strlen(default_txt_rsp_3[i])); + offset += strlen(default_txt_rsp_3[i]); + } + pwrpriv->wowlan_war_offload_mdns_txt_rsp[3].txt_len = offset; + // RTW_INFO("==> offset = %d\n\n", offset); + + // 4 + for(offset=0, i=0; i<11; i++) + { + pwrpriv->wowlan_war_offload_mdns_txt_rsp[4].txt[offset++] = strlen(default_txt_rsp_4[i]); + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[4].txt + offset, default_txt_rsp_4[i], strlen(default_txt_rsp_4[i])); + offset += strlen(default_txt_rsp_4[i]); + } + pwrpriv->wowlan_war_offload_mdns_txt_rsp[4].txt_len = offset; + // RTW_INFO("==> offset = %d\n\n", offset); + + /* txt_rsp_num is always as MAX_MDNS_TXT_NUM because the input mechanism(new/append) makes the entities are not in order */ + pwrpriv->wowlan_war_offload_mdns_txt_rsp_num = MAX_MDNS_TXT_NUM; + } +} + + +#endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */ +#endif /* CONFIG_WAR_OFFLOAD */ #endif /* CONFIG_WOWLAN */ +inline bool _rtw_wow_chk_cap(_adapter *adapter, u8 cap) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct wow_ctl_t *wow_ctl = &dvobj->wow_ctl; + + if (wow_ctl->wow_cap & cap) + return _TRUE; + return _FALSE; +} + #ifdef CONFIG_PNO_SUPPORT #define CSCAN_TLV_TYPE_SSID_IE 'S' #define CIPHER_IE "key_mgmt=" @@ -4828,9 +5203,7 @@ int rtw_dev_nlo_info_set(struct pno_nlo_info *nlo_info, pno_ssid_t *ssid, int i = 0; struct file *fp; - #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) mm_segment_t fs; - #endif loff_t pos = 0; u8 *source = NULL; long len = 0; @@ -4867,10 +5240,8 @@ int rtw_dev_nlo_info_set(struct pno_nlo_info *nlo_info, pno_ssid_t *ssid, return 0; } - #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) fs = get_fs(); set_fs(KERNEL_DS); - #endif source = rtw_zmalloc(2048); @@ -4880,9 +5251,7 @@ int rtw_dev_nlo_info_set(struct pno_nlo_info *nlo_info, pno_ssid_t *ssid, rtw_mfree(source, 2048); } - #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) set_fs(fs); - #endif filp_close(fp, NULL); RTW_INFO("-%s-\n", __func__); @@ -5060,3 +5429,236 @@ inline void rtw_collect_bcn_info(_adapter *adapter) /*TODO get offset of bcn's timestamp*/ /*pmlmeext->bcn_timestamp;*/ } + +static u32 rtw_get_vht_bitrate(u8 mcs, u8 bw, u8 nss, u8 sgi) +{ + static const u32 base[4][10] = { + { 6500000, + 13000000, + 19500000, + 26000000, + 39000000, + 52000000, + 58500000, + 65000000, + 78000000, + /* not in the spec, but some devices use this: */ + 86500000, + }, + { 13500000, + 27000000, + 40500000, + 54000000, + 81000000, + 108000000, + 121500000, + 135000000, + 162000000, + 180000000, + }, + { 29300000, + 58500000, + 87800000, + 117000000, + 175500000, + 234000000, + 263300000, + 292500000, + 351000000, + 390000000, + }, + { 58500000, + 117000000, + 175500000, + 234000000, + 351000000, + 468000000, + 526500000, + 585000000, + 702000000, + 780000000, + }, + }; + u32 bitrate; + int bw_idx; + + if (mcs > 9) { + RTW_INFO("Invalid mcs = %d\n", mcs); + return 0; + } + + if (nss > 4 || nss < 1) { + RTW_INFO("Now only support nss = 1, 2, 3, 4\n"); + } + + switch (bw) { + case CHANNEL_WIDTH_160: + bw_idx = 3; + break; + case CHANNEL_WIDTH_80: + bw_idx = 2; + break; + case CHANNEL_WIDTH_40: + bw_idx = 1; + break; + case CHANNEL_WIDTH_20: + bw_idx = 0; + break; + default: + RTW_INFO("bw = %d currently not supported\n", bw); + return 0; + } + + bitrate = base[bw_idx][mcs]; + bitrate *= nss; + + if (sgi) + bitrate = (bitrate / 9) * 10; + + /* do NOT round down here */ + return (bitrate + 50000) / 100000; +} + +static u32 rtw_get_ht_bitrate(u8 mcs, u8 bw, u8 sgi) +{ + int modulation, streams, bitrate; + + /* the formula below does only work for MCS values smaller than 32 */ + if (mcs >= 32) { + RTW_INFO("Invalid mcs = %d\n", mcs); + return 0; + } + + if (bw > 1) { + RTW_INFO("Now HT only support bw = 0(20Mhz), 1(40Mhz)\n"); + return 0; + } + + modulation = mcs & 7; + streams = (mcs >> 3) + 1; + + bitrate = (bw == 1) ? 13500000 : 6500000; + + if (modulation < 4) + bitrate *= (modulation + 1); + else if (modulation == 4) + bitrate *= (modulation + 2); + else + bitrate *= (modulation + 3); + + bitrate *= streams; + + if (sgi) + bitrate = (bitrate / 9) * 10; + + return (bitrate + 50000) / 100000; +} + +/** + * @bw: 0(20Mhz), 1(40Mhz), 2(80Mhz), 3(160Mhz) + * @rate_idx: DESC_RATEXXXX & 0x7f + * @sgi: DESC_RATEXXXX >> 7 + * Returns: bitrate in 100kbps + */ +u32 rtw_desc_rate_to_bitrate(u8 bw, u8 rate_idx, u8 sgi) +{ + u32 bitrate; + + if (rate_idx <= DESC_RATE54M){ + u16 ofdm_rate[12] = {10, 20, 55, 110, + 60, 90, 120, 180, 240, 360, 480, 540}; + + bitrate = ofdm_rate[rate_idx]; + } else if ((DESC_RATEMCS0 <= rate_idx) && + (rate_idx <= DESC_RATEMCS31)) { + u8 mcs = rate_idx - DESC_RATEMCS0; + + bitrate = rtw_get_ht_bitrate(mcs, bw, sgi); + } else if ((DESC_RATEVHTSS1MCS0 <= rate_idx) && + (rate_idx <= DESC_RATEVHTSS4MCS9)) { + u8 mcs = (rate_idx - DESC_RATEVHTSS1MCS0) % 10; + u8 nss = ((rate_idx - DESC_RATEVHTSS1MCS0) / 10) + 1; + + bitrate = rtw_get_vht_bitrate(mcs, bw, nss, sgi); + } else { + /* TODO: 60Ghz */ + bitrate = 1; + } + + return bitrate; +} + +#ifdef CONFIG_RTW_MULTI_AP +u8 rtw_get_ch_utilization(_adapter *adapter) +{ + u16 clm = rtw_phydm_clm_ratio(adapter); + u16 nhm = rtw_phydm_nhm_ratio(adapter); + u16 ch_util; + + ch_util = clm / 3 + (2 * (nhm / 3)); + /* For Multi-AP, scaling 0-100 to 0-255 */ + ch_util = 255 * ch_util / 100; + + return (u8)ch_util; +} + +void rtw_ch_util_rpt(_adapter *adapter) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + _adapter *iface; + int i, j; + u8 i_rpts = 0; + u8 *ch_util; + u8 **bssid; + u8 threshold = GET_PRIMARY_ADAPTER(adapter)->ch_util_threshold; + u8 need_rpt = 0; + + if (threshold == 0) + return; + + ch_util = rtw_zmalloc(sizeof(u8) * dvobj->iface_nums); + if (!ch_util) + goto err_out; + bssid = (u8 **) rtw_zmalloc(sizeof(u8 *) * dvobj->iface_nums); + if (!bssid) + goto err_out1; + for (j = 0; j < dvobj->iface_nums; j++) { + *(bssid + j) = (u8 *) rtw_zmalloc(sizeof(u8) * ETH_ALEN); + if (!(*(bssid + j))) + goto err_out2; + } + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if ((iface) && MLME_IS_AP(iface)) { + *(ch_util + i_rpts) = rtw_get_ch_utilization(iface); + _rtw_memcpy(*(bssid + i_rpts), iface->mac_addr, ETH_ALEN); + + if (*(ch_util + i_rpts) > threshold) + need_rpt = 1; + + i_rpts++; + } + } + + if (need_rpt) + rtw_nlrtw_ch_util_rpt(adapter, i_rpts, ch_util, bssid); + + rtw_mfree(ch_util, sizeof(u8) * dvobj->iface_nums); + for (i = 0; i < dvobj->iface_nums; i++) + rtw_mfree(*(bssid + i), ETH_ALEN); + rtw_mfree(bssid, sizeof(u8 *) * dvobj->iface_nums); + + return; + +err_out2: + for (i = 0; i < j; i++) + rtw_mfree(*(bssid + i), sizeof(u8) * ETH_ALEN); + rtw_mfree(bssid, sizeof(sizeof(u8 *) * dvobj->iface_nums)); +err_out1: + rtw_mfree(ch_util, sizeof(u8) * dvobj->iface_nums); +err_out: + RTW_INFO("[%s] rtw_zmalloc fail\n", __func__); +} +#endif + diff --git a/core/rtw_wnm.c b/core/rtw_wnm.c new file mode 100644 index 0000000..293eb86 --- /dev/null +++ b/core/rtw_wnm.c @@ -0,0 +1,1098 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#include +#include + +#ifndef RTW_WNM_DBG + #define RTW_WNM_DBG 0 +#endif +#if RTW_WNM_DBG + #define RTW_WNM_INFO(fmt, arg...) \ + RTW_INFO(fmt, arg) + #define RTW_WNM_DUMP(str, data, len) \ + RTW_INFO_DUMP(str, data, len) +#else + #define RTW_WNM_INFO(fmt, arg...) do {} while (0) + #define RTW_WNM_DUMP(str, data, len) do {} while (0) +#endif + +#ifdef CONFIG_RTW_WNM + +static u32 wnm_defualt_validity_time = 6000; +static u32 wnm_default_disassoc_time = 5000; +static u32 wnm_disassoc_wait_time = 500; + +/* for wifi test, need more validity time to wait scan done */ +static u32 wnm_ext_validity_time = 4000; + +static void rtw_wmn_btm_cache_update(_adapter *padapter, struct btm_req_hdr *phdr) +{ + struct btm_rpt_cache *pcache = &(padapter->mlmepriv.nb_info.btm_cache); + + pcache->dialog_token = phdr->dialog_token; + pcache->req_mode = phdr->req_mode; + pcache->disassoc_timer = le16_to_cpu(phdr->disassoc_timer); + + if (phdr->validity_interval > 0) + pcache->validity_interval = phdr->validity_interval; + + pcache->term_duration.id = phdr->term_duration.id; + pcache->term_duration.len = phdr->term_duration.len; + pcache->term_duration.tsf = le64_to_cpu(phdr->term_duration.tsf); + pcache->term_duration.duration = le16_to_cpu(phdr->term_duration.duration); + + RTW_WNM_INFO("%s: req_mode(0x%02x), disassoc_timer(0x%04x), " + "validity_interval(0x%02x %s), tsf(0x%llx), duration(0x%02x)\n", + __func__, pcache->req_mode, pcache->disassoc_timer, + pcache->validity_interval, (!phdr->validity_interval)?"default":"", + pcache->term_duration.tsf, + pcache->term_duration.duration); + + if (pcache->validity_interval > 0) { + pcache->validity_time = pcache->validity_interval * 100; + #ifdef CONFIG_RTW_MBO + if (rtw_mbo_wifi_logo_test(padapter)) + pcache->validity_time += wnm_ext_validity_time; + #endif + } + + if (pcache->disassoc_timer > 0) { + pcache->disassoc_time= pcache->disassoc_timer * 100; + #ifdef CONFIG_RTW_MBO + if (rtw_mbo_wifi_logo_test(padapter)) + pcache->disassoc_time += wnm_ext_validity_time; + #endif + } + + pcache->req_stime = rtw_get_current_time(); + + RTW_WNM_INFO("%s: validity_time=%u, disassoc_time=%u\n", + __func__, pcache->validity_time, pcache->disassoc_time); +} + +static u8 rtw_wnm_btm_candidate_validity(struct btm_rpt_cache *pcache, u8 flag) +{ + u8 is_validity =_TRUE; + u32 req_validity_time = rtw_get_passing_time_ms(pcache->req_stime); + + if ((flag & BIT(0)) && (req_validity_time > pcache->validity_time)) + is_validity = _FALSE; + + if ((flag & BIT(1)) && (req_validity_time > pcache->disassoc_time)) + is_validity = _FALSE; + + RTW_WNM_INFO("%s : validity=%u, rtime=%u, vtime=%u. dtime=%u\n", + __func__, is_validity, req_validity_time, + pcache->validity_time, pcache->disassoc_time); + return is_validity; +} + +u8 rtw_wmn_btm_rsp_reason_decision(_adapter *padapter, u8* req_mode) +{ + struct recv_priv *precvpriv = &padapter->recvpriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 reason = 0; + + if (!rtw_wnm_btm_diff_bss(padapter)) { + /* Reject - No suitable BSS transition candidates */ + reason = 7; + goto candidate_remove; + } + +#ifdef CONFIG_RTW_80211R + if (rtw_ft_chk_flags(padapter, RTW_FT_BTM_ROAM)) { + /* Accept */ + reason = 0; + goto under_survey; + } +#endif + + if (((*req_mode) & DISASSOC_IMMINENT) == 0) { + /* Reject - Unspecified reject reason */ + reason = 1; + goto candidate_remove; + } + + if (precvpriv->signal_strength_data.avg_val >= pmlmepriv->roam_rssi_threshold) { + reason = 1; + RTW_WNM_INFO("%s : Reject - under high roam rssi(%u, %u) \n", + __func__, precvpriv->signal_strength_data.avg_val, + pmlmepriv->roam_rssi_threshold); + goto candidate_remove; + } + +#ifdef CONFIG_RTW_80211R +under_survey: + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)) { + RTW_WNM_INFO("%s reject due to _FW_UNDER_SURVEY\n", __func__); + reason = 1; + } +#endif + +candidate_remove: + if (reason !=0) + rtw_wnm_reset_btm_candidate(&pmlmepriv->nb_info); + + return reason; +} + +static u32 rtw_wnm_btm_candidates_offset_get(u8* pframe) +{ + u32 offset = 0; + + if (!pframe) + return 0; + + offset += 7; + + /* BSS Termination Duration check */ + if (wnm_btm_bss_term_inc(pframe)) + offset += 12; + + /* Session Information URL check*/ + if (wnm_btm_ess_disassoc_im(pframe)) { + /*URL length field + URL variable length*/ + offset = 1 + *(pframe + offset); + } + + RTW_WNM_INFO("%s : hdr offset=%u\n", __func__, offset); + return offset; +} + +static void rtw_wnm_btm_req_hdr_parsing(u8* pframe, struct btm_req_hdr *phdr) +{ + u8 *pos; + u32 offset = 0; + + if (!pframe || !phdr) + return; + + _rtw_memset(phdr, 0, sizeof(struct btm_req_hdr)); + phdr->dialog_token = wnm_btm_dialog_token(pframe); + phdr->req_mode = wnm_btm_req_mode(pframe); + phdr->disassoc_timer = wnm_btm_disassoc_timer(pframe); + phdr->validity_interval = wnm_btm_valid_interval(pframe); + if (wnm_btm_bss_term_inc(pframe)) { + pos = wnm_btm_term_duration_offset(pframe); + if (*pos == WNM_BTM_TERM_DUR_SUBEID) { + phdr->term_duration.id = *pos; + phdr->term_duration.len = *(pos + 1); + phdr->term_duration.tsf = *((u64*)(pos + 2)); + phdr->term_duration.duration= *((u16*)(pos + 10)); + } else + RTW_WNM_INFO("%s : invaild BSS Termination Duration content!\n", __func__); + } + + RTW_WNM_INFO("WNM: req_mode(0x%02x), disassoc_timer(0x%04x), validity_interval(0x%02x)\n", + phdr->req_mode, phdr->disassoc_timer, phdr->validity_interval); + if (wnm_btm_bss_term_inc(pframe)) + RTW_WNM_INFO("WNM: tsf(0x%llx), duration(0x%4x)\n", + phdr->term_duration.tsf, phdr->term_duration.duration); +} + +u8 rtw_wnm_btm_reassoc_req(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct roam_nb_info *pnb = &(pmlmepriv->nb_info); + u8 breassoc = _FALSE; + + if (_rtw_memcmp(get_my_bssid(&(pmlmeinfo->network)), + pnb->roam_target_addr, ETH_ALEN)) { + RTW_WNM_INFO("%s : bss "MAC_FMT" found in roam_target "MAC_FMT"\n", + __func__, MAC_ARG(get_my_bssid(&(pmlmeinfo->network))), + MAC_ARG(pnb->roam_target_addr)); + + breassoc = _TRUE; + } + + return breassoc; +} + +void rtw_wnm_roam_scan_hdl(void *ctx) +{ + _adapter *padapter = (_adapter *)ctx; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + if (rtw_is_scan_deny(padapter)) + RTW_WNM_INFO("%s: roam scan would abort by scan_deny!\n", __func__); + +#ifdef CONFIG_RTW_80211R + if (rtw_ft_chk_flags(padapter, RTW_FT_BTM_ROAM)) { + pmlmepriv->need_to_roam = _TRUE; + rtw_set_to_roam(padapter, padapter->registrypriv.max_roaming_times); + RTW_WNM_INFO("%s : enable roaming\n", __func__); + } + + rtw_drv_scan_by_self(padapter, RTW_AUTO_SCAN_REASON_ROAM); +#endif +} + +static void rtw_wnm_roam_scan(_adapter *padapter) +{ + struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); + + if (rtw_is_scan_deny(padapter)) { + _cancel_timer_ex(&pnb->roam_scan_timer); + _set_timer(&pnb->roam_scan_timer, 1000); + } else + rtw_wnm_roam_scan_hdl((void *)padapter); +} + +void rtw_wnm_disassoc_chk_hdl(void *ctx) +{ + _adapter *padapter = (_adapter *)ctx; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct roam_nb_info *pnb = &(pmlmepriv->nb_info); + + RTW_WNM_INFO("%s : expired\n", __func__); + if (pnb->disassoc_waiting <= 0 ) { + RTW_WNM_INFO("%s : btm roam is interrupted by disassoc\n", __func__); + return; + } + + pnb->disassoc_waiting = _FALSE; + rtw_wnm_roam_scan(padapter); +} + +u8 rtw_wnm_try_btm_roam_imnt(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct roam_nb_info *pnb = &(pmlmepriv->nb_info); + struct btm_rpt_cache *pcache = &(pnb->btm_cache); + u8 reason = 0, flag = 0; + + if (!rtw_wnm_btm_preference_cap(padapter)) { + RTW_WNM_INFO("%s : no btm candidate can be used!\n", __func__); + return 1; + } + + flag = BIT(0) | BIT(1); + if (!rtw_wnm_btm_candidate_validity(pcache, flag)) + return 1; + +#ifdef CONFIG_RTW_MBO + if (!rtw_mbo_wifi_logo_test(padapter) + && !(pcache->req_mode & DISASSOC_IMMINENT)) { + RTW_WNM_INFO("%s : non-disassoc imminet req\n", __func__); + return 1; + } +#endif + + RTW_WNM_INFO("%s : disassoc_waiting(%d)\n", __func__, pnb->disassoc_waiting); + if (pnb->disassoc_waiting) { + _cancel_timer_ex(&pnb->disassoc_chk_timer); + pnb->disassoc_waiting = _FALSE; + rtw_wnm_roam_scan_hdl((void *)padapter); + } else if (!pnb->disassoc_waiting) + RTW_WNM_INFO("%s : waiting for btm roaming start/finish\n", __func__); + else + reason = 1; + + return reason; +} + +void rtw_wnm_process_btm_req(_adapter *padapter, u8* pframe, u32 frame_len) +{ + struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); + struct btm_req_hdr req_hdr; + u8 *ptr, reason; + u32 elem_len, offset; + + rtw_wnm_btm_req_hdr_parsing(pframe, &req_hdr); + offset = rtw_wnm_btm_candidates_offset_get(pframe); + if (offset == 0) + return; + + if ((frame_len - offset) <= 15) { + RTW_INFO("WNM : Reject - no suitable BSS transition candidates!\n"); + rtw_wnm_issue_action(padapter, + RTW_WLAN_ACTION_WNM_BTM_RSP, 7, req_hdr.dialog_token); + return; + } + + rtw_wmn_btm_cache_update(padapter, &req_hdr); + + ptr = (pframe + offset); + elem_len = (frame_len - offset); + rtw_wnm_btm_candidates_survey(padapter, ptr, elem_len, _TRUE); + reason = rtw_wmn_btm_rsp_reason_decision(padapter, &pframe[3]); + +#ifdef CONFIG_RTW_MBO + /* for wifi-test; AP2 could power-off when BTM-req received */ + if ((reason > 0) && (rtw_mbo_wifi_logo_test(padapter))) { + _rtw_memcpy(pnb->roam_target_addr, pnb->nb_rpt[0].bssid, ETH_ALEN); + RTW_WNM_INFO("%s : used report 0 as roam_target_addr(reason=%u)\n", + __func__, reason); + reason = 0; + pnb->preference_en = _TRUE; + pnb->nb_rpt_valid = _FALSE; + } +#endif + + rtw_wnm_issue_action(padapter, + RTW_WLAN_ACTION_WNM_BTM_RSP, reason, req_hdr.dialog_token); + + if (reason == 0) { + pnb->disassoc_waiting = _TRUE; + _set_timer(&pnb->disassoc_chk_timer, wnm_disassoc_wait_time); + } + +} + +void rtw_wnm_reset_btm_candidate(struct roam_nb_info *pnb) +{ + pnb->preference_en = _FALSE; + _rtw_memset(pnb->roam_target_addr, 0, ETH_ALEN); +} + +void rtw_wnm_reset_btm_cache(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct roam_nb_info *pnb = &(pmlmepriv->nb_info); + struct btm_rpt_cache *pcache = &(pnb->btm_cache); + u8 flag = 0; + + flag |= BIT(0); + if (rtw_wnm_btm_candidate_validity(pcache, flag)) + return; + + rtw_wnm_reset_btm_candidate(pnb); + _rtw_memset(pcache, 0, sizeof(struct btm_rpt_cache)); + pcache->validity_time = wnm_defualt_validity_time; + pcache->disassoc_time= wnm_default_disassoc_time; + +#ifdef CONFIG_RTW_80211R + if (rtw_ft_chk_flags(padapter, RTW_FT_BTM_ROAM)) { + pmlmepriv->need_to_roam = _FALSE; + rtw_set_to_roam(padapter, 0); + RTW_WNM_INFO("%s : disabled roaming\n", __func__); + } +#endif +} + +void rtw_wnm_reset_btm_state(_adapter *padapter) +{ + struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); + + pnb->last_nb_rpt_entries = 0; + pnb->nb_rpt_is_same = _TRUE; + pnb->nb_rpt_valid = _FALSE; + pnb->nb_rpt_ch_list_num = 0; + pnb->disassoc_waiting = -1; + _rtw_memset(&pnb->nb_rpt, 0, sizeof(pnb->nb_rpt)); + _rtw_memset(&pnb->nb_rpt_ch_list, 0, sizeof(pnb->nb_rpt_ch_list)); + rtw_wnm_reset_btm_cache(padapter); +} + +u32 rtw_wnm_btm_rsp_candidates_sz_get( + _adapter *padapter, u8* pframe, u32 frame_len) +{ + u32 num = 0, sz = 0; + u8 status; + u8 *ptr; + + if (!pframe || (frame_len <= 5)) + goto exit; + + status = wnm_btm_rsp_status(pframe); + if (((status != 0) && (status != 6)) || (frame_len < 23)) + goto exit; + + if (status == 0) + num = (frame_len - 5 - ETH_ALEN)/18; + else + num = (frame_len - 5)/18; + sz = sizeof(struct wnm_btm_cant) * num; +exit: + RTW_WNM_INFO("WNM: %u candidates(sz=%u) in BTM rsp\n", num, sz); + return sz; +} + +void rtw_wnm_process_btm_rsp(_adapter *padapter, + u8* pframe, u32 frame_len, struct btm_rsp_hdr *prsp) +{ + prsp->dialog_token = wnm_btm_dialog_token(pframe); + prsp->status = wnm_btm_rsp_status(pframe); + prsp->termination_delay = wnm_btm_rsp_term_delay(pframe); + + if ((pframe == NULL) || (frame_len == 0)) + return; + + prsp->status = *(pframe + 3); + prsp->termination_delay = *(pframe + 4); + + /* no Target BSSID & Candidate in frame */ + if (frame_len <= 5) + return; + + /* accept */ + if ((prsp->status == 0) && (frame_len >= 11)) + _rtw_memcpy(prsp->bssid, (pframe + 5), ETH_ALEN); + + /* STA BSS Transition Candidate List provided, + and at least one NB report exist */ + if (((prsp->status == 0) || (prsp->status == 6)) && (frame_len >= 23)) { + struct wnm_btm_cant cant; + u8 *ptr, *pend; + u32 idx = 0; + + ptr = pframe + 5; + if (prsp->status == 0) + ptr += ETH_ALEN; + + pend = ptr + frame_len; + prsp->candidates_num = 0; + while (ptr < pend) { + if (*ptr != RTW_WLAN_ACTION_WNM_NB_RPT_ELEM) + break; + _rtw_memset(&cant, 0, sizeof(cant)); + cant.nb_rpt.id = *ptr; + cant.nb_rpt.len = *(ptr + 1); + _rtw_memcpy(cant.nb_rpt.bssid, (ptr + 2), ETH_ALEN); + cant.nb_rpt.bss_info = *((u32 *)(ptr + 8)); + cant.nb_rpt.reg_class = *(ptr + 12); + cant.nb_rpt.ch_num = *(ptr + 13); + cant.nb_rpt.phy_type= *(ptr + 14); + + if (*(ptr + 15) == WNM_BTM_CAND_PREF_SUBEID) + cant.preference = *(ptr + 17); + ptr = ptr + cant.nb_rpt.len + 2; + if (prsp->pcandidates) { + prsp->candidates_num++; + _rtw_memcpy((prsp->pcandidates + sizeof(cant) * idx), &cant, sizeof(cant)); + } + + idx++; + RTW_WNM_INFO("WNM: btm rsp candidate bssid("MAC_FMT + ") ,bss_info(0x%04X), reg_class(0x%02X), ch(%d)," + " phy_type(0x%02X), preference(0x%02X)\n", + MAC_ARG(cant.nb_rpt.bssid), cant.nb_rpt.bss_info, + cant.nb_rpt.reg_class, cant.nb_rpt.ch_num, + cant.nb_rpt.phy_type, cant.preference); + if ((prsp->pcandidates) && (prsp->candidates_num > 0)) + RTW_WNM_DUMP("WNM candidates: ", prsp->pcandidates, + (sizeof(struct wnm_btm_cant) * prsp->candidates_num)); + } + } + +} + +void rtw_wnm_hdr_init(_adapter *padapter, + struct xmit_frame *pactionframe, u8 *pmac, + u8 action, u8 **pcontent) +{ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct pkt_attrib *pattrib; + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *pfctrl; + u8 category; + + pattrib = &(pactionframe->attrib); + update_mgntframe_attrib(padapter, pattrib); + _rtw_memset(pactionframe->buf_addr, 0, (WLANHDR_OFFSET + TXDESC_OFFSET)); + + *pcontent = (u8 *)(pactionframe->buf_addr + TXDESC_OFFSET); + pwlanhdr = (struct rtw_ieee80211_hdr *)(*pcontent); + pfctrl = &(pwlanhdr->frame_ctl); + *(pfctrl) = 0; + + _rtw_memcpy(pwlanhdr->addr1, pmac, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + set_frame_sub_type(*pcontent, WIFI_ACTION); + + *pcontent += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + category = RTW_WLAN_CATEGORY_WNM; + *pcontent = rtw_set_fixed_ie(*pcontent, 1, &(category), &(pattrib->pktlen)); + *pcontent = rtw_set_fixed_ie(*pcontent, 1, &(action), &(pattrib->pktlen)); +} + +void rtw_wnm_build_btm_req_ies(_adapter *padapter, + u8 **pframe, struct pkt_attrib *pattrib, + struct btm_req_hdr *phdr, u8 *purl, u32 url_len, + u8 *pcandidates, u8 candidate_cnt) +{ + int i; + + *pframe = rtw_set_fixed_ie(*pframe, 1, + &phdr->dialog_token, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 1, + &phdr->req_mode, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 2, + (u8 *)&phdr->disassoc_timer, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 1, + &phdr->validity_interval, &(pattrib->pktlen)); + + if (phdr->req_mode & BSS_TERMINATION_INCLUDED) { + *pframe = rtw_set_fixed_ie(*pframe, 1, + &phdr->term_duration.id, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 1, + &phdr->term_duration.len, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 8, + (u8 *)&phdr->term_duration.tsf, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 2, + (u8 *)&phdr->term_duration.duration, &(pattrib->pktlen)); + } + + if ((purl != NULL) && (url_len > 0) && + (phdr->req_mode & ESS_DISASSOC_IMMINENT)) { + *pframe = rtw_set_fixed_ie(*pframe, 1, + (u8 *)&url_len, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, + url_len, purl, &(pattrib->pktlen)); + } + + if ((pcandidates != NULL) && (candidate_cnt > 0)) { + for (i=0; inb_rpt); + + *pframe = rtw_set_fixed_ie(*pframe, 1, + &pcandidate->nb_rpt.id, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 1, + &pcandidate->nb_rpt.len, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, ETH_ALEN, + pcandidate->nb_rpt.bssid, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 4, + (u8 *)&pcandidate->nb_rpt.bss_info, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 1, + &pcandidate->nb_rpt.reg_class, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 1, + &pcandidate->nb_rpt.ch_num, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 1, + &pcandidate->nb_rpt.phy_type, &(pattrib->pktlen)); + *pframe = rtw_set_ie(*pframe, WNM_BTM_CAND_PREF_SUBEID, 1, + (u8 *)&pcandidate->preference, &(pattrib->pktlen)); + } + } + +} + +void rtw_wnm_issue_btm_req(_adapter *padapter, + u8 *pmac, struct btm_req_hdr *phdr, u8 *purl, u32 url_len, + u8 *pcandidates, u8 candidate_cnt) +{ + struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + u8 action, *pframe, dialog_token = 0; + + if (!pmac || is_zero_mac_addr(pmac) + || is_broadcast_mac_addr(pmac)) + return ; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + return ; + + rtw_wnm_hdr_init(padapter, pmgntframe, pmac, + RTW_WLAN_ACTION_WNM_BTM_REQ, &pframe); + + pattrib = &(pmgntframe->attrib); + rtw_wnm_build_btm_req_ies(padapter, &pframe, pattrib, + phdr, purl, url_len, pcandidates, candidate_cnt); + + if (0) { + u8 *__p = (u8 *)(pmgntframe->buf_addr + TXDESC_OFFSET); + RTW_WNM_DUMP("WNM BTM REQ :", __p, pattrib->pktlen); + } + + pattrib->last_txcmdsz = pattrib->pktlen; + dump_mgntframe(padapter, pmgntframe); + RTW_INFO("WNM: BSS Transition Management Request sent\n"); +} + +void rtw_wnm_issue_action(_adapter *padapter, + u8 action, u8 reason, u8 dialog) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct xmit_frame *pmgntframe; + struct rtw_ieee80211_hdr *pwlanhdr; + struct pkt_attrib *pattrib; + u8 category, termination_delay, *pframe, dialog_token = 0; +#ifdef CONFIG_RTW_MBO + u8 mbo_trans_rej_res = 1; /* Unspecified reason */ + u8 mbo_notif_req_type ; +#endif + u16 *fctrl; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + return ; + + pattrib = &(pmgntframe->attrib); + update_mgntframe_attrib(padapter, pattrib); + _rtw_memset(pmgntframe->buf_addr, 0, (WLANHDR_OFFSET + TXDESC_OFFSET)); + + pframe = (u8 *)(pmgntframe->buf_addr + TXDESC_OFFSET); + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + set_frame_sub_type(pframe, WIFI_ACTION); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + category = RTW_WLAN_CATEGORY_WNM; + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); + + switch (action) { + case RTW_WLAN_ACTION_WNM_BTM_QUERY: + dialog_token++; + pframe = rtw_set_fixed_ie(pframe, 1, &(dialog_token), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(reason), &(pattrib->pktlen)); + RTW_INFO("WNM: BSS Transition Management Query sent\n"); + break; + case RTW_WLAN_ACTION_WNM_BTM_RSP: + dialog_token = dialog; + termination_delay = 0; + pframe = rtw_set_fixed_ie(pframe, 1, &(dialog_token), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(reason), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(termination_delay), &(pattrib->pktlen)); + if (!reason && !is_zero_mac_addr(pmlmepriv->nb_info.roam_target_addr)) { + pframe = rtw_set_fixed_ie(pframe, 6, + pmlmepriv->nb_info.roam_target_addr, &(pattrib->pktlen)); + } + +#ifdef CONFIG_RTW_MBO + rtw_mbo_build_trans_reject_reason_attr(padapter, + &pframe, pattrib, &mbo_trans_rej_res); +#endif + + RTW_INFO("WNM: BSS Transition Management Response sent(reason:%d)\n", reason); + break; + case RTW_WLAN_ACTION_WNM_NOTIF_REQ: +#ifdef CONFIG_RTW_MBO + dialog_token++; + mbo_notif_req_type = WLAN_EID_VENDOR_SPECIFIC; + pframe = rtw_set_fixed_ie(pframe, 1, &(dialog_token), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(mbo_notif_req_type), &(pattrib->pktlen)); + rtw_mbo_build_wnm_notification(padapter, &pframe, pattrib); + RTW_INFO("WNM: Notification request sent\n"); +#endif + break; + default: + goto exit; + } + + pattrib->last_txcmdsz = pattrib->pktlen; + dump_mgntframe(padapter, pmgntframe); + +exit: + return; +} + +/* argument req_ie@cfg80211_roamed()/cfg80211_connect_result() + is association request IEs format. if driver used reassoc-req format, + RSN IE could not be parsed @supplicant process */ +void rtw_wnm_update_reassoc_req_ie(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u32 dup_len, offset; + u8 *pdup; + + if (!pmlmepriv->assoc_req || !pmlmepriv->assoc_req_len) + return; + + /* total len is assoc req len without Current AP Field*/ + dup_len = pmlmepriv->assoc_req_len - ETH_ALEN; + + /* offset is a len of 80211 header + capability(2B) + listen interval(2B) */ + offset = sizeof(struct rtw_ieee80211_hdr_3addr) + 4; + + pdup = rtw_zmalloc(dup_len); + if (pdup) { + /* remove Current AP Field @reassoc req IE */ + _rtw_memcpy(pdup, pmlmepriv->assoc_req, offset); + _rtw_memcpy(pdup + offset, pmlmepriv->assoc_req + offset + ETH_ALEN, + pmlmepriv->assoc_req_len - offset); + rtw_buf_update(&pmlmepriv->assoc_req, + &pmlmepriv->assoc_req_len, pdup, dup_len); + rtw_mfree(pdup, dup_len); + } +} +#endif /* CONFIG_RTW_WNM */ + +#if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) +void rtw_roam_nb_info_init(_adapter *padapter) +{ + struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); + struct btm_rpt_cache *pcache = &(pnb->btm_cache); + + _rtw_memset(&pnb->nb_rpt, 0, sizeof(pnb->nb_rpt)); + _rtw_memset(&pnb->nb_rpt_ch_list, 0, sizeof(pnb->nb_rpt_ch_list)); + _rtw_memset(&pnb->roam_target_addr, 0, ETH_ALEN); + pnb->nb_rpt_valid = _FALSE; + pnb->nb_rpt_ch_list_num = 0; + pnb->preference_en = _FALSE; + pnb->nb_rpt_is_same = _TRUE; + pnb->last_nb_rpt_entries = 0; + pnb->disassoc_waiting = -1; +#ifdef CONFIG_RTW_WNM + pnb->features = 0; + /* pnb->features |= RTW_WNM_FEATURE_BTM_REQ_EN; */ + +#ifdef CONFIG_PLATFORM_CMAP_INTFS + pnb->features |= RTW_WNM_FEATURE_BTM_REQ_EN; +#endif + + rtw_init_timer(&pnb->roam_scan_timer, + padapter, rtw_wnm_roam_scan_hdl, + padapter); + rtw_init_timer(&pnb->disassoc_chk_timer, + padapter, rtw_wnm_disassoc_chk_hdl, + padapter); + + _rtw_memset(pcache, 0, sizeof(struct btm_rpt_cache)); + pcache->validity_time = wnm_defualt_validity_time; + pcache->disassoc_time= wnm_default_disassoc_time ; +#endif +} + +u8 rtw_roam_nb_scan_list_set( + _adapter *padapter, struct sitesurvey_parm *pparm) +{ + u8 ret = _FALSE; + u32 i; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct roam_nb_info *pnb = &(pmlmepriv->nb_info); + +#ifdef CONFIG_RTW_80211R + if (!rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE) + && !rtw_ft_chk_flags(padapter, RTW_FT_BTM_ROAM)) + return ret; +#endif + + if (!pmlmepriv->need_to_roam) + return ret; + + if ((!pmlmepriv->nb_info.nb_rpt_valid) || (!pnb->nb_rpt_ch_list_num)) + return ret; + + if (!pparm) + return ret; + + rtw_init_sitesurvey_parm(padapter, pparm); + if (rtw_roam_busy_scan(padapter, pnb)) { + pparm->ch_num = 1; + pparm->ch[pmlmepriv->ch_cnt].hw_value = + pnb->nb_rpt_ch_list[pmlmepriv->ch_cnt].hw_value; + pmlmepriv->ch_cnt++; + ret = _TRUE; + + RTW_WNM_INFO("%s: ch_cnt=%u, (%u)hw_value=%u\n", + __func__, pparm->ch_num, pmlmepriv->ch_cnt, + pparm->ch[pmlmepriv->ch_cnt].hw_value); + + if (pmlmepriv->ch_cnt == pnb->nb_rpt_ch_list_num) { + pmlmepriv->nb_info.nb_rpt_valid = _FALSE; + pmlmepriv->ch_cnt = 0; + } + goto set_bssid_list; + } + + pparm->ch_num = (pnb->nb_rpt_ch_list_num > RTW_CHANNEL_SCAN_AMOUNT)? + (RTW_CHANNEL_SCAN_AMOUNT):(pnb->nb_rpt_ch_list_num); + for (i=0; ich_num; i++) { + pparm->ch[i].hw_value = pnb->nb_rpt_ch_list[i].hw_value; + pparm->ch[i].flags = RTW_IEEE80211_CHAN_PASSIVE_SCAN; + } + + pmlmepriv->nb_info.nb_rpt_valid = _FALSE; + pmlmepriv->ch_cnt = 0; + ret = _TRUE; + +set_bssid_list: + rtw_set_802_11_bssid_list_scan(padapter, pparm); + return ret; +} + +static u8 rtw_wnm_nb_elem_parsing( + u8* pdata, u32 data_len, u8 from_btm, + u32 *nb_rpt_num, u8 *nb_rpt_is_same, + struct roam_nb_info *pnb, struct wnm_btm_cant *pcandidates) +{ + u8 bfound = _FALSE, ret = _SUCCESS; + u8 *ptr, *pend, *op; + u32 elem_len, subelem_len, op_len; + u32 i, nb_rpt_entries = 0; + struct nb_rpt_hdr *pie; + struct wnm_btm_cant *pcandidate; + + if ((!pdata) || (!pnb)) + return _FAIL; + + if ((from_btm) && (!pcandidates)) + return _FAIL; + + ptr = pdata; + pend = ptr + data_len; + elem_len = data_len; + subelem_len = (u32)*(pdata+1); + + for (i=0; i < RTW_MAX_NB_RPT_NUM; i++) { + if (((ptr + 7) > pend) || (elem_len < subelem_len)) + break; + + if (*ptr != RTW_WLAN_ACTION_WNM_NB_RPT_ELEM) { + RTW_WNM_INFO("WNM: end of data(0x%2x)!\n", *ptr); + break; + } + + pie = (struct nb_rpt_hdr *)ptr; + if (from_btm) { + op = rtw_get_ie((u8 *)(ptr+15), + WNM_BTM_CAND_PREF_SUBEID, + &op_len, (subelem_len - 15)); + } + + ptr = (u8 *)(ptr + subelem_len + 2); + elem_len -= (subelem_len +2); + subelem_len = *(ptr+1); + if (from_btm) { + pcandidate = (pcandidates + i); + _rtw_memcpy(&pcandidate->nb_rpt, pie, sizeof(struct nb_rpt_hdr)); + if (op && (op_len !=0)) { + pcandidate->preference = *(op + 2); + bfound = _TRUE; + } else + pcandidate->preference = 0; + + RTW_WNM_INFO("WNM: preference check bssid("MAC_FMT + ") ,bss_info(0x%04X), reg_class(0x%02X), ch(%d)," + " phy_type(0x%02X), preference(0x%02X)\n", + MAC_ARG(pcandidate->nb_rpt.bssid), pcandidate->nb_rpt.bss_info, + pcandidate->nb_rpt.reg_class, pcandidate->nb_rpt.ch_num, + pcandidate->nb_rpt.phy_type, pcandidate->preference); + } else { + if (_rtw_memcmp(&pnb->nb_rpt[i], pie, sizeof(struct nb_rpt_hdr)) == _FALSE) + *nb_rpt_is_same = _FALSE; + _rtw_memcpy(&pnb->nb_rpt[i], pie, sizeof(struct nb_rpt_hdr)); + } + nb_rpt_entries++; + } + + if (from_btm) + pnb->preference_en = (bfound)?_TRUE:_FALSE; + + *nb_rpt_num = nb_rpt_entries; + return ret; +} + +/* selection sorting based on preference value + * IN : nb_rpt_entries - candidate num + * IN/OUT : pcandidates - candidate list + * return : TRUE - means pcandidates is updated. + */ +static u8 rtw_wnm_candidates_sorting( + u32 nb_rpt_entries, struct wnm_btm_cant *pcandidates) +{ + u8 updated = _FALSE; + u32 i, j, pos; + struct wnm_btm_cant swap; + struct wnm_btm_cant *pcant_1, *pcant_2; + + if ((!nb_rpt_entries) || (!pcandidates)) + return updated; + + for (i=0; i < (nb_rpt_entries - 1); i++) { + pos = i; + for (j=(i + 1); j < nb_rpt_entries; j++) { + pcant_1 = pcandidates+pos; + pcant_2 = pcandidates+j; + if ((pcant_1->preference) < (pcant_2->preference)) + pos = j; + } + + if (pos != i) { + updated = _TRUE; + _rtw_memcpy(&swap, (pcandidates+i), sizeof(struct wnm_btm_cant)); + _rtw_memcpy((pcandidates+i), (pcandidates+pos), sizeof(struct wnm_btm_cant)); + _rtw_memcpy((pcandidates+pos), &swap, sizeof(struct wnm_btm_cant)); + } + } + return updated; +} + +static void rtw_wnm_nb_info_update( + u32 nb_rpt_entries, u8 from_btm, + struct roam_nb_info *pnb, struct wnm_btm_cant *pcandidates, + u8 *nb_rpt_is_same) +{ + u8 is_found; + u32 i, j; + struct wnm_btm_cant *pcand; + + if (!pnb) + return; + + pnb->nb_rpt_ch_list_num = 0; + for (i=0; inb_rpt[i], &pcand->nb_rpt, + sizeof(struct nb_rpt_hdr)) == _FALSE) + *nb_rpt_is_same = _FALSE; + _rtw_memcpy(&pnb->nb_rpt[i], &pcand->nb_rpt, sizeof(struct nb_rpt_hdr)); + } + + RTW_WNM_INFO("WNM: bssid(" MAC_FMT + ") , bss_info(0x%04X), reg_class(0x%02X), ch_num(%d), phy_type(0x%02X)\n", + MAC_ARG(pnb->nb_rpt[i].bssid), pnb->nb_rpt[i].bss_info, + pnb->nb_rpt[i].reg_class, pnb->nb_rpt[i].ch_num, + pnb->nb_rpt[i].phy_type); + + if (pnb->nb_rpt[i].ch_num == 0) + continue; + + for (j=0; jnb_rpt[i].ch_num == pnb->nb_rpt_ch_list[j].hw_value) { + is_found = _TRUE; + break; + } + } + + if (!is_found) { + pnb->nb_rpt_ch_list[pnb->nb_rpt_ch_list_num].hw_value = pnb->nb_rpt[i].ch_num; + pnb->nb_rpt_ch_list_num++; + } + } +} + +static void rtw_wnm_btm_candidate_select(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); + struct wlan_network *pnetwork; + u8 bfound = _FALSE; + u8 ignore_currrent = _FALSE; + u32 i; + +#ifdef CONFIG_RTW_80211R + if (rtw_ft_chk_flags(padapter, RTW_FT_BTM_ROAM)) + ignore_currrent = _TRUE; +#endif + + for (i = 0; i < pnb->last_nb_rpt_entries; i++) { + if (ignore_currrent && + (_rtw_memcmp(pnb->nb_rpt[i].bssid,\ + padapter->mlmepriv.cur_network.network.MacAddress, ETH_ALEN))) { + RTW_WNM_INFO("WNM : ignore candidate "MAC_FMT" for it's connected(%u)!\n", + MAC_ARG(pnb->nb_rpt[i].bssid), i); + continue; + } + + pnetwork = rtw_find_network( + &(pmlmepriv->scanned_queue), + pnb->nb_rpt[i].bssid); + + if (pnetwork) { + bfound = _TRUE; + break; + } + } + + if (bfound) { + _rtw_memcpy(pnb->roam_target_addr, pnb->nb_rpt[i].bssid, ETH_ALEN); + RTW_INFO("WNM : select btm entry(%d) - %s("MAC_FMT", ch:%u) rssi:%d\n" + , i + , pnetwork->network.Ssid.Ssid + , MAC_ARG(pnetwork->network.MacAddress) + , pnetwork->network.Configuration.DSConfig + , (int)pnetwork->network.Rssi); + } else + _rtw_memset(pnb->roam_target_addr,0, ETH_ALEN); +} + +u32 rtw_wnm_btm_candidates_survey( + _adapter *padapter, u8* pframe, u32 elem_len, u8 from_btm) +{ + struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); + struct wnm_btm_cant *pcandidate_list = NULL; + u8 nb_rpt_is_same = _TRUE; + u32 ret = _FAIL; + u32 nb_rpt_entries = 0; + + if (from_btm) { + u32 mlen = sizeof(struct wnm_btm_cant) * RTW_MAX_NB_RPT_NUM; + pcandidate_list = (struct wnm_btm_cant *)rtw_malloc(mlen); + if (pcandidate_list == NULL) + goto exit; + } + + /*clean the status set last time*/ + _rtw_memset(&pnb->nb_rpt_ch_list, 0, sizeof(pnb->nb_rpt_ch_list)); + pnb->nb_rpt_valid = _FALSE; + if (!rtw_wnm_nb_elem_parsing( + pframe, elem_len, from_btm, + &nb_rpt_entries, &nb_rpt_is_same, + pnb, pcandidate_list)) + goto exit; + + if (nb_rpt_entries != 0) { + if ((from_btm) && (rtw_wnm_btm_preference_cap(padapter))) + rtw_wnm_candidates_sorting(nb_rpt_entries, pcandidate_list); + + rtw_wnm_nb_info_update( + nb_rpt_entries, from_btm, + pnb, pcandidate_list, &nb_rpt_is_same); + } + + RTW_WNM_INFO("nb_rpt_is_same = %d, nb_rpt_entries = %d, last_nb_rpt_entries = %d\n", + nb_rpt_is_same, nb_rpt_entries, pnb->last_nb_rpt_entries); + if ((nb_rpt_is_same == _TRUE) && (nb_rpt_entries == pnb->last_nb_rpt_entries)) + pnb->nb_rpt_is_same = _TRUE; + else { + pnb->nb_rpt_is_same = _FALSE; + pnb->last_nb_rpt_entries = nb_rpt_entries; + } + + if ((from_btm) && (nb_rpt_entries != 0)) + rtw_wnm_btm_candidate_select(padapter); + + pnb->nb_rpt_valid = _TRUE; + ret = _SUCCESS; + +exit: + if (from_btm && pcandidate_list) + rtw_mfree((u8 *)pcandidate_list, sizeof(struct wnm_btm_cant) * RTW_MAX_NB_RPT_NUM); + + return ret; +} + +#endif /*defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) */ + diff --git a/core/rtw_xmit.c b/core/rtw_xmit.c index 7c8a7c1..d51f2a3 100644 --- a/core/rtw_xmit.c +++ b/core/rtw_xmit.c @@ -43,6 +43,9 @@ void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv) _init_txservq(&psta_xmitpriv->bk_q); _init_txservq(&psta_xmitpriv->vi_q); _init_txservq(&psta_xmitpriv->vo_q); +#ifdef CONFIG_RTW_MGMT_QUEUE + _init_txservq(&psta_xmitpriv->mgmt_q); +#endif _rtw_init_listhead(&psta_xmitpriv->legacy_dz); _rtw_init_listhead(&psta_xmitpriv->apsd); @@ -92,12 +95,15 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, _adapter *padapter) _rtw_init_queue(&pxmitpriv->bk_pending); _rtw_init_queue(&pxmitpriv->vi_pending); _rtw_init_queue(&pxmitpriv->vo_pending); - _rtw_init_queue(&pxmitpriv->bm_pending); + _rtw_init_queue(&pxmitpriv->mgmt_pending); /* _rtw_init_queue(&pxmitpriv->legacy_dz_queue); */ /* _rtw_init_queue(&pxmitpriv->apsd_queue); */ _rtw_init_queue(&pxmitpriv->free_xmit_queue); +#ifdef CONFIG_LAYER2_ROAMING + _rtw_init_queue(&pxmitpriv->rpkt_queue); +#endif /* Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME, @@ -362,7 +368,7 @@ void rtw_mfree_xmit_priv_lock(struct xmit_priv *pxmitpriv) _rtw_spinlock_free(&pxmitpriv->bk_pending.lock); _rtw_spinlock_free(&pxmitpriv->vi_pending.lock); _rtw_spinlock_free(&pxmitpriv->vo_pending.lock); - _rtw_spinlock_free(&pxmitpriv->bm_pending.lock); + _rtw_spinlock_free(&pxmitpriv->mgmt_pending.lock); /* _rtw_spinlock_free(&pxmitpriv->legacy_dz_queue.lock); */ /* _rtw_spinlock_free(&pxmitpriv->apsd_queue.lock); */ @@ -420,7 +426,9 @@ void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv) /* free xmit extension buff */ _rtw_spinlock_free(&pxmitpriv->free_xmit_extbuf_queue.lock); - +#ifdef CONFIG_LAYER2_ROAMING + _rtw_spinlock_free(&pxmitpriv->rpkt_queue.lock); +#endif pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf; for (i = 0; i < NR_XMIT_EXTBUFF; i++) { rtw_os_xmit_resource_free(padapter, pxmitbuf, (MAX_XMIT_EXTBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE); @@ -677,7 +685,7 @@ void rtw_update_tx_rate_bmp(struct dvobj_priv *dvobj) /* TODO: per rfpath and rate section handling? */ if (update_ht_rs == _TRUE || update_vht_rs == _TRUE) - rtw_hal_set_tx_power_level(dvobj_get_primary_adapter(dvobj), hal_data->current_channel); + rtw_hal_update_txpwr_level(adapter); } #endif /* CONFIG_TXPWR_LIMIT */ } @@ -721,7 +729,7 @@ u8 rtw_get_tx_bw_bmp_of_vht_rate(struct dvobj_priv *dvobj, u8 rate, u8 max_bw) goto exit; } - rate_bmp = 1ULL << (rate - MGN_VHT1SS_MCS0); + rate_bmp = BIT_ULL(rate - MGN_VHT1SS_MCS0); if (max_bw > CHANNEL_WIDTH_160) max_bw = CHANNEL_WIDTH_160; @@ -736,7 +744,7 @@ exit: return bw_bmp; } -s16 rtw_adapter_get_oper_txpwr_max_mbm(_adapter *adapter) +s16 rtw_adapter_get_oper_txpwr_max_mbm(_adapter *adapter, bool eirp) { s16 mbm = -100 * MBM_PDBM; @@ -771,20 +779,19 @@ s16 rtw_adapter_get_oper_txpwr_max_mbm(_adapter *adapter) bmp_vht |= BIT(hw_rate - DESC_RATEVHTSS1MCS0); mbm = phy_get_txpwr_total_max_mbm(adapter - , bw, cch, ch, bmp_cck_ofdm, bmp_ht, bmp_vht); + , bw, cch, ch, bmp_cck_ofdm, bmp_ht, bmp_vht, 0, eirp); } return mbm; } -s16 rtw_get_oper_txpwr_max_mbm(struct dvobj_priv *dvobj) +s16 rtw_rfctl_get_oper_txpwr_max_mbm(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, u8 ifbmp_mod, u8 if_op, bool eirp) { - struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); + struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl); _adapter *adapter = dvobj_get_primary_adapter(dvobj); s16 mbm = -100 * MBM_PDBM; - u8 ch, bw, offset; - if (rtw_mi_get_ch_setting_union(adapter, &ch, &bw, &offset)) { + if (ch) { u8 cch = rtw_get_center_ch(ch, bw, offset); u16 bmp_cck_ofdm = 0; u32 bmp_ht = 0; @@ -792,17 +799,27 @@ s16 rtw_get_oper_txpwr_max_mbm(struct dvobj_priv *dvobj) int i; for (i = 0; i < dvobj->iface_nums; i++) { - if (dvobj->padapters[i] && MLME_IS_ASOC(dvobj->padapters[i])) { - struct mlme_ext_priv *mlmeext = &(dvobj->padapters[i]->mlmeextpriv); - u8 hw_rate = MRateToHwRate(mlmeext->tx_rate); + struct mlme_ext_priv *mlmeext; + u8 hw_rate; - if (IS_LEGACY_HRATE(hw_rate)) - bmp_cck_ofdm |= BIT(hw_rate); - else if (IS_HT_HRATE(hw_rate)) - bmp_ht |= BIT(hw_rate - DESC_RATEMCS0); - else if (IS_VHT_HRATE(hw_rate)) - bmp_vht |= BIT(hw_rate - DESC_RATEVHTSS1MCS0); - } + if (!dvobj->padapters[i]) + continue; + + if (ifbmp_mod & BIT(i)) { + if (!if_op) + continue; + } else if (!MLME_IS_ASOC(dvobj->padapters[i])) + continue; + + mlmeext = &(dvobj->padapters[i]->mlmeextpriv); + hw_rate = MRateToHwRate(mlmeext->tx_rate); + + if (IS_LEGACY_HRATE(hw_rate)) + bmp_cck_ofdm |= BIT(hw_rate); + else if (IS_HT_HRATE(hw_rate)) + bmp_ht |= BIT(hw_rate - DESC_RATEMCS0); + else if (IS_VHT_HRATE(hw_rate)) + bmp_vht |= BIT(hw_rate - DESC_RATEVHTSS1MCS0); } bmp_cck_ofdm |= rfctl->rate_bmp_cck_ofdm; @@ -812,12 +829,92 @@ s16 rtw_get_oper_txpwr_max_mbm(struct dvobj_priv *dvobj) bmp_vht |= rfctl->rate_bmp_vht_by_bw[i]; mbm = phy_get_txpwr_total_max_mbm(adapter - , bw, cch, ch, bmp_cck_ofdm, bmp_ht, bmp_vht); + , bw, cch, ch, bmp_cck_ofdm, bmp_ht, bmp_vht, 0, eirp); } return mbm; } +s16 rtw_get_oper_txpwr_max_mbm(struct dvobj_priv *dvobj, bool eirp) +{ + struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); + _adapter *adapter = dvobj_get_primary_adapter(dvobj); + s16 mbm = -100 * MBM_PDBM; + u8 ch = rfctl->op_ch, bw, offset; + + if (rtw_get_bw_offset_by_op_class_ch(rfctl->op_class, ch, &bw, &offset)) + mbm = rtw_rfctl_get_oper_txpwr_max_mbm(rfctl, ch, bw, offset, 0, 0, eirp); + + return mbm; +} + +s16 rtw_rfctl_get_reg_max_txpwr_mbm(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, bool eirp) +{ + struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl); + struct registry_priv *regsty = dvobj_to_regsty(dvobj); + _adapter *adapter = dvobj_get_primary_adapter(dvobj); + s16 mbm = -100 * MBM_PDBM; + u8 cch = rtw_get_center_ch(ch, bw, offset); + u16 bmp_cck_ofdm = 0; + u32 bmp_ht = 0; + u64 bmp_vht = 0; + + if (ch <= 14) + bmp_cck_ofdm |= RATE_BMP_CCK; + + /* TODO: NO OFDM? */ + bmp_cck_ofdm |= RATE_BMP_OFDM; + +#ifdef CONFIG_80211N_HT + if (regsty->ht_enable && is_supported_ht(regsty->wireless_mode)) { + switch (GET_HAL_TX_NSS(adapter)) { + case 1: + bmp_ht |= RATE_BMP_HT_1SS; + break; + case 2: + bmp_ht |= RATE_BMP_HT_2SS | RATE_BMP_HT_1SS; + break; + case 3: + bmp_ht |= RATE_BMP_HT_3SS | RATE_BMP_HT_2SS | RATE_BMP_HT_1SS; + break; + case 4: + bmp_ht |= RATE_BMP_HT_4SS | RATE_BMP_HT_3SS | RATE_BMP_HT_2SS | RATE_BMP_HT_1SS; + break; + default: + rtw_warn_on(1); + } + } +#endif + +#ifdef CONFIG_80211AC_VHT + if (ch > 14 && REGSTY_IS_11AC_ENABLE(regsty) && is_supported_vht(regsty->wireless_mode) + && (!rfctl->country_ent || COUNTRY_CHPLAN_EN_11AC(rfctl->country_ent)) + ) { + switch (GET_HAL_TX_NSS(adapter)) { + case 1: + bmp_vht |= RATE_BMP_VHT_1SS; + break; + case 2: + bmp_vht |= RATE_BMP_VHT_2SS | RATE_BMP_VHT_1SS; + break; + case 3: + bmp_vht |= RATE_BMP_VHT_3SS | RATE_BMP_VHT_2SS | RATE_BMP_VHT_1SS; + break; + case 4: + bmp_vht |= RATE_BMP_VHT_4SS | RATE_BMP_VHT_3SS | RATE_BMP_VHT_2SS | RATE_BMP_VHT_1SS; + break; + default: + rtw_warn_on(1); + } + } +#endif + + mbm = phy_get_txpwr_total_max_mbm(adapter + , bw, cch, ch, bmp_cck_ofdm, bmp_ht, bmp_vht, 1, eirp); + + return mbm; +} + u8 query_ra_short_GI(struct sta_info *psta, u8 bw) { u8 sgi = _FALSE, sgi_20m = _FALSE, sgi_40m = _FALSE, sgi_80m = _FALSE; @@ -847,14 +944,45 @@ u8 query_ra_short_GI(struct sta_info *psta, u8 bw) return sgi; } +/* This function references driver insmond parameters to decide vcs mode. */ +/* Driver insmond parameters: rtw_vrtl_carrier_sense and rtw_vcs_type */ +static u8 validate_vcs(_adapter *padapter, u8 mode) { + + u8 vcs_mode = NONE_VCS; + + switch(padapter->registrypriv.vrtl_carrier_sense) { + + case DISABLE_VCS: + vcs_mode = NONE_VCS; + break; + + case ENABLE_VCS: + vcs_mode = padapter->registrypriv.vcs_type; + break; + + case AUTO_VCS: + vcs_mode = mode; + break; + + default: + vcs_mode = NONE_VCS; + break; + } + + return vcs_mode; + +} + static void update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitframe) { u32 sz; struct pkt_attrib *pattrib = &pxmitframe->attrib; - /* struct sta_info *psta = pattrib->psta; */ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - + #ifdef RTW_FORCE_CTS_TO_SELF_UNDER_LOW_RSSI + s8 rssi = 0; + struct sta_info *psta = pattrib->psta; + #endif /* if(pattrib->psta) { @@ -872,9 +1000,9 @@ static void update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitf return; } - if(!(psta->state &_FW_LINKED)) + if(!(psta->state &WIFI_ASOC_STATE)) { - RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state); return; } */ @@ -921,7 +1049,6 @@ static void update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitf break; } - /* check ERP protection */ if (pattrib->rtsen || pattrib->cts2self) { if (pattrib->rtsen) @@ -959,8 +1086,18 @@ static void update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitf pattrib->vcs_mode = NONE_VCS; break; } + #ifdef RTW_FORCE_CTS_TO_SELF_UNDER_LOW_RSSI + /*RTStoCTS while let TP degree ,while enable full BW*/ + if (psta != NULL) { + rssi = psta->cmn.rssi_stat.rssi; + if ((rssi < 18) && (pattrib->vcs_mode == RTS_CTS)) + pattrib->vcs_mode = CTS_TO_SELF; + } + #endif } + pattrib->vcs_mode = validate_vcs(padapter, pattrib->vcs_mode); + /* for debug : force driver control vrtl_carrier_sense. */ if (padapter->driver_vcs_en == 1) { /* u8 driver_vcs_en; */ /* Enable=1, Disable=0 driver control vrtl_carrier_sense. */ @@ -1076,7 +1213,7 @@ static void update_attrib_phy_info(_adapter *padapter, struct pkt_attrib *pattri pattrib->retry_ctrl = _FALSE; } -static s32 update_attrib_sec_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta) +static s32 update_attrib_sec_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta, enum eap_type eapol_type) { sint res = _SUCCESS; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -1087,7 +1224,22 @@ static s32 update_attrib_sec_info(_adapter *padapter, struct pkt_attrib *pattrib _rtw_memset(pattrib->dot11tkiptxmickey.skey, 0, 16); pattrib->mac_id = psta->cmn.mac_id; - if (psta->ieee8021x_blocked == _TRUE) { + /* Comment by Owen at 2020/05/19 + * Issue: RTK STA sends encrypted 4-way 4/4 when AP thinks the 4-way incomplete + * In TCL pressure test, AP may resend 4-way 3/4 with new replay counter in 2 ms. + * In this situation, STA sends unencrypted 4-way 4/4 with old replay counter after more + * than 2 ms, followed by the encrypted 4-way 4/4 with new replay counter. Because the + * AP only accepts unencrypted 4-way 4/4 with a new play counter, and the STA encrypts + * each 4-way 4/4 at this time, the 4-way handshake cannot be completed. + * So we modified that after STA receives unencrypted 4-way 1/4 and 4-way 3/4, + * 4-way 2/4 and 4-way 4/4 sent by STA in the next 100 ms are not encrypted. + */ + if (psta->ieee8021x_blocked == _TRUE || + ((eapol_type == EAPOL_2_4 || eapol_type == EAPOL_4_4) && + rtw_get_passing_time_ms(psta->resp_nonenc_eapol_key_starttime) <= 100)) { + + if (eapol_type == EAPOL_2_4 || eapol_type == EAPOL_4_4) + RTW_INFO("Respond unencrypted eapol key\n"); pattrib->encrypt = 0; @@ -1178,6 +1330,31 @@ static s32 update_attrib_sec_info(_adapter *padapter, struct pkt_attrib *pattrib break; + case _GCMP_: + case _GCMP_256_: + + pattrib->iv_len = 8; + pattrib->icv_len = 16; + + if (bmcast) + GCMP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + else + GCMP_IV(pattrib->iv, psta->dot11txpn, 0); + + break; + + case _CCMP_256_: + + pattrib->iv_len = 8; + pattrib->icv_len = 16; + + if (bmcast) + GCMP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + else + GCMP_IV(pattrib->iv, psta->dot11txpn, 0); + + break; + #ifdef CONFIG_WAPI_SUPPORT case _SMS4_: pattrib->iv_len = 18; @@ -1191,8 +1368,11 @@ static s32 update_attrib_sec_info(_adapter *padapter, struct pkt_attrib *pattrib break; } - if (pattrib->encrypt > 0) - _rtw_memcpy(pattrib->dot118021x_UncstKey.skey, psta->dot118021x_UncstKey.skey, 16); + if (pattrib->encrypt > 0) { + _rtw_memcpy(pattrib->dot118021x_UncstKey.skey + , psta->dot118021x_UncstKey.skey + , (pattrib->encrypt & _SEC_TYPE_256_) ? 32 : 16); + } if (pattrib->encrypt && @@ -1202,9 +1382,7 @@ static s32 update_attrib_sec_info(_adapter *padapter, struct pkt_attrib *pattrib pattrib->bswenc = _FALSE; } -#if defined(CONFIG_CONCURRENT_MODE) pattrib->bmc_camid = padapter->securitypriv.dot118021x_bmc_cam_id; -#endif if (pattrib->encrypt && bmcast && _rtw_camctl_chk_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH)) pattrib->bswenc = _TRUE; @@ -1214,6 +1392,9 @@ static s32 update_attrib_sec_info(_adapter *padapter, struct pkt_attrib *pattrib pattrib->bswenc = _FALSE; #endif + if ((pattrib->encrypt) && (eapol_type == EAPOL_4_4)) + pattrib->bswenc = _TRUE; + exit: return res; @@ -1328,7 +1509,7 @@ static void set_qos(_pkt *pkt, struct pkt_attrib *pattrib) null_pkt: pattrib->priority = UserPriority; - pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN; + pattrib->hdrlen = XATTRIB_GET_WDS(pattrib) ? WLAN_HDR_A4_QOS_LEN : WLAN_HDR_A3_QOS_LEN; pattrib->subtype = WIFI_QOS_DATA_TYPE; } @@ -1402,7 +1583,7 @@ s32 update_tdls_attrib(_adapter *padapter, struct pkt_attrib *pattrib) } /* TODO:_lock */ - if (update_attrib_sec_info(padapter, pattrib, psta) == _FAIL) { + if (update_attrib_sec_info(padapter, pattrib, psta, NON_EAPOL) == _FAIL) { res = _FAIL; goto exit; } @@ -1423,7 +1604,8 @@ inline u8 rtw_get_hwseq_no(_adapter *padapter) u8 hwseq_num = 0; #ifdef CONFIG_CONCURRENT_MODE - #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) + #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) \ + || defined(CONFIG_RTL8723F) hwseq_num = padapter->iface_id; if (hwseq_num > 3) hwseq_num = 3; @@ -1473,6 +1655,7 @@ static s32 update_attrib(_adapter *padapter, _pkt *pkt, struct pkt_attrib *pattr struct qos_priv *pqospriv = &pmlmepriv->qospriv; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; sint res = _SUCCESS; + enum eap_type eapol_type = NON_EAPOL; #ifdef CONFIG_LPS u8 pkt_type = 0; #endif @@ -1484,30 +1667,36 @@ static s32 update_attrib(_adapter *padapter, _pkt *pkt, struct pkt_attrib *pattr pattrib->ether_type = ntohs(etherhdr.h_proto); - if (MLME_IS_MESH(padapter)) /* address resolve is done for mesh */ + if (MLME_STATE(padapter) & (WIFI_AP_STATE | WIFI_MESH_STATE)) /* address resolve is done for ap/mesh */ goto get_sta_info; _rtw_memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN); _rtw_memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN); + _rtw_memcpy(pattrib->ta, adapter_mac_addr(padapter), ETH_ALEN); if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) || (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) { _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); - _rtw_memcpy(pattrib->ta, adapter_mac_addr(padapter), ETH_ALEN); DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_adhoc); } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { -#ifdef CONFIG_TDLS + #ifdef CONFIG_TDLS if (rtw_check_tdls_established(padapter, pattrib) == _TRUE) _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); /* For TDLS direct link Tx, set ra to be same to dst */ else -#endif + #endif + { _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); - _rtw_memcpy(pattrib->ta, adapter_mac_addr(padapter), ETH_ALEN); + #ifdef CONFIG_RTW_WDS + if (adapter_use_wds(padapter) + && _rtw_memcmp(pattrib->src, pattrib->ta, ETH_ALEN) == _FALSE + ) { + pattrib->wds = 1; + if (IS_MCAST(pattrib->dst)) + rtw_tx_wds_gptr_update(padapter, pattrib->src); + } + #endif + } DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_sta); - } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { - _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); - _rtw_memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN); - DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_ap); } else DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_unknown); @@ -1532,16 +1721,21 @@ get_sta_info: #endif res = _FAIL; goto exit; - } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE && !(psta->state & _FW_LINKED)) { + } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE && !(psta->state & WIFI_ASOC_STATE)) { DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_ucast_ap_link); res = _FAIL; goto exit; } + + #ifdef CONFIG_RTW_WDS + if (XATTRIB_GET_WDS(pattrib) && !(psta->flags & WLAN_STA_WDS)) + pattrib->wds = 0; + #endif } - if (!(psta->state & _FW_LINKED)) { + if (!(psta->state & WIFI_ASOC_STATE)) { DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_link); - RTW_INFO("%s-"ADPT_FMT" psta("MAC_FMT")->state(0x%x) != _FW_LINKED\n", + RTW_INFO("%s-"ADPT_FMT" psta("MAC_FMT")->state(0x%x) != WIFI_ASOC_STATE\n", __func__, ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr), psta->state); res = _FAIL; goto exit; @@ -1623,7 +1817,7 @@ get_sta_info: } } else if (0x888e == pattrib->ether_type) - parsing_eapol_packet(padapter, pktfile.cur_addr, psta, 1); + eapol_type = parsing_eapol_packet(padapter, pktfile.cur_addr, psta, 1); #if defined (DBG_ARP_DUMP) || defined (DBG_IP_R_MONITOR) else if (pattrib->ether_type == ETH_P_ARP) { u8 arp[28] = {0}; @@ -1658,7 +1852,7 @@ get_sta_info: #endif /* TODO:_lock */ - if (update_attrib_sec_info(padapter, pattrib, psta) == _FAIL) { + if (update_attrib_sec_info(padapter, pattrib, psta, eapol_type) == _FAIL) { DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_sec); res = _FAIL; goto exit; @@ -1667,7 +1861,7 @@ get_sta_info: /* get ether_hdr_len */ pattrib->pkt_hdrlen = ETH_HLEN;/* (pattrib->ether_type == 0x8100) ? (14 + 4 ): 14; */ /* vlan tag */ - pattrib->hdrlen = WLAN_HDR_A3_LEN; + pattrib->hdrlen = XATTRIB_GET_WDS(pattrib) ? WLAN_HDR_A4_LEN : WLAN_HDR_A3_LEN; pattrib->subtype = WIFI_DATA_TYPE; pattrib->qos_en = psta->qos_option; pattrib->priority = 0; @@ -1763,9 +1957,9 @@ static s32 xmitframe_addmic(_adapter *padapter, struct xmit_frame *pxmitframe) return _FAIL; } - if(!(stainfo->state &_FW_LINKED)) + if(!(stainfo->state &WIFI_ASOC_STATE)) { - RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state); + RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, stainfo->state); return _FAIL; } */ @@ -1883,8 +2077,13 @@ static s32 xmitframe_swencrypt(_adapter *padapter, struct xmit_frame *pxmitframe rtw_tkip_encrypt(padapter, (u8 *)pxmitframe); break; case _AES_: + case _CCMP_256_: rtw_aes_encrypt(padapter, (u8 *)pxmitframe); break; + case _GCMP_: + case _GCMP_256_: + rtw_gcmp_encrypt(padapter, (u8 *)pxmitframe); + break; #ifdef CONFIG_WAPI_SUPPORT case _SMS4_: rtw_sms4_encrypt(padapter, (u8 *)pxmitframe); @@ -1929,9 +2128,9 @@ s32 rtw_make_wlanhdr(_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib) return _FAIL; } - if(!(psta->state &_FW_LINKED)) + if(!(psta->state &WIFI_ASOC_STATE)) { - RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state); return _FAIL; } */ @@ -1954,23 +2153,47 @@ s32 rtw_make_wlanhdr(_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib) } else #endif /* CONFIG_TDLS */ { - /* to_ds = 1, fr_ds = 0; */ - /* 1.Data transfer to AP */ - /* 2.Arp pkt will relayed by AP */ - SetToDs(fctrl); - _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); + #ifdef CONFIG_RTW_WDS + if (pattrib->wds) { + SetToDs(fctrl); + SetFrDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, pattrib->ra, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr4, pattrib->src, ETH_ALEN); + } else + #endif + { + /* to_ds = 1, fr_ds = 0; */ + /* 1.Data transfer to AP */ + /* 2.Arp pkt will relayed by AP */ + SetToDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); + } if (pqospriv->qos_option) qos_option = _TRUE; } } else if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)) { - /* to_ds = 0, fr_ds = 1; */ - SetFrDs(fctrl); - _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN); + #ifdef CONFIG_RTW_WDS + if (pattrib->wds) { + SetToDs(fctrl); + SetFrDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, pattrib->ra, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr4, pattrib->src, ETH_ALEN); + } else + #endif + { + /* to_ds = 0, fr_ds = 1; */ + SetFrDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN); + } if (pattrib->qos_en) qos_option = _TRUE; @@ -2046,8 +2269,8 @@ s32 rtw_make_wlanhdr(_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib) return _FAIL; } - if (!(psta->state & _FW_LINKED)) { - RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + if (!(psta->state & WIFI_ASOC_STATE)) { + RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state); return _FAIL; } @@ -2109,7 +2332,11 @@ s32 rtw_txframes_pending(_adapter *padapter) return ((_rtw_queue_empty(&pxmitpriv->be_pending) == _FALSE) || (_rtw_queue_empty(&pxmitpriv->bk_pending) == _FALSE) || (_rtw_queue_empty(&pxmitpriv->vi_pending) == _FALSE) || - (_rtw_queue_empty(&pxmitpriv->vo_pending) == _FALSE)); + (_rtw_queue_empty(&pxmitpriv->vo_pending) == _FALSE) +#ifdef CONFIG_RTW_MGMT_QUEUE + || (_rtw_queue_empty(&pxmitpriv->mgmt_pending) == _FALSE) +#endif + ); } s32 rtw_txframes_sta_ac_pending(_adapter *padapter, struct pkt_attrib *pattrib) @@ -2139,8 +2366,8 @@ s32 rtw_txframes_sta_ac_pending(_adapter *padapter, struct pkt_attrib *pattrib) return 0; } - if (!(psta->state & _FW_LINKED)) { - RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + if (!(psta->state & WIFI_ASOC_STATE)) { + RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state); return 0; } @@ -2474,6 +2701,7 @@ u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib) s32 check_amsdu(struct xmit_frame *pxmitframe) { struct pkt_attrib *pattrib; + struct sta_info *psta = NULL; s32 ret = _TRUE; if (!pxmitframe) @@ -2481,6 +2709,11 @@ s32 check_amsdu(struct xmit_frame *pxmitframe) pattrib = &pxmitframe->attrib; + psta = rtw_get_stainfo(&pxmitframe->padapter->stapriv, &pattrib->ra[0]); + if (psta) { + if (psta->flags & WLAN_STA_AMSDU_DISABLE) + ret =_FALSE; + } if (IS_MCAST(pattrib->ra)) ret = _FALSE; @@ -2770,9 +3003,9 @@ s32 rtw_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxm } - if(!(psta->state &_FW_LINKED)) + if(!(psta->state &WIFI_ASOC_STATE)) { - RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state); return _FAIL; } */ @@ -2961,11 +3194,13 @@ s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct rtw_ieee80211_hdr *pwlanhdr; - u8 MME[_MME_IE_LENGTH_]; + u8 mme_cont[_MME_IE_LENGTH_ - 2]; + u8 mme_clen; _irqL irqL; u32 ori_len; union pn48 *pn = NULL; + enum security_type cipher = _NO_PRIVACY_; u8 kid; if (pxmitframe->buf_addr == NULL) { @@ -3006,7 +3241,7 @@ s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame } } - ori_len = BIP_AAD_SIZE + pattrib->pktlen; + ori_len = BIP_AAD_SIZE + pattrib->pktlen + _MME_IE_LENGTH_; tmp_buf = BIP_AAD = rtw_zmalloc(ori_len); if (BIP_AAD == NULL) return _FAIL; @@ -3037,6 +3272,7 @@ s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame } pn = &psta->dot11txpn; + cipher = padapter->securitypriv.dot118021XGrpPrivacy; kid = padapter->securitypriv.dot118021XGrpKeyid; } else { #ifdef CONFIG_IEEE80211W @@ -3059,19 +3295,20 @@ s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame } #endif - _rtw_memset(MME, 0, _MME_IE_LENGTH_); + _rtw_memset(mme_cont, 0, _MME_IE_LENGTH_ - 2); + mme_clen = padapter->securitypriv.dot11wCipher == _BIP_CMAC_128_ ? 16 : 24; MGMT_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); pframe += pattrib->pktlen; /* octent 0 and 1 is key index ,BIP keyid is 4 or 5, LSB only need octent 0 */ - MME[0] = padapter->securitypriv.dot11wBIPKeyid; + mme_cont[0] = padapter->securitypriv.dot11wBIPKeyid; /* increase PN and apply to packet */ padapter->securitypriv.dot11wBIPtxpn.val++; - RTW_PUT_LE64(&MME[2], padapter->securitypriv.dot11wBIPtxpn.val); + RTW_PUT_LE64(&mme_cont[2], padapter->securitypriv.dot11wBIPtxpn.val); /* add MME IE with MIC all zero, MME string doesn't include element id and length */ - pframe = rtw_set_ie(pframe, _MME_IE_ , 16 , MME, &(pattrib->pktlen)); + pframe = rtw_set_ie(pframe, _MME_IE_ , mme_clen , mme_cont, &(pattrib->pktlen)); pattrib->last_txcmdsz = pattrib->pktlen; /* total frame length - header length */ frame_body_len = pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr); @@ -3082,7 +3319,7 @@ s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame ClearPwrMgt(BIP_AAD); ClearMData(BIP_AAD); /* conscruct AAD, copy address 1 to address 3 */ - _rtw_memcpy(BIP_AAD + 2, pwlanhdr->addr1, 18); + _rtw_memcpy(BIP_AAD + 2, GetAddr1Ptr((u8 *)pwlanhdr), 18); /* copy management fram body */ _rtw_memcpy(BIP_AAD + BIP_AAD_SIZE, MGMT_body, frame_body_len); @@ -3098,8 +3335,10 @@ s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame #endif /* calculate mic */ - if (omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey - , BIP_AAD, BIP_AAD_SIZE + frame_body_len, mic)) + if (rtw_calculate_bip_mic(padapter->securitypriv.dot11wCipher, + (u8 *)pwlanhdr, pattrib->pktlen, + padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey, + BIP_AAD, (BIP_AAD_SIZE + frame_body_len), mic) == _FAIL) goto xmitframe_coalesce_fail; #if DBG_MGMT_XMIT_BIP_DUMP @@ -3114,7 +3353,10 @@ s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame #endif /* copy right BIP mic value, total is 128bits, we use the 0~63 bits */ - _rtw_memcpy(pframe - 8, mic, 8); + if (padapter->securitypriv.dot11wCipher == _BIP_CMAC_128_) + _rtw_memcpy(pframe - 8, mic, 8); + else + _rtw_memcpy(pframe - 16, mic, 16); #if DBG_MGMT_XMIT_BIP_DUMP /*dump all packet after mic ok */ @@ -3147,16 +3389,19 @@ s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame } #endif - _rtw_memcpy(pattrib->dot118021x_UncstKey.skey, psta->dot118021x_UncstKey.skey, 16); + pn = &psta->dot11txpn; + cipher = psta->dot118021XPrivacy; + kid = 0; + + _rtw_memcpy(pattrib->dot118021x_UncstKey.skey + , psta->dot118021x_UncstKey.skey + , (cipher & _SEC_TYPE_256_) ? 32 : 16); /* To use wrong key */ if (pattrib->key_type == IEEE80211W_WRONG_KEY) { RTW_INFO("use wrong key\n"); pattrib->dot118021x_UncstKey.skey[0] = 0xff; } - - pn = &psta->dot11txpn; - kid = 0; } #if DBG_MGMT_XMIT_ENC_DUMP @@ -3175,21 +3420,32 @@ s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame /* move to data portion */ pframe += pattrib->hdrlen; - /* 802.11w encrypted management packet must be _AES_ */ if (pattrib->key_type != IEEE80211W_NO_KEY) { - pattrib->encrypt = _AES_; + pattrib->encrypt = cipher; pattrib->bswenc = _TRUE; } - pattrib->iv_len = 8; - /* it's MIC of AES */ - pattrib->icv_len = 8; - + /* + * 802.11w encrypted management packet must be: + * _AES_, _CCMP_256_, _GCMP_, _GCMP_256_ + */ switch (pattrib->encrypt) { case _AES_: - /* set AES IV header */ + pattrib->iv_len = 8; + pattrib->icv_len = 8; AES_IV(pattrib->iv, (*pn), kid); break; + case _CCMP_256_: + pattrib->iv_len = 8; + pattrib->icv_len = 16; + AES_IV(pattrib->iv, (*pn), kid); + break; + case _GCMP_: + case _GCMP_256_: + pattrib->iv_len = 8; + pattrib->icv_len = 16; + GCMP_IV(pattrib->iv, (*pn), kid); + break; default: goto xmitframe_coalesce_fail; } @@ -3407,7 +3663,7 @@ struct xmit_frame *__rtw_alloc_cmdxmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pcmdframe; struct xmit_buf *pxmitbuf; - pcmdframe = rtw_alloc_xmitframe(pxmitpriv); + pcmdframe = rtw_alloc_xmitframe(pxmitpriv, 0); if (pcmdframe == NULL) { RTW_INFO("%s, alloc xmitframe fail\n", __FUNCTION__); return NULL; @@ -3670,7 +3926,7 @@ Otherwise, we must use _enter/_exit critical to protect free_xmit_queue... Must be very very cautious... */ -struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* (_queue *pfree_xmit_queue) */ +struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv, u16 os_qid) { /* Please remember to use all the osdep_service api, @@ -3683,7 +3939,6 @@ struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* (_queue *p _list *plist, *phead; _queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue; - _enter_critical_bh(&pfree_xmit_queue->lock, &irqL); if (_rtw_queue_empty(pfree_xmit_queue) == _TRUE) { @@ -3697,10 +3952,14 @@ struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* (_queue *p rtw_list_delete(&(pxframe->list)); pxmitpriv->free_xmitframe_cnt--; + pxframe->os_qid = os_qid; } _exit_critical_bh(&pfree_xmit_queue->lock, &irqL); + if (pxframe) + rtw_os_check_stop_queue(pxmitpriv->adapter, os_qid); + rtw_init_xmitframe(pxframe); @@ -3808,6 +4067,9 @@ s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitfram _exit_critical_bh(&queue->lock, &irqL); + if (queue == &pxmitpriv->free_xmit_queue) + rtw_os_check_wakup_queue(padapter, pxmitframe->os_qid); + check_pkt_complete: if (pndis_pkt) @@ -3819,6 +4081,76 @@ exit: return _SUCCESS; } +#ifdef CONFIG_RTW_MGMT_QUEUE +void rtw_free_mgmt_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *mgmt_queue) +{ + _irqL irqL; + _list *plist, *phead; + struct xmit_frame *pxmitframe; + + _enter_critical_bh(&(mgmt_queue->lock), &irqL); + + phead = get_list_head(mgmt_queue); + plist = get_next(phead); + + while (rtw_end_of_queue_search(phead, plist) == _FALSE) { + + pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list); + plist = get_next(plist); + + #ifdef DBG_MGMT_QUEUE + RTW_INFO("%s seq_num = %u\n", __func__, pxmitframe->attrib.seqnum); + #endif + + rtw_free_xmitbuf_ext(pxmitpriv, pxmitframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pxmitframe); + } + _exit_critical_bh(&(mgmt_queue->lock), &irqL); +} + +u8 rtw_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + struct sta_info *psta; + struct tx_servq *ptxservq; + struct pkt_attrib *pattrib = &(pxmitframe->attrib); + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct hw_xmit *phwxmits = pxmitpriv->hwxmits; + u8 mgmt_idx = pxmitpriv->hwxmit_entry - 1; + + DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class); + + psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); + if (pattrib->psta != psta) { + DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_sta); + RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta); + return _FAIL; + } + + if (psta == NULL) { + DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_nosta); + RTW_INFO("rtw_xmit_classifier: psta == NULL\n"); + return _FAIL; + } + + if (!(psta->state & WIFI_ASOC_STATE)) { + DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_fwlink); + RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state); + return _FAIL; + } + + ptxservq = &(psta->sta_xmitpriv.mgmt_q); + + if (rtw_is_list_empty(&ptxservq->tx_pending)) + rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmits[mgmt_idx].sta_queue)); + + rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending)); + ptxservq->qcnt++; + phwxmits[mgmt_idx].accnt++; + + return _SUCCESS; +} +#endif + void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue) { _irqL irqL; @@ -3918,8 +4250,13 @@ struct xmit_frame *rtw_get_xframe(struct xmit_priv *pxmitpriv, int *num_frame) _irqL irqL0; _list *sta_plist, *sta_phead; struct hw_xmit *phwxmit_i = pxmitpriv->hwxmits; - sint entry = pxmitpriv->hwxmit_entry; - +#ifdef CONFIG_RTW_MGMT_QUEUE + /* This function gets xmit_frame from AC queue. */ + /* When mgmt queue is used, AC queue index is (hwxmit_entry - 1) */ + sint entry = pxmitpriv->hwxmit_entry - 1; +#else + sint entry = pxmitpriv->hwxmit_entry; +#endif struct hw_xmit *phwxmit; struct tx_servq *ptxservq = NULL; _queue *pframe_queue = NULL; @@ -3970,6 +4307,54 @@ exit: return pxmitframe; } +#ifdef CONFIG_RTW_MGMT_QUEUE +struct xmit_frame *rtw_dequeue_mgmt_xframe(struct xmit_priv *pxmitpriv) +{ + _irqL irqL0; + _list *sta_plist, *sta_phead; + struct hw_xmit *mgmt_hwxmit; + struct tx_servq *ptxservq = NULL; + _queue *pframe_queue = NULL; + struct xmit_frame *pxmitframe = NULL; + u8 mgmt_entry = pxmitpriv->hwxmit_entry - 1; + + _enter_critical_bh(&pxmitpriv->lock, &irqL0); + + /* management queue */ + mgmt_hwxmit = (pxmitpriv->hwxmits) + mgmt_entry; + + sta_phead = get_list_head(mgmt_hwxmit->sta_queue); + sta_plist = get_next(sta_phead); + + while ((rtw_end_of_queue_search(sta_phead, sta_plist)) == _FALSE) { + + ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending); + + pframe_queue = &ptxservq->sta_pending; + + pxmitframe = dequeue_one_xmitframe(pxmitpriv, mgmt_hwxmit, ptxservq, pframe_queue); + + #ifdef DBG_MGMT_QUEUE + RTW_INFO("%s dequeue mgmt frame (seq_num = %u) to TX\n", __func__, pxmitframe->attrib.seqnum); + #endif + + if (pxmitframe) { + mgmt_hwxmit->accnt--; + + /* Remove sta node when there is no pending packets. */ + if (_rtw_queue_empty(pframe_queue)) /* must be done after get_next and before break */ + rtw_list_delete(&ptxservq->tx_pending); + + goto exit; + } + sta_plist = get_next(sta_plist); + } +exit: + _exit_critical_bh(&pxmitpriv->lock, &irqL0); + + return pxmitframe; +} +#endif struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, sint entry) { @@ -3980,9 +4365,13 @@ struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmi _queue *pframe_queue = NULL; struct xmit_frame *pxmitframe = NULL; _adapter *padapter = pxmitpriv->adapter; - struct registry_priv *pregpriv = &padapter->registrypriv; + struct registry_priv *pregpriv = &padapter->registrypriv; int i, inx[4]; - +#ifdef CONFIG_RTW_MGMT_QUEUE + /* This function gets xmit_frame from AC queue. */ + /* When mgmt queue is used, AC queue index is (hwxmit_entry - 1) */ + entry--; +#endif inx[0] = 0; inx[1] = 1; inx[2] = 2; @@ -4049,7 +4438,6 @@ exit: return pxmitframe; } -#if 1 struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, sint up, u8 *ac) { struct tx_servq *ptxservq = NULL; @@ -4086,60 +4474,6 @@ struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, return ptxservq; } -#else -__inline static struct tx_servq *rtw_get_sta_pending -(_adapter *padapter, _queue **ppstapending, struct sta_info *psta, sint up) -{ - struct tx_servq *ptxservq; - struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; - - -#ifdef CONFIG_RTL8711 - - if (IS_MCAST(psta->cmn.mac_addr)) { - ptxservq = &(psta->sta_xmitpriv.be_q); /* we will use be_q to queue bc/mc frames in BCMC_stainfo */ - *ppstapending = &padapter->xmitpriv.bm_pending; - } else -#endif - { - switch (up) { - case 1: - case 2: - ptxservq = &(psta->sta_xmitpriv.bk_q); - *ppstapending = &padapter->xmitpriv.bk_pending; - (phwxmits + 3)->accnt++; - break; - - case 4: - case 5: - ptxservq = &(psta->sta_xmitpriv.vi_q); - *ppstapending = &padapter->xmitpriv.vi_pending; - (phwxmits + 1)->accnt++; - break; - - case 6: - case 7: - ptxservq = &(psta->sta_xmitpriv.vo_q); - *ppstapending = &padapter->xmitpriv.vo_pending; - (phwxmits + 0)->accnt++; - break; - - case 0: - case 3: - default: - ptxservq = &(psta->sta_xmitpriv.be_q); - *ppstapending = &padapter->xmitpriv.be_pending; - (phwxmits + 2)->accnt++; - break; - - } - - } - - - return ptxservq; -} -#endif /* * Will enqueue pxmitframe to the proper queue, @@ -4181,9 +4515,9 @@ s32 rtw_xmit_classifier(_adapter *padapter, struct xmit_frame *pxmitframe) goto exit; } - if (!(psta->state & _FW_LINKED)) { + if (!(psta->state & WIFI_ASOC_STATE)) { DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_fwlink); - RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state); return _FAIL; } @@ -4228,49 +4562,27 @@ void rtw_alloc_hwxmits(_adapter *padapter) hwxmits = pxmitpriv->hwxmits; - if (pxmitpriv->hwxmit_entry == 5) { - /* pxmitpriv->bmc_txqueue.head = 0; */ - /* hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue; */ - hwxmits[0] .sta_queue = &pxmitpriv->bm_pending; + rtw_warn_on(pxmitpriv->hwxmit_entry < 4); - /* pxmitpriv->vo_txqueue.head = 0; */ - /* hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue; */ - hwxmits[1] .sta_queue = &pxmitpriv->vo_pending; + /* pxmitpriv->vo_txqueue.head = 0; */ + /* hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; */ + hwxmits[0].sta_queue = &pxmitpriv->vo_pending; - /* pxmitpriv->vi_txqueue.head = 0; */ - /* hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue; */ - hwxmits[2] .sta_queue = &pxmitpriv->vi_pending; + /* pxmitpriv->vi_txqueue.head = 0; */ + /* hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; */ + hwxmits[1].sta_queue = &pxmitpriv->vi_pending; - /* pxmitpriv->bk_txqueue.head = 0; */ - /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */ - hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; + /* pxmitpriv->be_txqueue.head = 0; */ + /* hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; */ + hwxmits[2].sta_queue = &pxmitpriv->be_pending; - /* pxmitpriv->be_txqueue.head = 0; */ - /* hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue; */ - hwxmits[4] .sta_queue = &pxmitpriv->be_pending; - - } else if (pxmitpriv->hwxmit_entry == 4) { - - /* pxmitpriv->vo_txqueue.head = 0; */ - /* hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; */ - hwxmits[0] .sta_queue = &pxmitpriv->vo_pending; - - /* pxmitpriv->vi_txqueue.head = 0; */ - /* hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; */ - hwxmits[1] .sta_queue = &pxmitpriv->vi_pending; - - /* pxmitpriv->be_txqueue.head = 0; */ - /* hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; */ - hwxmits[2] .sta_queue = &pxmitpriv->be_pending; - - /* pxmitpriv->bk_txqueue.head = 0; */ - /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */ - hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; - } else { - - - } + /* pxmitpriv->bk_txqueue.head = 0; */ + /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */ + hwxmits[3].sta_queue = &pxmitpriv->bk_pending; +#ifdef CONFIG_RTW_MGMT_QUEUE + hwxmits[4].sta_queue = &pxmitpriv->mgmt_pending; +#endif } @@ -4570,9 +4882,8 @@ s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev) unsigned char *pframe; u8 dummybuf[32]; int len = skb->len, rtap_len; -#ifdef CONFIG_MONITOR_MODE_XMIT - int consume; -#endif /* CONFIG_MONITOR_MODE_XMIT */ + + rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize); #ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL @@ -4588,25 +4899,13 @@ s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev) if (unlikely(skb->len < rtap_len)) goto fail; -#ifdef CONFIG_MONITOR_MODE_XMIT - len -= sizeof(struct ieee80211_radiotap_header); - rtap_len -= sizeof(struct ieee80211_radiotap_header); - - while(rtap_len) { - consume = rtap_len > sizeof(dummybuf) ? sizeof(dummybuf) : rtap_len; - _rtw_pktfile_read(&pktfile, dummybuf, consume); - rtap_len -= consume; - len -= consume; - } -#else /* CONFIG_MONITOR_MODE_XMIT */ if (rtap_len != 12) { RTW_INFO("radiotap len (should be 14): %d\n", rtap_len); goto fail; } _rtw_pktfile_read(&pktfile, dummybuf, rtap_len-sizeof(struct ieee80211_radiotap_header)); len = len - rtap_len; -#endif /* CONFIG_MONITOR_MODE_XMIT */ -#endif /* CONFIG_CUSTOMER_ALIBABA_GENERAL */ +#endif pmgntframe = alloc_mgtxmitframe(pxmitpriv); if (pmgntframe == NULL) { rtw_udelay_os(500); @@ -4646,9 +4945,6 @@ s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev) dump_mgntframe(padapter, pmgntframe); fail: -#ifdef CONFIG_MONITOR_MODE_XMIT - rtw_endofpktfile(&pktfile); -#endif /* CONFIG_MONITOR_MODE_XMIT */ rtw_skb_free(skb); return 0; } @@ -4845,26 +5141,35 @@ s32 rtw_xmit_posthandle(_adapter *padapter, struct xmit_frame *pxmitframe, _pkt * 0 success, hardware will handle this xmit frame(packet) * <0 fail */ -s32 rtw_xmit(_adapter *padapter, _pkt **ppkt) +s32 rtw_xmit(_adapter *padapter, _pkt **ppkt, u16 os_qid) { static systime start = 0; static u32 drop_cnt = 0; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct xmit_frame *pxmitframe = NULL; s32 res; +#ifdef CONFIG_LAYER2_ROAMING + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sk_buff *skb = (struct sk_buff *)(*ppkt); + _irqL irqL; +#endif DBG_COUNTER(padapter->tx_logs.core_tx); if (IS_CH_WAITING(adapter_to_rfctl(padapter))) return -1; - if (rtw_linked_check(padapter) == _FALSE) + if ((rtw_linked_check(padapter) == _FALSE) +#ifdef CONFIG_LAYER2_ROAMING + &&(!padapter->mlmepriv.roam_network) +#endif + ) return -1; if (start == 0) start = rtw_get_current_time(); - pxmitframe = rtw_alloc_xmitframe(pxmitpriv); + pxmitframe = rtw_alloc_xmitframe(pxmitpriv, os_qid); if (rtw_get_passing_time_ms(start) > 2000) { if (drop_cnt) @@ -4881,7 +5186,7 @@ s32 rtw_xmit(_adapter *padapter, _pkt **ppkt) } #ifdef CONFIG_BR_EXT - if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) { + if (!adapter_use_wds(padapter) && check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) { void *br_port = NULL; #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) @@ -4902,18 +5207,33 @@ s32 rtw_xmit(_adapter *padapter, _pkt **ppkt) } } #endif /* CONFIG_BR_EXT */ +#ifdef CONFIG_LAYER2_ROAMING + if ((pmlmepriv->roam_network) && (skb->protocol != htons(0x888e))) { /* eapol never enqueue.*/ + pxmitframe->pkt = *ppkt; + rtw_list_delete(&pxmitframe->list); + _enter_critical_bh(&pxmitpriv->rpkt_queue.lock, &irqL); + rtw_list_insert_tail(&(pxmitframe->list), get_list_head(&(pxmitpriv->rpkt_queue))); + _exit_critical_bh(&pxmitpriv->rpkt_queue.lock, &irqL); + return 1; + } +#endif -#ifdef CONFIG_RTW_MESH - if (MLME_IS_MESH(padapter)) { +#if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) + if (MLME_STATE(padapter) & (WIFI_AP_STATE | WIFI_MESH_STATE)) { _list b2u_list; - res = rtw_mesh_addr_resolve(padapter, pxmitframe, *ppkt, &b2u_list); + #ifdef CONFIG_RTW_MESH + if (MLME_IS_MESH(padapter)) + res = rtw_mesh_addr_resolve(padapter, os_qid, pxmitframe, *ppkt, &b2u_list); + else + #endif + res = rtw_ap_addr_resolve(padapter, os_qid, pxmitframe, *ppkt, &b2u_list); if (res == RTW_RA_RESOLVING) return 1; if (res == _FAIL) return -1; - #if CONFIG_RTW_MESH_DATA_BMC_TO_UC + #if CONFIG_RTW_DATA_BMC_TO_UC if (!rtw_is_list_empty(&b2u_list)) { _list *list = get_next(&b2u_list); struct xmit_frame *b2uframe; @@ -4934,14 +5254,14 @@ s32 rtw_xmit(_adapter *padapter, _pkt **ppkt) rtw_xmit_posthandle(padapter, b2uframe, b2uframe->pkt); } } - #endif /* CONFIG_RTW_MESH_DATA_BMC_TO_UC */ + #endif if (res == RTW_BMC_NO_NEED) { rtw_free_xmitframe(&padapter->xmitpriv, pxmitframe); return 0; } } -#endif /* CONFIG_RTW_MESH */ +#endif /* defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) */ pxmitframe->pkt = NULL; /* let rtw_xmit_posthandle not to free pkt inside */ res = rtw_xmit_posthandle(padapter, pxmitframe, *ppkt); @@ -5058,6 +5378,96 @@ inline bool xmitframe_hiq_filter(struct xmit_frame *xmitframe) } #if defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS) +#ifdef CONFIG_RTW_MGMT_QUEUE +u8 mgmt_xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + _irqL irqL; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct sta_info *psta = pattrib->psta; + struct sta_priv *pstapriv = &padapter->stapriv; + bool update_tim = _FALSE; + u8 ret = _TRUE; + + if (is_broadcast_mac_addr(pattrib->ra) || pattrib->ps_dontq) + return _FALSE; + + if (psta == NULL) { + RTW_INFO("%s, psta==NUL, pattrib->ra:"MAC_FMT"\n", + __func__, MAC_ARG(pattrib->ra)); + return _FALSE; + } + + if (!(psta->state & WIFI_ASOC_STATE)) { + DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_link); + RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state); + return _FALSE; + } + + _enter_critical_bh(&psta->mgmt_sleep_q.lock, &irqL); + + if (psta->state & WIFI_SLEEP_STATE && + rtw_tim_map_is_set(padapter, pstapriv->sta_dz_bitmap, psta->cmn.aid)) { + + rtw_list_delete(&pxmitframe->list); + rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->mgmt_sleep_q)); + psta->mgmt_sleepq_len++; + + #ifdef DBG_MGMT_QUEUE + RTW_INFO("%s attrib->ra:"MAC_FMT" seq_num = %u, subtype = 0x%x\n", + __func__, MAC_ARG(pattrib->ra), pattrib->seqnum, pattrib->subtype); + #endif + + if (!(rtw_tim_map_is_set(padapter, pstapriv->tim_bitmap, psta->cmn.aid))) + update_tim = _TRUE; + + rtw_tim_map_set(padapter, pstapriv->tim_bitmap, psta->cmn.aid); + + /* upate BCN for TIM IE */ + if (update_tim == _TRUE) + _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, 0, "buffer mgmt frame"); + + ret = RTW_QUEUE_MGMT; + DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_ucast); + } + + _exit_critical_bh(&psta->mgmt_sleep_q.lock, &irqL); + + return ret; +} + +static void dequeue_mgmt_xmitframe_to_sleepq(_adapter *padapter, struct sta_info *psta, _queue *pframequeue) +{ + sint ret; + _list *plist, *phead; + struct tx_servq *ptxservq; + struct pkt_attrib *pattrib; + struct xmit_frame *pxmitframe; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct hw_xmit *phwxmits = pxmitpriv->hwxmits; + u8 mgmt_idx = pxmitpriv->hwxmit_entry - 1; + + phead = get_list_head(pframequeue); + plist = get_next(phead); + + while (rtw_end_of_queue_search(phead, plist) == _FALSE) { + pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list); + plist = get_next(plist); + + pattrib = &pxmitframe->attrib; + pattrib->triggered = 0; + + ret = mgmt_xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe); + + if (ret == RTW_QUEUE_MGMT) { + ptxservq = &(psta->sta_xmitpriv.mgmt_q); + ptxservq->qcnt--; + phwxmits[mgmt_idx].accnt--; + } else { + /* RTW_INFO("xmitframe_enqueue_for_sleeping_sta return _FALSE\n"); */ + } + } +} +#endif sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe) { @@ -5102,9 +5512,9 @@ sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *p return _FALSE; } - if (!(psta->state & _FW_LINKED)) { + if (!(psta->state & WIFI_ASOC_STATE)) { DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_link); - RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state); return _FALSE; } @@ -5286,7 +5696,8 @@ void stop_sta_xmit(_adapter *padapter, struct sta_info *psta) /* for BC/MC Frames */ psta_bmc = rtw_get_bcmc_stainfo(padapter); - + if (!psta_bmc) + rtw_warn_on(1); _enter_critical_bh(&pxmitpriv->lock, &irqL0); @@ -5297,6 +5708,11 @@ void stop_sta_xmit(_adapter *padapter, struct sta_info *psta) #endif /* CONFIG_TDLS */ rtw_tim_map_set(padapter, pstapriv->sta_dz_bitmap, psta->cmn.aid); +#ifdef CONFIG_RTW_MGMT_QUEUE + dequeue_mgmt_xmitframe_to_sleepq(padapter, psta, &pstaxmitpriv->mgmt_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->mgmt_q.tx_pending)); +#endif + dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending); rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending)); dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending); @@ -5306,10 +5722,12 @@ void stop_sta_xmit(_adapter *padapter, struct sta_info *psta) dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending); rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending)); -#ifdef CONFIG_TDLS - if (!(psta->tdls_sta_state & TDLS_LINKED_STATE) && (psta_bmc != NULL)) { -#endif /* CONFIG_TDLS */ - + if (psta_bmc != NULL + #ifdef CONFIG_TDLS + && !(psta->tdls_sta_state & TDLS_LINKED_STATE) + #endif + ) + { /* for BC/MC Frames */ pstaxmitpriv = &psta_bmc->sta_xmitpriv; dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->vo_q.sta_pending); @@ -5320,10 +5738,7 @@ void stop_sta_xmit(_adapter *padapter, struct sta_info *psta) rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending)); dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->bk_q.sta_pending); rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending)); - -#ifdef CONFIG_TDLS } -#endif /* CONFIG_TDLS */ _exit_critical_bh(&pxmitpriv->lock, &irqL0); @@ -5345,6 +5760,32 @@ void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta) /* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */ _enter_critical_bh(&pxmitpriv->lock, &irqL); +#ifdef CONFIG_RTW_MGMT_QUEUE + /* management queue */ + xmitframe_phead = get_list_head(&psta->mgmt_sleep_q); + xmitframe_plist = get_next(xmitframe_phead); + + while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + + xmitframe_plist = get_next(xmitframe_plist); + + rtw_list_delete(&pxmitframe->list); + + #ifdef DBG_MGMT_QUEUE + RTW_INFO("%s seq_num = %u, subtype = 0x%x\n", + __func__, pxmitframe->attrib.seqnum, pxmitframe->attrib.subtype); + #endif + + psta->mgmt_sleepq_len--; + + pxmitframe->attrib.triggered = 1; + + rtw_hal_mgmt_xmitframe_enqueue(padapter, pxmitframe); + } +#endif /* CONFIG_RTW_MGMT_QUEUE */ + + /* AC queue */ xmitframe_phead = get_list_head(&psta->sleep_q); xmitframe_plist = get_next(xmitframe_phead); @@ -5407,7 +5848,11 @@ void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta) } - if (psta->sleepq_len == 0) { + if (psta->sleepq_len == 0 +#ifdef CONFIG_RTW_MGMT_QUEUE + && psta->mgmt_sleepq_len == 0 +#endif + ) { #ifdef CONFIG_TDLS if (psta->tdls_sta_state & TDLS_LINKED_STATE) { if (psta->state & WIFI_SLEEP_STATE) @@ -5504,7 +5949,6 @@ _exit: else _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, 0, "clear UC"); } - } void xmit_delivery_enabled_frames(_adapter *padapter, struct sta_info *psta) diff --git a/core/wds/rtw_wds.c b/core/wds/rtw_wds.c new file mode 100644 index 0000000..fd88b1c --- /dev/null +++ b/core/wds/rtw_wds.c @@ -0,0 +1,786 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#define _RTW_WDS_C_ + +#include + +#if defined(CONFIG_RTW_WDS) +#include + +#if defined(CONFIG_AP_MODE) + +#ifdef PLATFORM_LINUX +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) +static void rtw_wpath_free_rcu(struct rtw_wds_path *wpath) +{ + kfree_rcu(wpath, rcu); + rtw_mstat_update(MSTAT_TYPE_PHY, MSTAT_FREE, sizeof(struct rtw_wds_path)); +} +#else +static void rtw_wpath_free_rcu_callback(rtw_rcu_head *head) +{ + struct rtw_wds_path *wpath; + + wpath = container_of(head, struct rtw_wds_path, rcu); + rtw_mfree(wpath, sizeof(struct rtw_wds_path)); +} + +static void rtw_wpath_free_rcu(struct rtw_wds_path *wpath) +{ + call_rcu(&wpath->rcu, rtw_wpath_free_rcu_callback); +} +#endif +#endif /* PLATFORM_LINUX */ + +static void rtw_wds_path_free_rcu(struct rtw_wds_table *tbl, struct rtw_wds_path *wpath); + +static u32 rtw_wds_table_hash(const void *addr, u32 len, u32 seed) +{ + /* Use last four bytes of hw addr as hash index */ + return jhash_1word(*(u32 *)(addr+2), seed); +} + +static const rtw_rhashtable_params rtw_wds_rht_params = { + .nelem_hint = 2, + .automatic_shrinking = true, + .key_len = ETH_ALEN, + .key_offset = offsetof(struct rtw_wds_path, dst), + .head_offset = offsetof(struct rtw_wds_path, rhash), + .hashfn = rtw_wds_table_hash, +}; + +static void rtw_wds_path_rht_free(void *ptr, void *tblptr) +{ + struct rtw_wds_path *wpath = ptr; + struct rtw_wds_table *tbl = tblptr; + + rtw_wds_path_free_rcu(tbl, wpath); +} + +static struct rtw_wds_table *rtw_wds_table_alloc(void) +{ + struct rtw_wds_table *newtbl; + + newtbl = rtw_malloc(sizeof(struct rtw_wds_table)); + if (!newtbl) + return NULL; + + return newtbl; +} + +static void rtw_wds_table_free(struct rtw_wds_table *tbl) +{ + rtw_rhashtable_free_and_destroy(&tbl->rhead, + rtw_wds_path_rht_free, tbl); + rtw_mfree(tbl, sizeof(struct rtw_wds_table)); +} + +void rtw_wds_path_assign_nexthop(struct rtw_wds_path *wpath, struct sta_info *sta) +{ + rtw_rcu_assign_pointer(wpath->next_hop, sta); +} + +static struct rtw_wds_path *rtw_wpath_lookup(struct rtw_wds_table *tbl, const u8 *dst) +{ + struct rtw_wds_path *wpath; + + if (!tbl) + return NULL; + + wpath = rtw_rhashtable_lookup_fast(&tbl->rhead, dst, rtw_wds_rht_params); + + return wpath; +} + +struct rtw_wds_path *rtw_wds_path_lookup(_adapter *adapter, const u8 *dst) +{ + return rtw_wpath_lookup(adapter->wds_paths, dst); +} + +static struct rtw_wds_path * +__rtw_wds_path_lookup_by_idx(struct rtw_wds_table *tbl, int idx) +{ + int i = 0, ret; + struct rtw_wds_path *wpath = NULL; + rtw_rhashtable_iter iter; + + if (!tbl) + return NULL; + + ret = rtw_rhashtable_walk_enter(&tbl->rhead, &iter); + if (ret) + return NULL; + + ret = rtw_rhashtable_walk_start(&iter); + if (ret && ret != -EAGAIN) + goto err; + + while ((wpath = rtw_rhashtable_walk_next(&iter))) { + if (IS_ERR(wpath) && PTR_ERR(wpath) == -EAGAIN) + continue; + if (IS_ERR(wpath)) + break; + if (i++ == idx) + break; + } +err: + rtw_rhashtable_walk_stop(&iter); + rtw_rhashtable_walk_exit(&iter); + + if (IS_ERR(wpath) || !wpath) + return NULL; + + return wpath; +} + +/** + * Locking: must be called within a read rcu section. + */ +struct rtw_wds_path * +rtw_wds_path_lookup_by_idx(_adapter *adapter, int idx) +{ + return __rtw_wds_path_lookup_by_idx(adapter->wds_paths, idx); +} + +void dump_wpath(void *sel, _adapter *adapter) +{ + struct rtw_wds_path *wpath; + int idx = 0; + char dst[ETH_ALEN]; + char next_hop[ETH_ALEN]; + u32 age_ms; + + RTW_PRINT_SEL(sel, "num:%d\n", ATOMIC_READ(&adapter->wds_path_num)); + RTW_PRINT_SEL(sel, "%-17s %-17s %-6s\n" + , "dst", "next_hop", "age" + ); + + do { + rtw_rcu_read_lock(); + + wpath = rtw_wds_path_lookup_by_idx(adapter, idx); + if (wpath) { + _rtw_memcpy(dst, wpath->dst, ETH_ALEN); + _rtw_memcpy(next_hop, wpath->next_hop->cmn.mac_addr, ETH_ALEN); + age_ms = rtw_get_passing_time_ms(wpath->last_update); + } + + rtw_rcu_read_unlock(); + + if (wpath) { + RTW_PRINT_SEL(sel, MAC_FMT" "MAC_FMT" %6u\n" + , MAC_ARG(dst), MAC_ARG(next_hop) + , age_ms < 999999 ? age_ms : 999999 + ); + } + + idx++; + } while (wpath); +} + +static +struct rtw_wds_path *rtw_wds_path_new(_adapter *adapter, + const u8 *dst) +{ + struct rtw_wds_path *new_wpath; + + new_wpath = rtw_zmalloc(sizeof(struct rtw_wds_path)); + if (!new_wpath) + return NULL; + + new_wpath->adapter = adapter; + _rtw_memcpy(new_wpath->dst, dst, ETH_ALEN); + new_wpath->last_update = rtw_get_current_time(); + + return new_wpath; +} + +/** + * Returns: 0 on success + * + * State: the initial state of the new path is set to 0 + */ +struct rtw_wds_path *rtw_wds_path_add(_adapter *adapter, + const u8 *dst, struct sta_info *next_hop) +{ + struct rtw_wds_table *tbl = adapter->wds_paths; + struct rtw_wds_path *wpath, *new_wpath; + int ret; + + if (!tbl) + return ERR_PTR(-ENOTSUPP); + + if (_rtw_memcmp(dst, adapter_mac_addr(adapter), ETH_ALEN) == _TRUE) + /* never add ourselves as neighbours */ + return ERR_PTR(-ENOTSUPP); + + if (IS_MCAST(dst)) + return ERR_PTR(-ENOTSUPP); + + if (ATOMIC_INC_UNLESS(&adapter->wds_path_num, RTW_WDS_MAX_PATHS) == 0) + return ERR_PTR(-ENOSPC); + + new_wpath = rtw_wds_path_new(adapter, dst); + if (!new_wpath) + return ERR_PTR(-ENOMEM); + + do { + ret = rtw_rhashtable_lookup_insert_fast(&tbl->rhead, + &new_wpath->rhash, + rtw_wds_rht_params); + + if (ret == -EEXIST) + wpath = rtw_rhashtable_lookup_fast(&tbl->rhead, + dst, + rtw_wds_rht_params); + + } while (unlikely(ret == -EEXIST && !wpath)); + + if (ret && ret != -EEXIST) + return ERR_PTR(ret); + + /* At this point either new_wpath was added, or we found a + * matching entry already in the table; in the latter case + * free the unnecessary new entry. + */ + if (ret == -EEXIST) { + rtw_mfree(new_wpath, sizeof(struct rtw_wds_path)); + new_wpath = wpath; + } + rtw_wds_path_assign_nexthop(new_wpath, next_hop); + + return new_wpath; +} + +static void rtw_wds_path_free_rcu(struct rtw_wds_table *tbl, + struct rtw_wds_path *wpath) +{ + _adapter *adapter = wpath->adapter; + + ATOMIC_DEC(&adapter->wds_path_num); + + rtw_wpath_free_rcu(wpath); +} + +static void __rtw_wds_path_del(struct rtw_wds_table *tbl, struct rtw_wds_path *wpath) +{ + rtw_rhashtable_remove_fast(&tbl->rhead, &wpath->rhash, rtw_wds_rht_params); + rtw_wds_path_free_rcu(tbl, wpath); +} + +void rtw_wds_path_flush_by_nexthop(struct sta_info *sta) +{ + _adapter *adapter = sta->padapter; + struct rtw_wds_table *tbl = adapter->wds_paths; + struct rtw_wds_path *wpath; + rtw_rhashtable_iter iter; + int ret; + + if (!tbl) + return; + + ret = rtw_rhashtable_walk_enter(&tbl->rhead, &iter); + if (ret) + return; + + ret = rtw_rhashtable_walk_start(&iter); + if (ret && ret != -EAGAIN) + goto out; + + while ((wpath = rtw_rhashtable_walk_next(&iter))) { + if (IS_ERR(wpath) && PTR_ERR(wpath) == -EAGAIN) + continue; + if (IS_ERR(wpath)) + break; + + if (rtw_rcu_access_pointer(wpath->next_hop) == sta) + __rtw_wds_path_del(tbl, wpath); + } +out: + rtw_rhashtable_walk_stop(&iter); + rtw_rhashtable_walk_exit(&iter); +} + +static void rtw_wds_table_flush_by_iface(struct rtw_wds_table *tbl) +{ + struct rtw_wds_path *wpath; + rtw_rhashtable_iter iter; + int ret; + + if (!tbl) + return; + + ret = rtw_rhashtable_walk_enter(&tbl->rhead, &iter); + if (ret) + return; + + ret = rtw_rhashtable_walk_start(&iter); + if (ret && ret != -EAGAIN) + goto out; + + while ((wpath = rtw_rhashtable_walk_next(&iter))) { + if (IS_ERR(wpath) && PTR_ERR(wpath) == -EAGAIN) + continue; + if (IS_ERR(wpath)) + break; + __rtw_wds_path_del(tbl, wpath); + } +out: + rtw_rhashtable_walk_stop(&iter); + rtw_rhashtable_walk_exit(&iter); +} + +void rtw_wds_path_flush_by_iface(_adapter *adapter) +{ + rtw_wds_table_flush_by_iface(adapter->wds_paths); +} + +static int rtw_wds_table_path_del(struct rtw_wds_table *tbl, + const u8 *addr) +{ + struct rtw_wds_path *wpath; + + if (!tbl) + return -ENXIO; + + rtw_rcu_read_lock(); + wpath = rtw_rhashtable_lookup_fast(&tbl->rhead, addr, rtw_wds_rht_params); + if (!wpath) { + rtw_rcu_read_unlock(); + return -ENXIO; + } + + __rtw_wds_path_del(tbl, wpath); + rtw_rcu_read_unlock(); + return 0; +} + +int rtw_wds_path_del(_adapter *adapter, const u8 *addr) +{ + int err; + + err = rtw_wds_table_path_del(adapter->wds_paths, addr); + return err; +} + +int rtw_wds_pathtbl_init(_adapter *adapter) +{ + struct rtw_wds_table *tbl_path; + int ret; + + tbl_path = rtw_wds_table_alloc(); + if (!tbl_path) + return -ENOMEM; + + rtw_rhashtable_init(&tbl_path->rhead, &rtw_wds_rht_params); + + ATOMIC_SET(&adapter->wds_path_num, 0); + adapter->wds_paths = tbl_path; + + return 0; +} + +static +void rtw_wds_path_tbl_expire(_adapter *adapter, + struct rtw_wds_table *tbl) +{ + struct rtw_wds_path *wpath; + rtw_rhashtable_iter iter; + int ret; + + if (!tbl) + return; + + ret = rtw_rhashtable_walk_enter(&tbl->rhead, &iter); + if (ret) + return; + + ret = rtw_rhashtable_walk_start(&iter); + if (ret && ret != -EAGAIN) + goto out; + + while ((wpath = rtw_rhashtable_walk_next(&iter))) { + if (IS_ERR(wpath) && PTR_ERR(wpath) == -EAGAIN) + continue; + if (IS_ERR(wpath)) + break; + if (rtw_time_after(rtw_get_current_time(), wpath->last_update + RTW_WDS_PATH_EXPIRE)) + __rtw_wds_path_del(tbl, wpath); + } + +out: + rtw_rhashtable_walk_stop(&iter); + rtw_rhashtable_walk_exit(&iter); +} + +void rtw_wds_path_expire(_adapter *adapter) +{ + rtw_wds_path_tbl_expire(adapter, adapter->wds_paths); +} + +void rtw_wds_pathtbl_unregister(_adapter *adapter) +{ + if (adapter->wds_paths) { + rtw_wds_table_free(adapter->wds_paths); + adapter->wds_paths = NULL; + } +} + +int rtw_wds_nexthop_lookup(_adapter *adapter, const u8 *da, u8 *ra) +{ + struct rtw_wds_path *wpath; + struct sta_info *next_hop; + int err = -ENOENT; + + rtw_rcu_read_lock(); + wpath = rtw_wds_path_lookup(adapter, da); + + if (!wpath) + goto endlookup; + + next_hop = rtw_rcu_dereference(wpath->next_hop); + if (next_hop) { + _rtw_memcpy(ra, next_hop->cmn.mac_addr, ETH_ALEN); + err = 0; + } + +endlookup: + rtw_rcu_read_unlock(); + return err; +} + +#endif /* defined(CONFIG_AP_MODE) */ + +/* WDS group adddressed proxy TX record */ +struct rtw_wds_gptr { + u8 src[ETH_ALEN]; + systime last_update; + rtw_rhash_head rhash; + _adapter *adapter; + rtw_rcu_head rcu; +}; + +#define RTW_WDS_GPTR_EXPIRE (2 * HZ) + +/* Maximum number of gptrs per interface */ +#define RTW_WDS_MAX_GPTRS 1024 + +#ifdef PLATFORM_LINUX +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) +static void rtw_wgptr_free_rcu(struct rtw_wds_gptr *wgptr) +{ + kfree_rcu(wgptr, rcu); + rtw_mstat_update(MSTAT_TYPE_PHY, MSTAT_FREE, sizeof(struct rtw_wds_gptr)); +} +#else +static void rtw_wgptr_free_rcu_callback(rtw_rcu_head *head) +{ + struct rtw_wds_gptr *wgptr; + + wgptr = container_of(head, struct rtw_wds_gptr, rcu); + rtw_mfree(wgptr, sizeof(struct rtw_wds_gptr)); +} + +static void rtw_wgptr_free_rcu(struct rtw_wds_gptr *wgptr) +{ + call_rcu(&wgptr->rcu, rtw_wgptr_free_rcu_callback); +} +#endif +#endif /* PLATFORM_LINUX */ + +static void rtw_wds_gptr_free_rcu(struct rtw_wds_gptr_table *tbl, struct rtw_wds_gptr *wgptr) +{ + _adapter *adapter = wgptr->adapter; + + ATOMIC_DEC(&adapter->wds_gpt_record_num); + + rtw_wgptr_free_rcu(wgptr); +} + +static u32 rtw_wds_gptr_table_hash(const void *addr, u32 len, u32 seed) +{ + /* Use last four bytes of hw addr as hash index */ + return jhash_1word(*(u32 *)(addr+2), seed); +} + +static const rtw_rhashtable_params rtw_wds_gptr_rht_params = { + .nelem_hint = 2, + .automatic_shrinking = true, + .key_len = ETH_ALEN, + .key_offset = offsetof(struct rtw_wds_gptr, src), + .head_offset = offsetof(struct rtw_wds_gptr, rhash), + .hashfn = rtw_wds_gptr_table_hash, +}; + +static void rtw_wds_gptr_rht_free(void *ptr, void *tblptr) +{ + struct rtw_wds_gptr *wgptr = ptr; + struct rtw_wds_gptr_table *tbl = tblptr; + + rtw_wds_gptr_free_rcu(tbl, wgptr); +} + +static struct rtw_wds_gptr_table *rtw_wds_gptr_table_alloc(void) +{ + struct rtw_wds_gptr_table *newtbl; + + newtbl = rtw_malloc(sizeof(struct rtw_wds_gptr_table)); + if (!newtbl) + return NULL; + + return newtbl; +} + +static void rtw_wds_gptr_table_free(struct rtw_wds_gptr_table *tbl) +{ + rtw_rhashtable_free_and_destroy(&tbl->rhead, + rtw_wds_gptr_rht_free, tbl); + rtw_mfree(tbl, sizeof(struct rtw_wds_gptr_table)); +} + +static struct rtw_wds_gptr *rtw_wds_gptr_lookup(_adapter *adapter, const u8 *src) +{ + struct rtw_wds_gptr_table *tbl = adapter->wds_gpt_records; + + if (!tbl) + return NULL; + + return rtw_rhashtable_lookup_fast(&tbl->rhead, src, rtw_wds_gptr_rht_params); +} + +/** + * Locking: must be called within a read rcu section. + */ +static struct rtw_wds_gptr *rtw_wds_gptr_lookup_by_idx(_adapter *adapter, int idx) +{ + int i = 0, ret; + struct rtw_wds_gptr_table *tbl = adapter->wds_gpt_records; + struct rtw_wds_gptr *wgptr = NULL; + rtw_rhashtable_iter iter; + + if (!tbl) + return NULL; + + ret = rtw_rhashtable_walk_enter(&tbl->rhead, &iter); + if (ret) + return NULL; + + ret = rtw_rhashtable_walk_start(&iter); + if (ret && ret != -EAGAIN) + goto err; + + while ((wgptr = rtw_rhashtable_walk_next(&iter))) { + if (IS_ERR(wgptr) && PTR_ERR(wgptr) == -EAGAIN) + continue; + if (IS_ERR(wgptr)) + break; + if (i++ == idx) + break; + } +err: + rtw_rhashtable_walk_stop(&iter); + rtw_rhashtable_walk_exit(&iter); + + if (IS_ERR(wgptr) || !wgptr) + return NULL; + + return wgptr; +} + +void dump_wgptr(void *sel, _adapter *adapter) +{ + struct rtw_wds_gptr *wgptr; + int idx = 0; + char src[ETH_ALEN]; + u32 age_ms; + + RTW_PRINT_SEL(sel, "num:%d\n", ATOMIC_READ(&adapter->wds_gpt_record_num)); + RTW_PRINT_SEL(sel, "%-17s %-6s\n" + , "src", "age" + ); + + do { + rtw_rcu_read_lock(); + + wgptr = rtw_wds_gptr_lookup_by_idx(adapter, idx); + if (wgptr) { + _rtw_memcpy(src, wgptr->src, ETH_ALEN); + age_ms = rtw_get_passing_time_ms(wgptr->last_update); + } + + rtw_rcu_read_unlock(); + + if (wgptr) { + RTW_PRINT_SEL(sel, MAC_FMT" %6u\n" + , MAC_ARG(src) + , age_ms < 999999 ? age_ms : 999999 + ); + } + + idx++; + } while (wgptr); +} + +static struct rtw_wds_gptr *rtw_wds_gptr_new(_adapter *adapter, const u8 *src) +{ + struct rtw_wds_gptr *new_wgptr; + + new_wgptr = rtw_zmalloc(sizeof(struct rtw_wds_gptr)); + if (!new_wgptr) + return NULL; + + new_wgptr->adapter = adapter; + _rtw_memcpy(new_wgptr->src, src, ETH_ALEN); + new_wgptr->last_update = rtw_get_current_time(); + + return new_wgptr; +} + +static struct rtw_wds_gptr *rtw_wds_gptr_add(_adapter *adapter, const u8 *src) +{ + struct rtw_wds_gptr_table *tbl = adapter->wds_gpt_records; + struct rtw_wds_gptr *wgptr, *new_wgptr; + int ret; + + if (!tbl) + return ERR_PTR(-ENOTSUPP); + + if (ATOMIC_INC_UNLESS(&adapter->wds_gpt_record_num, RTW_WDS_MAX_PATHS) == 0) + return ERR_PTR(-ENOSPC); + + new_wgptr = rtw_wds_gptr_new(adapter, src); + if (!new_wgptr) + return ERR_PTR(-ENOMEM); + + do { + ret = rtw_rhashtable_lookup_insert_fast(&tbl->rhead, + &new_wgptr->rhash, + rtw_wds_gptr_rht_params); + + if (ret == -EEXIST) + wgptr = rtw_rhashtable_lookup_fast(&tbl->rhead, + src, + rtw_wds_gptr_rht_params); + + } while (unlikely(ret == -EEXIST && !wgptr)); + + if (ret && ret != -EEXIST) + return ERR_PTR(ret); + + /* At this point either new_wgptr was added, or we found a + * matching entry already in the table; in the latter case + * free the unnecessary new entry. + */ + if (ret == -EEXIST) { + rtw_mfree(new_wgptr, sizeof(struct rtw_wds_gptr)); + new_wgptr = wgptr; + } + + return new_wgptr; +} + +bool rtw_rx_wds_gptr_check(_adapter *adapter, const u8 *src) +{ + struct rtw_wds_gptr *wgptr; + bool ret = 0; + + rtw_rcu_read_lock(); + + wgptr = rtw_wds_gptr_lookup(adapter, src); + if (wgptr) + ret = rtw_time_after(wgptr->last_update + RTW_WDS_GPTR_EXPIRE, rtw_get_current_time()); + + rtw_rcu_read_unlock(); + + return ret; +} + +void rtw_tx_wds_gptr_update(_adapter *adapter, const u8 *src) +{ + struct rtw_wds_gptr *wgptr; + + rtw_rcu_read_lock(); + wgptr = rtw_wds_gptr_lookup(adapter, src); + if (!wgptr) + rtw_wds_gptr_add(adapter, src); + else + wgptr->last_update = rtw_get_current_time(); + rtw_rcu_read_unlock(); +} + +static void __rtw_wds_gptr_del(struct rtw_wds_gptr_table *tbl, struct rtw_wds_gptr *wgptr) +{ + rtw_rhashtable_remove_fast(&tbl->rhead, &wgptr->rhash, rtw_wds_gptr_rht_params); + rtw_wds_gptr_free_rcu(tbl, wgptr); +} + +void rtw_wds_gptr_expire(_adapter *adapter) +{ + struct rtw_wds_gptr_table *tbl = adapter->wds_gpt_records; + struct rtw_wds_gptr *wgptr; + rtw_rhashtable_iter iter; + int ret; + + if (!tbl) + return; + + ret = rtw_rhashtable_walk_enter(&tbl->rhead, &iter); + if (ret) + return; + + ret = rtw_rhashtable_walk_start(&iter); + if (ret && ret != -EAGAIN) + goto out; + + while ((wgptr = rtw_rhashtable_walk_next(&iter))) { + if (IS_ERR(wgptr) && PTR_ERR(wgptr) == -EAGAIN) + continue; + if (IS_ERR(wgptr)) + break; + if (rtw_time_after(rtw_get_current_time(), wgptr->last_update + RTW_WDS_GPTR_EXPIRE)) + __rtw_wds_gptr_del(tbl, wgptr); + } + +out: + rtw_rhashtable_walk_stop(&iter); + rtw_rhashtable_walk_exit(&iter); +} + +int rtw_wds_gptr_tbl_init(_adapter *adapter) +{ + struct rtw_wds_gptr_table *tbl; + int ret; + + tbl = rtw_wds_gptr_table_alloc(); + if (!tbl) + return -ENOMEM; + + rtw_rhashtable_init(&tbl->rhead, &rtw_wds_gptr_rht_params); + + ATOMIC_SET(&adapter->wds_gpt_record_num, 0); + adapter->wds_gpt_records = tbl; + + return 0; +} + +void rtw_wds_gptr_tbl_unregister(_adapter *adapter) +{ + if (adapter->wds_gpt_records) { + rtw_wds_gptr_table_free(adapter->wds_gpt_records); + adapter->wds_gpt_records = NULL; + } +} +#endif /* defined(CONFIG_RTW_WDS) */ + diff --git a/core/wds/rtw_wds.h b/core/wds/rtw_wds.h new file mode 100644 index 0000000..f1312c7 --- /dev/null +++ b/core/wds/rtw_wds.h @@ -0,0 +1,65 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2019 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#ifndef __RTW_WDS_H_ +#define __RTW_WDS_H_ + +#ifdef CONFIG_AP_MODE +struct rtw_wds_path { + u8 dst[ETH_ALEN]; + rtw_rhash_head rhash; + _adapter *adapter; + struct sta_info __rcu *next_hop; + rtw_rcu_head rcu; + systime last_update; +}; + +struct rtw_wds_table { + rtw_rhashtable rhead; +}; + +#define RTW_WDS_PATH_EXPIRE (600 * HZ) + +/* Maximum number of paths per interface */ +#define RTW_WDS_MAX_PATHS 1024 + +int rtw_wds_nexthop_lookup(_adapter *adapter, const u8 *da, u8 *ra); + +struct rtw_wds_path *rtw_wds_path_lookup(_adapter *adapter, const u8 *dst); +void dump_wpath(void *sel, _adapter *adapter); + +void rtw_wds_path_expire(_adapter *adapter); + +struct rtw_wds_path *rtw_wds_path_add(_adapter *adapter, const u8 *dst, struct sta_info *next_hop); +void rtw_wds_path_assign_nexthop(struct rtw_wds_path *path, struct sta_info *sta); + +int rtw_wds_pathtbl_init(_adapter *adapter); +void rtw_wds_pathtbl_unregister(_adapter *adapter); + +void rtw_wds_path_flush_by_nexthop(struct sta_info *sta); +#endif /* CONFIG_AP_MODE */ + +struct rtw_wds_gptr_table { + rtw_rhashtable rhead; +}; + +void dump_wgptr(void *sel, _adapter *adapter); +bool rtw_rx_wds_gptr_check(_adapter *adapter, const u8 *src); +void rtw_tx_wds_gptr_update(_adapter *adapter, const u8 *src); +void rtw_wds_gptr_expire(_adapter *adapter); +int rtw_wds_gptr_tbl_init(_adapter *adapter); +void rtw_wds_gptr_tbl_unregister(_adapter *adapter); + +#endif /* __RTW_WDSH_ */ + diff --git a/hal/btc/halbtc8822b1ant.c b/hal/btc/halbtc8822b1ant.c index ffcf806..17cd47c 100644 --- a/hal/btc/halbtc8822b1ant.c +++ b/hal/btc/halbtc8822b1ant.c @@ -28,9 +28,9 @@ static const char *const glbt_info_src_8822b_1ant[] = { "BT Info[bt scbd]" }; -u32 glcoex_ver_date_8822b_1ant = 20191120; -u32 glcoex_ver_8822b_1ant = 0x77; -u32 glcoex_ver_btdesired_8822b_1ant = 0x75; +u32 glcoex_ver_date_8822b_1ant = 20210316; +u32 glcoex_ver_8822b_1ant = 0x18317b; +u32 glcoex_ver_btdesired_8822b_1ant = 0x79; #if 0 static @@ -264,7 +264,8 @@ halbtc8822b1ant_ccklock_action(struct btc_coexist *btc) struct coex_sta_8822b_1ant *coex_sta = &btc->coex_sta_8822b_1ant; u8 h2c_parameter[2] = {0}; static u8 cnt; - + boolean wifi_busy = FALSE; +#if 0 if (coex_sta->tdma_timer_base == 3) { if (!coex_sta->is_no_wl_5ms_extend) { BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, @@ -279,10 +280,22 @@ halbtc8822b1ant_ccklock_action(struct btc_coexist *btc) } return; } +#endif + btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + if (!coex_sta->gl_wifi_busy || + coex_sta->wl_iot_peer == BTC_IOT_PEER_CISCO) { + cnt = 0; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi is not busy or CISCO AP, return!!\n"); + BTC_TRACE(trace_buf); + return; + } + if (!coex_sta->is_no_wl_5ms_extend && coex_sta->force_lps_ctrl && !coex_sta->cck_lock_ever) { - if (coex_sta->wl_fw_dbg_info[7] <= 5) + if (coex_sta->wl_fw_dbg_info[7] <= 5 && wifi_busy) cnt++; else cnt = 0; @@ -319,14 +332,13 @@ halbtc8822b1ant_ccklock_detect(struct btc_coexist *btc) { struct coex_sta_8822b_1ant *coex_sta = &btc->coex_sta_8822b_1ant; struct coex_dm_8822b_1ant *coex_dm = &btc->coex_dm_8822b_1ant; - struct btc_wifi_link_info_ext *link_info_ext = &btc->wifi_link_info_ext; + struct wifi_link_info_8822b_1ant *link_info_ext = + &btc->wifi_link_info_8822b_1ant; boolean is_cck_lock_rate = FALSE; if (coex_dm->bt_status == BTC_BTSTATUS_INQ_PAGE || - coex_sta->is_setup_link) { - coex_sta->cck_lock = FALSE; - return; - } + coex_sta->is_setup_link) + return; if (coex_sta->wl_rx_rate <= BTC_CCK_2 || coex_sta->wl_rts_rx_rate <= BTC_CCK_2) @@ -408,10 +420,6 @@ halbtc8822b1ant_set_tdma_timer_base(struct btc_coexist *btc, u8 type) BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s() h2c_0x69 = 0x%x\n", __func__, h2c_para[1]); BTC_TRACE(trace_buf); - - /* no 5ms_wl_slot_extend for 4-slot mode */ - if (coex_sta->tdma_timer_base == 3) - halbtc8822b1ant_ccklock_action(btc); } static void halbtc8822b1ant_low_penalty_ra(struct btc_coexist *btc, @@ -531,13 +539,14 @@ static void halbtc8822b1ant_enable_gnt_to_gpio(struct btc_coexist *btc, } } -static void halbtc8822b1ant_monitor_bt_ctr(struct btc_coexist *btc) +static boolean halbtc8822b1ant_monitor_bt_ctr(struct btc_coexist *btc) { struct coex_sta_8822b_1ant *coex_sta = &btc->coex_sta_8822b_1ant; - u32 reg_hp_txrx, reg_lp_txrx, u32tmp; + struct coex_dm_8822b_1ant *coex_dm = &btc->coex_dm_8822b_1ant; + u32 reg_hp_txrx, reg_lp_txrx, u32tmp, cnt_bt_all; u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0; - static u8 num_of_bt_counter_chk, cnt_autoslot_hang; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; + static u32 cnt_bt_pre = 0; + boolean is_run_coex = FALSE; reg_hp_txrx = 0x770; reg_lp_txrx = 0x774; @@ -563,9 +572,35 @@ static void halbtc8822b1ant_monitor_bt_ctr(struct btc_coexist *btc) /* reset counter */ btc->btc_write_1byte(btc, 0x76e, 0xc); + if (coex_sta->under_lps || coex_sta->under_ips || + (coex_sta->high_priority_tx == 65535 && + coex_sta->high_priority_rx == 65535 && + coex_sta->low_priority_tx == 65535 && + coex_sta->low_priority_rx == 65535)) + coex_sta->bt_ctr_ok = FALSE; + else + coex_sta->bt_ctr_ok = TRUE; + + if (!coex_sta->bt_ctr_ok) + return FALSE; + if (coex_sta->low_priority_tx > 1150 && !coex_sta->c2h_bt_inquiry_page) coex_sta->pop_event_cnt++; + + cnt_bt_all = coex_sta->high_priority_tx + + coex_sta->high_priority_rx + + coex_sta->low_priority_tx + + coex_sta->low_priority_rx; + + if ((cnt_bt_pre > (cnt_bt_all + 50) || + cnt_bt_all > (cnt_bt_pre + 50)) && + coex_dm->bt_status == BT_8822B_1ANT_BSTATUS_NCON_IDLE) + is_run_coex = TRUE; + + cnt_bt_pre = cnt_bt_all; + + return is_run_coex; } static void halbtc8822b1ant_monitor_wifi_ctr(struct btc_coexist *btc) @@ -577,7 +612,6 @@ static void halbtc8822b1ant_monitor_wifi_ctr(struct btc_coexist *btc) u32 cnt_cck; static u8 cnt_ccklocking; u8 h2c_parameter[1] = {0}; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); btc->btc_get(btc, BTC_GET_BL_WIFI_SCAN, &wifi_scan); @@ -859,9 +893,17 @@ static void halbtc8822b1ant_update_wifi_link_info(struct btc_coexist *btc, struct btc_wifi_link_info wifi_link_info; struct coex_dm_8822b_1ant *coex_dm = &btc->coex_dm_8822b_1ant; u8 wifi_central_chnl = 0, num_of_wifi_link = 0; - boolean isunder5G = FALSE, ismcc25g = FALSE, isp2pconnected = FALSE; u32 wifi_link_status = 0; + boolean isunder5G = FALSE, ismcc25g = FALSE, isp2pconnected = FALSE; + boolean wifi_connected = FALSE; + boolean scan = FALSE, link = FALSE, roam = FALSE, under_4way = FALSE; + btc->btc_get(btc, BTC_GET_BL_WIFI_SCAN, &scan); + btc->btc_get(btc, BTC_GET_BL_WIFI_LINK, &link); + btc->btc_get(btc, BTC_GET_BL_WIFI_ROAM, &roam); + btc->btc_get(btc, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &under_4way); + btc->btc_get(btc, BTC_GET_BL_WIFI_LW_PWR_STATE, + &wifi_link_info_ext->is_32k); btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_link_info_ext->is_connected); @@ -959,6 +1001,20 @@ static void halbtc8822b1ant_update_wifi_link_info(struct btc_coexist *btc, wifi_link_info_ext->num_of_active_port = num_of_wifi_link; wifi_link_info_ext->is_p2p_connected = isp2pconnected; + + if (scan || link || roam || under_4way || + reason == BT_8822B_1ANT_RSN_2GSCANSTART || + reason == BT_8822B_1ANT_RSN_2GSWITCHBAND || + reason == BT_8822B_1ANT_RSN_2GCONSTART || + reason == BT_8822B_1ANT_RSN_2GSPECIALPKT) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], scan = %d, link = %d, roam = %d 4way = %d!!!\n", + scan, link, roam, under_4way); + BTC_TRACE(trace_buf); + coex_sta->is_wifi_linkscan_process = TRUE; + } else { + coex_sta->is_wifi_linkscan_process = FALSE; + } BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], wifi_link_info: link_mode=%d, STA_Ch=%d, P2P_Ch=%d, AnyClient_Join_Go=%d !\n", @@ -1188,6 +1244,7 @@ static void halbtc8822b1ant_update_bt_link_info(struct btc_coexist *btc) #if 1 if (coex_sta->hid_busy_num == 0 && coex_sta->hid_pair_cnt > 0 && + coex_sta->bt_ctr_ok && coex_sta->low_priority_tx > 1500 && coex_sta->low_priority_rx > 1500 && !coex_sta->c2h_bt_inquiry_page) @@ -1390,11 +1447,16 @@ halbtc8822b1ant_update_wifi_ch_info(struct btc_coexist *btc, u8 type) } } - coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; - coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; - coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; + /* Only send mailbox if ch info change */ + if (coex_dm->wifi_chnl_info[0] != h2c_parameter[0] && + coex_dm->wifi_chnl_info[1] != h2c_parameter[1] && + coex_dm->wifi_chnl_info[2] != h2c_parameter[2]) { - btc->btc_fill_h2c(btc, 0x66, 3, h2c_parameter); + coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; + coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; + coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; + btc->btc_fill_h2c(btc, 0x66, 3, h2c_parameter); + } BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], para[0:2] = 0x%x 0x%x 0x%x\n", h2c_parameter[0], @@ -1651,6 +1713,7 @@ halbtc8822b1ant_set_gnt_wl(struct btc_coexist *btc, u8 state) static void halbtc8822b1ant_mimo_ps(struct btc_coexist *btc, boolean force_exec, u8 state) { +#if 0 static u8 pre_state; if (!force_exec) { @@ -1665,6 +1728,7 @@ static void halbtc8822b1ant_mimo_ps(struct btc_coexist *btc, BTC_TRACE(trace_buf); btc->btc_set(btc, BTC_SET_MIMO_PS_MODE, &state); +#endif } static void halbtc8822b1ant_set_table(struct btc_coexist *btc, @@ -1862,6 +1926,16 @@ void halbtc8822b1ant_table(struct btc_coexist *btc, boolean force_exec, u8 type) 0x5a5a5aaa, break_table, select_table); break; + case 29: + halbtc8822b1ant_set_table(btc, force_exec, 0xdaffdaff, + 0xdaffdaff, break_table, + select_table); + break; + case 30: + halbtc8822b1ant_set_table(btc, force_exec, 0x6a555a5a, + 0x5a5a5a5a, break_table, + select_table); + break; default: break; } @@ -2055,7 +2129,6 @@ void halbtc8822b1ant_set_tdma(struct btc_coexist *btc, u8 byte1, u8 h2c_parameter[5] = {0}; u8 real_byte1 = byte1, real_byte5 = byte5; boolean ap_enable = FALSE, result = FALSE; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; u8 ps_type = BTC_PS_WIFI_NATIVE; if (byte5 & BIT(2)) @@ -2146,7 +2219,6 @@ halbtc8822b1ant_tdma(struct btc_coexist *btc, boolean force_exec, { struct coex_sta_8822b_1ant *coex_sta = &btc->coex_sta_8822b_1ant; struct coex_dm_8822b_1ant *coex_dm = &btc->coex_dm_8822b_1ant; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; u8 type; btc->btc_set_atomic(btc, &coex_dm->setting_tdma, TRUE); @@ -2154,7 +2226,7 @@ halbtc8822b1ant_tdma(struct btc_coexist *btc, boolean force_exec, /* tcase: bit0~7 --> tdma case index * bit8 --> for 4-slot (50ms) mode */ - if (tcase & TDMA_4SLOT)/* 4-slot (50ms) mode */ + if (tcase & TDMA_4SLOT)/* 4-slot (50ms) mode */ halbtc8822b1ant_set_tdma_timer_base(btc, 3); else halbtc8822b1ant_set_tdma_timer_base(btc, 0); @@ -2182,7 +2254,12 @@ halbtc8822b1ant_tdma(struct btc_coexist *btc, boolean force_exec, type); BTC_TRACE(trace_buf); - halbtc8822b1ant_write_scbd(btc, BT_8822B_1ANT_SCBD_TDMA, TRUE); + if (coex_sta->a2dp_exist && coex_sta->bt_inq_page_remain) + halbtc8822b1ant_write_scbd(btc, BT_8822B_1ANT_SCBD_TDMA, + FALSE); + else + halbtc8822b1ant_write_scbd(btc, BT_8822B_1ANT_SCBD_TDMA, + TRUE); /* enable TBTT nterrupt */ btc->btc_write_1byte_bitmask(btc, 0x550, 0x8, 0x1); @@ -2277,7 +2354,7 @@ halbtc8822b1ant_tdma(struct btc_coexist *btc, boolean force_exec, 0x10); break; case 25: - halbtc8822b1ant_set_tdma(btc, 0x51, 0x3a, 0x3, 0x11, + halbtc8822b1ant_set_tdma(btc, 0x51, 0x3a, 0x3, 0x10, 0x50); break; case 26: @@ -2897,6 +2974,9 @@ static void halbtc8822b1ant_action_bt_whql_test(struct btc_coexist *btc) halbtc8822b1ant_set_wl_rx_gain(btc, NM_EXCU, FALSE); halbtc8822b1ant_set_bt_rx_gain(btc, NM_EXCU, FALSE); + halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, + BT_8822B_1ANT_PHASE_2G); + halbtc8822b1ant_table(btc, NM_EXCU, 0); halbtc8822b1ant_tdma(btc, NM_EXCU, FALSE, 8); } @@ -2911,6 +2991,9 @@ static void halbtc8822b1ant_action_bt_relink(struct btc_coexist *btc) halbtc8822b1ant_set_wl_rx_gain(btc, NM_EXCU, FALSE); halbtc8822b1ant_set_bt_rx_gain(btc, NM_EXCU, FALSE); + halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, + BT_8822B_1ANT_PHASE_2G); + if (coex_sta->gl_wifi_busy) { halbtc8822b1ant_table(btc, NM_EXCU, 3); @@ -2934,7 +3017,7 @@ static void halbtc8822b1ant_action_bt_idle(struct btc_coexist *btc) wifi_rssi_state = halbtc8822b1ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2, - 20, 0); + 32, 0); halbtc8822b1ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); halbtc8822b1ant_set_bt_tx_power(btc, NM_EXCU, 0); @@ -2984,6 +3067,9 @@ static void halbtc8822b1ant_action_bt_inquiry(struct btc_coexist *btc) halbtc8822b1ant_set_wl_rx_gain(btc, NM_EXCU, FALSE); halbtc8822b1ant_set_bt_rx_gain(btc, NM_EXCU, FALSE); + halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, + BT_8822B_1ANT_PHASE_2G); + btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); @@ -3032,17 +3118,35 @@ void halbtc8822b1ant_action_bt_sco_hid_busy(struct btc_coexist *btc) { struct coex_sta_8822b_1ant *coex_sta = &btc->coex_sta_8822b_1ant; struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; - boolean wifi_busy = FALSE; + boolean wifi_busy = FALSE, is_bt_ctr_hi = FALSE; halbtc8822b1ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); halbtc8822b1ant_set_bt_tx_power(btc, NM_EXCU, 0); halbtc8822b1ant_set_wl_rx_gain(btc, NM_EXCU, FALSE); halbtc8822b1ant_set_bt_rx_gain(btc, NM_EXCU, FALSE); + if (coex_sta->bt_ctr_ok && + (coex_sta->low_priority_rx + coex_sta->low_priority_tx > 360)) + is_bt_ctr_hi = TRUE; + else + is_bt_ctr_hi = FALSE; + btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); if (!wifi_busy) wifi_busy = coex_sta->gl_wifi_busy; +#if 0 + if (coex_sta->cck_lock_ever) { + coex_sta->wl_coex_mode = BT_8822B_1ANT_WLINK_2GFREE; + halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, + BT_8822B_1ANT_PHASE_2G_FREERUN); + halbtc8822b1ant_table(btc, NM_EXCU, 29); + halbtc8822b1ant_tdma(btc, NM_EXCU, FALSE, 8); + return; + } +#endif + halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, + BT_8822B_1ANT_PHASE_2G); if (bt_link_info->sco_exist) { if (coex_sta->is_bt_multi_link) { @@ -3059,9 +3163,8 @@ void halbtc8822b1ant_action_bt_sco_hid_busy(struct btc_coexist *btc) /* for HID exist */ if (bt_link_info->hid_only && (coex_sta->is_bt_multi_link || - (coex_sta->low_priority_rx + - coex_sta->low_priority_tx > 360) || - bt_link_info->slave_role)) { + is_bt_ctr_hi || + bt_link_info->slave_role)) { if (coex_sta->gl_wifi_busy && (coex_sta->wl_rx_rate <= 3 || coex_sta->wl_rts_rx_rate <= 3)) @@ -3096,9 +3199,12 @@ static void halbtc8822b1ant_action_bt_acl_busy(struct btc_coexist *btc) boolean wifi_busy = FALSE, wifi_turbo = FALSE, ap_enable = FALSE; static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW; static u8 prewifi_rssi_state2 = BTC_RSSI_STATE_LOW; - u32 wifi_bw = 1; + u32 wifi_bw = 1, slot_type = 0; u8 wifi_rssi_state, wifi_rssi_state2, iot_peer = BTC_IOT_PEER_UNKNOWN; + halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, + BT_8822B_1ANT_PHASE_2G); + btc->btc_get(btc, BTC_GET_U4_WIFI_BW, &wifi_bw); btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); btc->btc_get(btc, BTC_GET_U1_AP_NUM, &coex_sta->scan_ap_num); @@ -3200,20 +3306,25 @@ static void halbtc8822b1ant_action_bt_acl_busy(struct btc_coexist *btc) 7 | TDMA_4SLOT); } else if (bt_link_info->hid_exist && bt_link_info->a2dp_exist) { /* HID + A2DP */ + + /*4-slot will not be applied when AP is CISCO*/ + if (coex_sta->wl_iot_peer != BTC_IOT_PEER_CISCO) + slot_type = TDMA_4SLOT; + halbtc8822b1ant_table(btc, FC_EXCU, 1); if (coex_sta->connect_ap_period_cnt > 0 || !wifi_busy) { halbtc8822b1ant_tdma(btc, NM_EXCU, TRUE, - 26 | TDMA_4SLOT); + 26 | slot_type); } else if (coex_sta->bt_418_hid_exist || coex_sta->bt_ble_hid_exist) { halbtc8822b1ant_wltoggle_table(btc, NM_EXCU, 3, 0xaa, 0x5a, 0x5a, 0x5a); halbtc8822b1ant_tdma(btc, NM_EXCU, TRUE, - 39 | TDMA_4SLOT); + 39 | slot_type); } else { halbtc8822b1ant_tdma(btc, NM_EXCU, TRUE, - 7 | TDMA_4SLOT); + 7 | slot_type); } /* PAN, HID+PAN */ } else if ((bt_link_info->pan_only) || @@ -3238,28 +3349,11 @@ static void halbtc8822b1ant_action_bt_acl_busy(struct btc_coexist *btc) static void halbtc8822b1ant_action_bt_mr(struct btc_coexist *btc) { - struct wifi_link_info_8822b_1ant *wifi_link_info_ext = - &btc->wifi_link_info_8822b_1ant; + halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, + BT_8822B_1ANT_PHASE_2G_FREERUN); - if (!wifi_link_info_ext->is_all_under_5g) { - halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, - BT_8822B_1ANT_PHASE_2G_FREERUN); - - halbtc8822b1ant_table(btc, NM_EXCU, 8); - halbtc8822b1ant_tdma(btc, NM_EXCU, FALSE, 8); - - /* Enter MIMO Power Save, 0:enable */ - halbtc8822b1ant_mimo_ps(btc, NM_EXCU, 0); - } else { - halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, - BT_8822B_1ANT_PHASE_5G); - - halbtc8822b1ant_table(btc, NM_EXCU, 0); - halbtc8822b1ant_tdma(btc, NM_EXCU, FALSE, 8); - - /* No MIMO Power Save, 3:disable */ - halbtc8822b1ant_mimo_ps(btc, NM_EXCU, 3); - } + halbtc8822b1ant_table(btc, NM_EXCU, 8); + halbtc8822b1ant_tdma(btc, NM_EXCU, FALSE, 8); } static void halbtc8822b1ant_action_rf4ce(struct btc_coexist *btc) @@ -3269,6 +3363,9 @@ static void halbtc8822b1ant_action_rf4ce(struct btc_coexist *btc) halbtc8822b1ant_set_wl_rx_gain(btc, NM_EXCU, FALSE); halbtc8822b1ant_set_bt_rx_gain(btc, NM_EXCU, FALSE); + halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, + BT_8822B_1ANT_PHASE_2G); + halbtc8822b1ant_table(btc, NM_EXCU, 1); halbtc8822b1ant_tdma(btc, NM_EXCU, TRUE, 50); } @@ -3296,6 +3393,9 @@ static void halbtc8822b1ant_action_wifi_only(struct btc_coexist *btc) halbtc8822b1ant_set_wl_rx_gain(btc, NM_EXCU, FALSE); halbtc8822b1ant_set_bt_rx_gain(btc, NM_EXCU, FALSE); + halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, + BT_8822B_1ANT_PHASE_2G); + btc->btc_get(btc, BTC_GET_BL_RF4CE_CONNECTED, &rf4ce_enabled); btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); @@ -3319,7 +3419,6 @@ halbtc8822b1ant_action_wifi_native_lps(struct btc_coexist *btc) { struct wifi_link_info_8822b_1ant *wifi_link_info_ext = &btc->wifi_link_info_8822b_1ant; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; if (wifi_link_info_ext->is_all_under_5g) return; @@ -3329,6 +3428,9 @@ halbtc8822b1ant_action_wifi_native_lps(struct btc_coexist *btc) halbtc8822b1ant_set_wl_rx_gain(btc, NM_EXCU, FALSE); halbtc8822b1ant_set_bt_rx_gain(btc, NM_EXCU, FALSE); + halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, + BT_8822B_1ANT_PHASE_2G); + halbtc8822b1ant_table(btc, NM_EXCU, 21); halbtc8822b1ant_tdma(btc, NM_EXCU, FALSE, 8); } @@ -3342,8 +3444,11 @@ static void halbtc8822b1ant_action_wifi_linkscan(struct btc_coexist *btc) halbtc8822b1ant_set_wl_rx_gain(btc, NM_EXCU, FALSE); halbtc8822b1ant_set_bt_rx_gain(btc, NM_EXCU, FALSE); + halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, + BT_8822B_1ANT_PHASE_2G); + if (bt_link_info->pan_exist) { - halbtc8822b1ant_table(btc, NM_EXCU, 1); + halbtc8822b1ant_table(btc, NM_EXCU, 30); halbtc8822b1ant_tdma(btc, NM_EXCU, TRUE, 22); } else if (bt_link_info->a2dp_exist) { halbtc8822b1ant_table(btc, NM_EXCU, 1); @@ -3362,6 +3467,9 @@ halbtc8822b1ant_action_wifi_not_connected(struct btc_coexist *btc) halbtc8822b1ant_set_wl_rx_gain(btc, NM_EXCU, FALSE); halbtc8822b1ant_set_bt_rx_gain(btc, NM_EXCU, FALSE); + halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, + BT_8822B_1ANT_PHASE_2G); + /* tdma and coex table */ halbtc8822b1ant_table(btc, NM_EXCU, 0); halbtc8822b1ant_tdma(btc, FC_EXCU, FALSE, 8); @@ -3379,7 +3487,8 @@ static void halbtc8822b1ant_action_wifi_connected(struct btc_coexist *btc) if (coex_dm->bt_status == BT_8822B_1ANT_BSTATUS_ACL_BUSY || coex_dm->bt_status == BT_8822B_1ANT_BSTATUS_ACL_SCO_BUSY) { - if (bt_link_info->hid_only) /* HID only */ + if (bt_link_info->hid_only || bt_link_info->sco_exist) + /* HID only or SCO*/ halbtc8822b1ant_action_bt_sco_hid_busy(btc); else halbtc8822b1ant_action_bt_acl_busy(btc); @@ -3482,7 +3591,6 @@ static void halbtc8822b1ant_action_wifi_multiport2g(struct btc_coexist *btc) { struct coex_sta_8822b_1ant *coex_sta = &btc->coex_sta_8822b_1ant; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; u32 traffic_dir; u8 ant_pase; @@ -3499,8 +3607,7 @@ halbtc8822b1ant_action_wifi_multiport2g(struct btc_coexist *btc) BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], BT is disabled !!!\n"); BTC_TRACE(trace_buf); - halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, - BT_8822B_1ANT_PHASE_2G); + halbtc8822b1ant_action_wifi_only(btc); } else if (coex_sta->is_setup_link || coex_sta->bt_relink_downcount != 0) { @@ -3543,8 +3650,6 @@ halbtc8822b1ant_action_wifi_multiport2g(struct btc_coexist *btc) "[BTCoex], wifi_multiport2g, WL scan!!\n"); BTC_TRACE(trace_buf); - halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, - BT_8822B_1ANT_PHASE_2G); halbtc8822b1ant_action_wifi_linkscan(btc); } else { BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, @@ -3590,29 +3695,6 @@ static void halbtc8822b1ant_run_coex(struct btc_coexist *btc, u8 reason) struct coex_sta_8822b_1ant *coex_sta = &btc->coex_sta_8822b_1ant; struct wifi_link_info_8822b_1ant *wifi_link_info_ext = &btc->wifi_link_info_8822b_1ant; - boolean wifi_connected = FALSE, wifi_32k = false; - boolean scan = FALSE, link = FALSE, roam = FALSE, under_4way = FALSE; - - btc->btc_get(btc, BTC_GET_BL_WIFI_SCAN, &scan); - btc->btc_get(btc, BTC_GET_BL_WIFI_LINK, &link); - btc->btc_get(btc, BTC_GET_BL_WIFI_ROAM, &roam); - btc->btc_get(btc, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &under_4way); - btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); - btc->btc_get(btc, BTC_GET_BL_WIFI_LW_PWR_STATE, &wifi_32k); - - if (scan || link || roam || under_4way || - reason == BT_8822B_1ANT_RSN_2GSCANSTART || - reason == BT_8822B_1ANT_RSN_2GSWITCHBAND || - reason == BT_8822B_1ANT_RSN_2GCONSTART || - reason == BT_8822B_1ANT_RSN_2GSPECIALPKT) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], scan = %d, link = %d, roam = %d 4way = %d!!!\n", - scan, link, roam, under_4way); - BTC_TRACE(trace_buf); - coex_sta->is_wifi_linkscan_process = TRUE; - } else { - coex_sta->is_wifi_linkscan_process = FALSE; - } /* update wifi_link_info_ext variable */ halbtc8822b1ant_update_wifi_link_info(btc, reason); @@ -3645,7 +3727,7 @@ static void halbtc8822b1ant_run_coex(struct btc_coexist *btc, u8 reason) return; } - if (coex_sta->under_lps && wifi_32k) { + if (coex_sta->under_lps && wifi_link_info_ext->is_32k) { BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], RunCoexistMechanism(), return for wifi is under LPS-32K !!!\n"); BTC_TRACE(trace_buf); @@ -3666,21 +3748,8 @@ static void halbtc8822b1ant_run_coex(struct btc_coexist *btc, u8 reason) return; } - if (coex_sta->msft_mr_exist && wifi_connected) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], RunCoexistMechanism(), microsoft MR!!\n"); - BTC_TRACE(trace_buf); - - coex_sta->wl_coex_mode = BT_8822B_1ANT_WLINK_BTMR; - halbtc8822b1ant_action_bt_mr(btc); - return; - } - coex_sta->coex_run_cnt++; - /* No MIMO Power Save, 3:disable */ - halbtc8822b1ant_mimo_ps(btc, NM_EXCU, 3); - /* Pure-5G Coex Process */ if (wifi_link_info_ext->is_all_under_5g) { BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, @@ -3689,10 +3758,20 @@ static void halbtc8822b1ant_run_coex(struct btc_coexist *btc, u8 reason) coex_sta->wl_coex_mode = BT_8822B_1ANT_WLINK_5G; halbtc8822b1ant_action_wifi_under5g(btc); - return; + goto exit; } - if (wifi_link_info_ext->is_mcc_25g) { /* not iclude scan action */ + if (coex_sta->msft_mr_exist && wifi_link_info_ext->is_connected) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], RunCoexistMechanism(), microsoft MR!!\n"); + BTC_TRACE(trace_buf); + + coex_sta->wl_coex_mode = BT_8822B_1ANT_WLINK_BTMR; + halbtc8822b1ant_action_bt_mr(btc); + goto exit; + } + + if (wifi_link_info_ext->is_mcc_25g) { /* not include scan action */ BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], WiFi is under mcc dual-band!!!\n"); @@ -3700,7 +3779,7 @@ static void halbtc8822b1ant_run_coex(struct btc_coexist *btc, u8 reason) coex_sta->wl_coex_mode = BT_8822B_1ANT_WLINK_25GMPORT; halbtc8822b1ant_action_wifi_multiport25g(btc); - return; + goto exit; } /* if multi-port or P2PGO+Client_Join */ @@ -3721,7 +3800,7 @@ static void halbtc8822b1ant_run_coex(struct btc_coexist *btc, u8 reason) coex_sta->wl_coex_mode = BT_8822B_1ANT_WLINK_2GMPORT; halbtc8822b1ant_action_wifi_multiport2g(btc); - return; + goto exit; } BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, @@ -3742,50 +3821,45 @@ static void halbtc8822b1ant_run_coex(struct btc_coexist *btc, u8 reason) BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], BT is disabled !!!\n"); BTC_TRACE(trace_buf); - halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, - BT_8822B_1ANT_PHASE_2G); + halbtc8822b1ant_action_wifi_only(btc); - return; + goto exit; } if (coex_sta->under_lps && !coex_sta->force_lps_ctrl) { BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], RunCoexistMechanism(), wifi is under LPS !!!\n"); BTC_TRACE(trace_buf); - halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, - BT_8822B_1ANT_PHASE_2G); + halbtc8822b1ant_action_wifi_native_lps(btc); - return; + goto exit; } if (coex_sta->bt_whck_test) { BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], BT is under WHCK TEST!!!\n"); BTC_TRACE(trace_buf); - halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, - BT_8822B_1ANT_PHASE_2G); + halbtc8822b1ant_action_bt_whql_test(btc); - return; + goto exit; } if (coex_sta->is_setup_link || coex_sta->bt_relink_downcount != 0) { BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], BT is re-link !!!\n"); BTC_TRACE(trace_buf); - halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, - BT_8822B_1ANT_PHASE_2G); + halbtc8822b1ant_action_bt_relink(btc); - return; + goto exit; } if (coex_sta->c2h_bt_inquiry_page) { BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], BT is under inquiry/page !!\n"); BTC_TRACE(trace_buf); - halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, - BT_8822B_1ANT_PHASE_2G); + halbtc8822b1ant_action_bt_inquiry(btc); - return; + goto exit; } if ((coex_dm->bt_status == BT_8822B_1ANT_BSTATUS_NCON_IDLE || @@ -3795,34 +3869,41 @@ static void halbtc8822b1ant_run_coex(struct btc_coexist *btc, u8 reason) "############# [BTCoex], BT Is idle\n"); BTC_TRACE(trace_buf); halbtc8822b1ant_action_bt_idle(btc); - return; + goto exit; } if (coex_sta->is_wifi_linkscan_process) { BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], wifi is under linkscan process!!\n"); BTC_TRACE(trace_buf); - halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, - BT_8822B_1ANT_PHASE_2G); + halbtc8822b1ant_action_wifi_linkscan(btc); - return; + goto exit; } - if (wifi_connected) { + if (wifi_link_info_ext->is_connected) { BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], wifi is under connected!!\n"); BTC_TRACE(trace_buf); - halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, - BT_8822B_1ANT_PHASE_2G); + halbtc8822b1ant_action_wifi_connected(btc); + goto exit; } else { BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], wifi is under not-connected!!\n"); BTC_TRACE(trace_buf); - halbtc8822b1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, - BT_8822B_1ANT_PHASE_2G); + halbtc8822b1ant_action_wifi_not_connected(btc); + goto exit; } +exit: + + /*MIMO Power Save-> 0:enable 3:disable*/ + if (coex_sta->wl_coex_mode == BT_8822B_1ANT_WLINK_BTMR || + coex_sta->wl_coex_mode == BT_8822B_1ANT_WLINK_2GFREE) + halbtc8822b1ant_mimo_ps(btc, NM_EXCU, 1); + else + halbtc8822b1ant_mimo_ps(btc, NM_EXCU, 0); } static void halbtc8822b1ant_init_coex_var(struct btc_coexist *btc) @@ -4447,12 +4528,13 @@ void ex_halbtc8822b1ant_display_coex_info(struct btc_coexist *btc) ps_tdma_case = coex_dm->cur_ps_tdma; CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %02x %02x %02x %02x %02x (case-%d, %s)", + "\r\n %-35s = %02x %02x %02x %02x %02x (case-%d, %s, Timer:%d)", "TDMA", coex_dm->ps_tdma_para[0], coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2], coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4], ps_tdma_case, - (coex_dm->cur_ps_tdma_on ? "TDMA-On" : "TDMA-Off")); + (coex_dm->cur_ps_tdma_on ? "On" : "Off"), + coex_sta->tdma_timer_base); CL_PRINTF(cli_buf); switch (coex_sta->wl_coex_mode) { @@ -5001,6 +5083,7 @@ void ex_halbtc8822b1ant_media_status_notify(struct btc_coexist *btc, u8 type) struct coex_sta_8822b_1ant *coex_sta = &btc->coex_sta_8822b_1ant; struct coex_dm_8822b_1ant *coex_dm = &btc->coex_dm_8822b_1ant; boolean wifi_under_b_mode = FALSE; + u8 h2c_parameter[2] = {0}; if (btc->manual_control || btc->stop_coex_dm) return; @@ -5039,6 +5122,12 @@ void ex_halbtc8822b1ant_media_status_notify(struct btc_coexist *btc, u8 type) else btc->btc_write_1byte_bitmask(btc, 0x6cf, BIT(4), 0x1); + /*Leak-AP protection will reopen when connecting AP*/ + h2c_parameter[0] = 0xc; + h2c_parameter[1] = 0x0; + btc->btc_fill_h2c(btc, 0x69, 2, h2c_parameter); + coex_sta->is_no_wl_5ms_extend = FALSE; + halbtc8822b1ant_run_coex(btc, BT_8822B_1ANT_RSN_2GMEDIA); } else { BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, @@ -5054,7 +5143,7 @@ void ex_halbtc8822b1ant_media_status_notify(struct btc_coexist *btc, u8 type) halbtc8822b1ant_run_coex(btc, BT_8822B_1ANT_RSN_MEDIADISCON); } - + btc->btc_get(btc, BTC_GET_U1_IOT_PEER, &coex_sta->wl_iot_peer); halbtc8822b1ant_update_wifi_ch_info(btc, type); } @@ -5218,6 +5307,14 @@ void ex_halbtc8822b1ant_bt_info_notify(struct btc_coexist *btc, u8 *tmp_buf, coex_sta->c2h_bt_inquiry_page = ((coex_sta->bt_info_lb2 & BIT(2)) ? TRUE : FALSE); + if (coex_sta->bt_inq_page_pre != coex_sta->c2h_bt_inquiry_page) { + coex_sta->bt_inq_page_pre = coex_sta->c2h_bt_inquiry_page; + coex_sta->bt_inq_page_remain = TRUE; + + if (!coex_sta->c2h_bt_inquiry_page) + coex_sta->bt_inq_page_downcount = 2; + } + if ((coex_sta->bt_info_lb2 & 0x49) == 0x49) coex_sta->a2dp_bit_pool = (coex_sta->bt_info_hb3 & 0x7f); else @@ -5241,6 +5338,7 @@ void ex_halbtc8822b1ant_bt_info_notify(struct btc_coexist *btc, u8 *tmp_buf, if (coex_sta->hid_pair_cnt > 0 && coex_sta->hid_busy_num >= 2) { coex_sta->bt_418_hid_exist = TRUE; } else if (coex_sta->hid_busy_num == 1 && + coex_sta->bt_ctr_ok && (coex_sta->high_priority_rx + 100 < coex_sta->high_priority_tx) && coex_sta->high_priority_rx < 100) { @@ -5548,7 +5646,8 @@ void ex_halbtc8822b1ant_coex_dm_reset(struct btc_coexist *btc) void ex_halbtc8822b1ant_periodical(struct btc_coexist *btc) { struct coex_sta_8822b_1ant *coex_sta = &btc->coex_sta_8822b_1ant; - boolean bt_relink_finish = FALSE, is_defreeze = FALSE; + boolean bt_relink_finish = FALSE, is_defreeze = FALSE, + bt_ctr_change = FALSE; static u8 freeze_cnt; BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, @@ -5558,7 +5657,7 @@ void ex_halbtc8822b1ant_periodical(struct btc_coexist *btc) if (!btc->auto_report) halbtc8822b1ant_query_bt_info(btc); - halbtc8822b1ant_monitor_bt_ctr(btc); + bt_ctr_change = halbtc8822b1ant_monitor_bt_ctr(btc); halbtc8822b1ant_monitor_wifi_ctr(btc); halbtc8822b1ant_update_wifi_link_info(btc, BT_8822B_1ANT_RSN_PERIODICAL); @@ -5572,6 +5671,12 @@ void ex_halbtc8822b1ant_periodical(struct btc_coexist *btc) } } + if (coex_sta->bt_inq_page_downcount != 0) { + coex_sta->bt_inq_page_downcount--; + if (coex_sta->bt_relink_downcount == 0) + coex_sta->bt_inq_page_remain = FALSE; + } + if (coex_sta->freeze_coexrun_by_btinfo) { freeze_cnt++; @@ -5621,7 +5726,7 @@ void ex_halbtc8822b1ant_periodical(struct btc_coexist *btc) } if (halbtc8822b1ant_moniter_wifibt_status(btc) || bt_relink_finish || - coex_sta->is_set_ps_state_fail || is_defreeze) + coex_sta->is_set_ps_state_fail || is_defreeze || bt_ctr_change) halbtc8822b1ant_run_coex(btc, BT_8822B_1ANT_RSN_PERIODICAL); } diff --git a/hal/btc/halbtc8822b1ant.h b/hal/btc/halbtc8822b1ant.h index 196d948..d0eca61 100644 --- a/hal/btc/halbtc8822b1ant.h +++ b/hal/btc/halbtc8822b1ant.h @@ -205,6 +205,7 @@ enum bt_8822b_1ant_WL_LINK_MODE { BT_8822B_1ANT_WLINK_2GGO = 0x4, BT_8822B_1ANT_WLINK_2GGC = 0x5, BT_8822B_1ANT_WLINK_BTMR = 0x6, + BT_8822B_1ANT_WLINK_2GFREE = 0x7, BT_8822B_1ANT_WLINK_MAX }; @@ -266,6 +267,7 @@ struct coex_sta_8822b_1ant { u32 high_priority_rx; u32 low_priority_tx; u32 low_priority_rx; + boolean bt_ctr_ok; boolean is_hi_pri_rx_overhead; s8 bt_rssi; u8 pre_bt_rssi_state; @@ -274,6 +276,8 @@ struct coex_sta_8822b_1ant { u32 bt_info_c2h_cnt[BT_8822B_1ANT_INFO_SRC_MAX]; boolean bt_whck_test; boolean c2h_bt_inquiry_page; + boolean bt_inq_page_pre; + boolean bt_inq_page_remain; boolean c2h_bt_remote_name_req; boolean c2h_bt_page; /* Add for win8.1 page out issue */ boolean wifi_high_pri_task1; @@ -351,6 +355,7 @@ struct coex_sta_8822b_1ant { u32 gnt_error_cnt; u8 bt_afh_map[10]; u8 bt_relink_downcount; + u8 bt_inq_page_downcount; boolean is_tdma_btautoslot; u8 switch_band_notify_to; @@ -406,6 +411,7 @@ struct coex_sta_8822b_1ant { u8 tdma_timer_base; boolean wl_slot_toggle; boolean wl_slot_toggle_change; /* if toggle to no-toggle */ + u8 wl_iot_peer; }; struct rfe_type_8822b_1ant { @@ -423,6 +429,7 @@ struct wifi_link_info_8822b_1ant { boolean is_mcc_25g; boolean is_p2p_connected; boolean is_connected; + boolean is_32k; }; /* ******************************************* diff --git a/hal/btc/halbtc8822b2ant.c b/hal/btc/halbtc8822b2ant.c index 89cd00e..2b20cfc 100644 --- a/hal/btc/halbtc8822b2ant.c +++ b/hal/btc/halbtc8822b2ant.c @@ -28,9 +28,9 @@ static const char *const glbt_info_src_8822b_2ant[] = { "BT Info[bt scbd]" }; -u32 glcoex_ver_date_8822b_2ant = 20191120; -u32 glcoex_ver_8822b_2ant = 0x77; -u32 glcoex_ver_btdesired_8822b_2ant = 0x75; +u32 glcoex_ver_date_8822b_2ant = 20200302; +u32 glcoex_ver_8822b_2ant = 0x7b; +u32 glcoex_ver_btdesired_8822b_2ant = 0x79; static u8 halbtc8822b2ant_bt_rssi_state(struct btc_coexist *btc, u8 *ppre_bt_rssi_state, u8 level_num, @@ -264,25 +264,22 @@ halbtc8822b2ant_ccklock_action(struct btc_coexist *btc) struct coex_sta_8822b_2ant *coex_sta = &btc->coex_sta_8822b_2ant; u8 h2c_parameter[2] = {0}; static u8 cnt; + boolean wifi_busy = FALSE; - if (coex_sta->tdma_timer_base == 3) { - if (!coex_sta->is_no_wl_5ms_extend) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], set h2c 0x69 opcode 12 to turn off 5ms WL slot extend!!\n"); - BTC_TRACE(trace_buf); + btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); - h2c_parameter[0] = 0xc; - h2c_parameter[1] = 0x1; - btc->btc_fill_h2c(btc, 0x69, 2, h2c_parameter); - coex_sta->is_no_wl_5ms_extend = TRUE; - cnt = 0; - } + if (!coex_sta->gl_wifi_busy || + coex_sta->wl_iot_peer == BTC_IOT_PEER_CISCO) { + cnt = 0; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi is not busy or CISCO AP, return!!\n"); + BTC_TRACE(trace_buf); return; } if (!coex_sta->is_no_wl_5ms_extend && coex_sta->force_lps_ctrl && !coex_sta->cck_lock_ever) { - if (coex_sta->wl_fw_dbg_info[7] <= 5) + if (coex_sta->wl_fw_dbg_info[7] <= 5 && wifi_busy) cnt++; else cnt = 0; @@ -319,14 +316,13 @@ halbtc8822b2ant_ccklock_detect(struct btc_coexist *btc) { struct coex_sta_8822b_2ant *coex_sta = &btc->coex_sta_8822b_2ant; struct coex_dm_8822b_2ant *coex_dm = &btc->coex_dm_8822b_2ant; - struct btc_wifi_link_info_ext *link_info_ext = &btc->wifi_link_info_ext; + struct wifi_link_info_8822b_2ant *link_info_ext = + &btc->wifi_link_info_8822b_2ant; boolean is_cck_lock_rate = FALSE; if (coex_dm->bt_status == BTC_BTSTATUS_INQ_PAGE || - coex_sta->is_setup_link) { - coex_sta->cck_lock = FALSE; - return; - } + coex_sta->is_setup_link) + return; if (coex_sta->wl_rx_rate <= BTC_CCK_2 || coex_sta->wl_rts_rx_rate <= BTC_CCK_2) @@ -408,10 +404,6 @@ halbtc8822b2ant_set_tdma_timer_base(struct btc_coexist *btc, u8 type) BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s() h2c_0x69 = 0x%x\n", __func__, h2c_para[1]); BTC_TRACE(trace_buf); - - /* no 5ms_wl_slot_extend for 4-slot mode */ - if (coex_sta->tdma_timer_base == 3) - halbtc8822b2ant_ccklock_action(btc); } static void halbtc8822b2ant_coex_switch_thres(struct btc_coexist *btc, @@ -615,14 +607,14 @@ static void halbtc8822b2ant_enable_gnt_to_gpio(struct btc_coexist *btc, } } -static void halbtc8822b2ant_monitor_bt_ctr(struct btc_coexist *btc) +static boolean halbtc8822b2ant_monitor_bt_ctr(struct btc_coexist *btc) { struct coex_sta_8822b_2ant *coex_sta = &btc->coex_sta_8822b_2ant; - u32 reg_hp_txrx, reg_lp_txrx, u32tmp; + struct coex_dm_8822b_2ant *coex_dm = &btc->coex_dm_8822b_2ant; + u32 reg_hp_txrx, reg_lp_txrx, u32tmp, cnt_bt_all; u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0; - static u8 num_of_bt_counter_chk, cnt_autoslot_hang; - - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; + static u32 cnt_bt_pre = 0; + boolean is_run_coex = FALSE; reg_hp_txrx = 0x770; reg_lp_txrx = 0x774; @@ -640,9 +632,21 @@ static void halbtc8822b2ant_monitor_bt_ctr(struct btc_coexist *btc) coex_sta->low_priority_tx = reg_lp_tx; coex_sta->low_priority_rx = reg_lp_rx; + if (coex_sta->under_lps || coex_sta->under_ips || + (coex_sta->high_priority_tx == 65535 && + coex_sta->high_priority_rx == 65535 && + coex_sta->low_priority_tx == 65535 && + coex_sta->low_priority_rx == 65535)) + coex_sta->bt_ctr_ok = FALSE; + else + coex_sta->bt_ctr_ok = TRUE; + /* reset counter */ btc->btc_write_1byte(btc, 0x76e, 0xc); + if (!coex_sta->bt_ctr_ok) + return FALSE; + if (coex_sta->low_priority_tx > 1050 && !coex_sta->c2h_bt_inquiry_page) coex_sta->pop_event_cnt++; @@ -654,6 +658,20 @@ static void halbtc8822b2ant_monitor_bt_ctr(struct btc_coexist *btc) else coex_sta->is_esco_mode = TRUE; } + + cnt_bt_all = coex_sta->high_priority_tx + + coex_sta->high_priority_rx + + coex_sta->low_priority_tx + + coex_sta->low_priority_rx; + + if ((cnt_bt_pre > (cnt_bt_all + 50) || + cnt_bt_all > (cnt_bt_pre + 50)) && + coex_dm->bt_status == BT_8822B_2ANT_BSTATUS_NCON_IDLE) + is_run_coex = TRUE; + + cnt_bt_pre = cnt_bt_all; + + return is_run_coex; } static void halbtc8822b2ant_monitor_wifi_ctr(struct btc_coexist *btc) @@ -666,7 +684,6 @@ static void halbtc8822b2ant_monitor_wifi_ctr(struct btc_coexist *btc) u32 cnt_cck; static u8 cnt_ccklocking; u8 h2c_parameter[1] = {0}; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; #if 0 /*send h2c to query WL FW dbg info */ @@ -1464,11 +1481,16 @@ halbtc8822b2ant_update_wifi_ch_info(struct btc_coexist *btc, u8 type) } } - coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; - coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; - coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; + /* Only send mailbox if ch info change */ + if (coex_dm->wifi_chnl_info[0] != h2c_parameter[0] && + coex_dm->wifi_chnl_info[1] != h2c_parameter[1] && + coex_dm->wifi_chnl_info[2] != h2c_parameter[2]) { - btc->btc_fill_h2c(btc, 0x66, 3, h2c_parameter); + coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; + coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; + coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; + btc->btc_fill_h2c(btc, 0x66, 3, h2c_parameter); + } BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], para[0:2] = 0x%x 0x%x 0x%x\n", h2c_parameter[0], @@ -1584,12 +1606,13 @@ static void halbtc8822b2ant_set_wl_rx_gain(struct btc_coexist *btc, for (i = 0; i < ARRAY_SIZE(rx_gain_value_en); i++) btc->btc_write_4byte(btc, 0x81c, rx_gain_value_en[i]); - +#if 0 /* set Rx filter corner RCK offset */ btc->btc_set_rf_reg(btc, BTC_RF_A, 0xde, 0x2, 0x1); btc->btc_set_rf_reg(btc, BTC_RF_A, 0x1d, 0x3f, 0x3f); btc->btc_set_rf_reg(btc, BTC_RF_B, 0xde, 0x2, 0x1); btc->btc_set_rf_reg(btc, BTC_RF_B, 0x1d, 0x3f, 0x3f); +#endif } else { BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], BB Agc Table Off!\n"); @@ -1597,12 +1620,13 @@ static void halbtc8822b2ant_set_wl_rx_gain(struct btc_coexist *btc, for (i = 0; i < ARRAY_SIZE(rx_gain_value_dis); i++) btc->btc_write_4byte(btc, 0x81c, rx_gain_value_dis[i]); - +#if 0 /* set Rx filter corner RCK offset */ btc->btc_set_rf_reg(btc, BTC_RF_A, 0x1d, 0x3f, 0x4); btc->btc_set_rf_reg(btc, BTC_RF_A, 0xde, 0x2, 0x0); btc->btc_set_rf_reg(btc, BTC_RF_B, 0x1d, 0x3f, 0x4); btc->btc_set_rf_reg(btc, BTC_RF_B, 0xde, 0x2, 0x0); +#endif } coex_dm->cur_agc_table_en = agc_table_en; @@ -1616,6 +1640,87 @@ static void halbtc8822b2ant_set_bt_rx_gain(struct btc_coexist *btc, halbtc8822b2ant_write_scbd(btc, BT_8822B_2ANT_SCBD_RXGAIN, rx_gain_en); } +static void +halbtc8822b2ant_set_rf_para(struct btc_coexist *btc, boolean force_exec, + u8 level) +{ + struct btc_coex_sta *coex_sta = &btc->coex_sta; + u8 tmp = 0; + u32 traffic_dir; + struct btc_rf_para rf_para; + /* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */ + struct btc_rf_para rf_para_tx_8822b[] = { + {0xc8, 0x00, FALSE, 1}, /* for normal */ + {0xc8, 0x00, FALSE, 1}, /* for WL-CPT */ + {0xc8, 0x00, TRUE, 1}, /* 2 for RCU SDR */ + {0xcc, 0xfa, TRUE, 1}, + {0xd0, 0xf7, TRUE, 1}, + {0xd4, 0xf3, TRUE, 1}, + {0xc8, 0x00, TRUE, 1}, /* 6 for RCU OFC */ + {0xcc, 0xfa, TRUE, 1}, + {0xd0, 0xf7, TRUE, 1}, + {0xd4, 0xf3, TRUE, 1}, + {0xc8, 0x00, TRUE, 1}, /* 10 for A2DP SDR */ + {0xcc, 0xfa, TRUE, 1}, + {0xd0, 0xf7, TRUE, 1}, + {0xd4, 0xf3, TRUE, 1}, + {0xc8, 0x00, TRUE, 1}, /* 14 for A2DP OFC */ + {0xcc, 0xfa, TRUE, 1}, + {0xd0, 0xf7, TRUE, 1}, + {0xd4, 0xf3, TRUE, 1}, + {0xc8, 0x00, TRUE, 1}, /* 18 for A2DP+RCU SDR */ + {0xcc, 0xfa, TRUE, 1}, + {0xd0, 0xf7, TRUE, 1}, + {0xd4, 0xf3, TRUE, 1}, + {0xc8, 0x00, TRUE, 1}, /* 22 for A2DP+RCU OFC */ + {0xcc, 0xfa, TRUE, 1}, + {0xd0, 0xf7, TRUE, 1}, + {0xd4, 0xf3, TRUE, 1} }; + + struct btc_rf_para rf_para_rx_8822b[] = { + {0xc8, 0x00, FALSE, 1}, /* for normal */ + {0xc8, 0x00, FALSE, 1}, /* for WL-CPT */ + {0xc8, 0x00, TRUE, 1}, /* 2 for RCU SDR */ + {0xcc, 0xfa, TRUE, 1}, + {0xd0, 0xf7, TRUE, 1}, + {0xd4, 0xf3, TRUE, 1}, + {0xc8, 0x00, TRUE, 1}, /* 6 for RCU OFC */ + {0xcc, 0xfa, TRUE, 1}, + {0xd0, 0xf7, TRUE, 1}, + {0xd4, 0xf3, TRUE, 1}, + {0xc8, 0x00, TRUE, 1}, /* 10 for A2DP SDR */ + {0xcc, 0xfa, TRUE, 1}, + {0xd0, 0xf7, TRUE, 1}, + {0xd4, 0xf3, TRUE, 1}, + {0xc8, 0x00, TRUE, 1}, /* 14 for A2DP OFC */ + {0xcc, 0xfa, TRUE, 1}, + {0xd0, 0xf7, TRUE, 1}, + {0xd4, 0xf3, TRUE, 1}, + {0xc8, 0x00, TRUE, 1}, /* 18 for A2DP+RCU SDR */ + {0xcc, 0xfa, TRUE, 1}, + {0xd0, 0xf7, TRUE, 1}, + {0xd4, 0xf3, TRUE, 1}, + {0xc8, 0x00, TRUE, 1}, /* 22 for A2DP+RCU OFC */ + {0xcc, 0xfa, TRUE, 1}, + {0xd0, 0xf7, TRUE, 1}, + {0xd4, 0xf3, TRUE, 1} }; + + btc->btc_get(btc, BTC_GET_U4_WIFI_TRAFFIC_DIR, &traffic_dir); + + if (level > ARRAY_SIZE(rf_para_tx_8822b)) + level = ARRAY_SIZE(rf_para_tx_8822b) - 1; + + if (traffic_dir == BTC_WIFI_TRAFFIC_TX) + rf_para = rf_para_tx_8822b[level]; + else + rf_para = rf_para_rx_8822b[level]; + + halbtc8822b2ant_set_wl_tx_power(btc, NM_EXCU, rf_para.wl_pwr_dec_lvl); + halbtc8822b2ant_set_bt_tx_power(btc, FC_EXCU, rf_para.bt_pwr_dec_lvl); + halbtc8822b2ant_set_wl_rx_gain(btc, NM_EXCU, rf_para.wl_low_gain_en); + halbtc8822b2ant_set_bt_rx_gain(btc, FC_EXCU, rf_para.bt_lna_lvl); +} + static u32 halbtc8822b2ant_wait_indirect_reg_ready(struct btc_coexist *btc) { @@ -2077,7 +2182,6 @@ static void halbtc8822b2ant_set_tdma(struct btc_coexist *btc, u8 byte1, u8 h2c_parameter[5] = {0}; u8 real_byte1 = byte1, real_byte5 = byte5; boolean ap_enable = FALSE, result = FALSE; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; u8 ps_type = BTC_PS_WIFI_NATIVE; if (byte5 & BIT(2)) @@ -2168,7 +2272,6 @@ halbtc8822b2ant_tdma(struct btc_coexist *btc, boolean force_exec, { struct coex_sta_8822b_2ant *coex_sta = &btc->coex_sta_8822b_2ant; struct coex_dm_8822b_2ant *coex_dm = &btc->coex_dm_8822b_2ant; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; u8 type; btc->btc_set_atomic(btc, &coex_dm->setting_tdma, TRUE); @@ -2176,12 +2279,12 @@ halbtc8822b2ant_tdma(struct btc_coexist *btc, boolean force_exec, /* tcase: bit0~7 --> tdma case index * bit8 --> for 4-slot (50ms) mode */ - if (tcase & TDMA_4SLOT)/* 4-slot (50ms) mode */ + if (tcase & TDMA_4SLOT)/* 4-slot (50ms) mode */ halbtc8822b2ant_set_tdma_timer_base(btc, 3); else halbtc8822b2ant_set_tdma_timer_base(btc, 0); - type = tcase & 0xff; + type = (u8)(tcase & 0xff); /* To avoid TDMA H2C fail before Last LPS enter */ if (!force_exec && coex_sta->coex_run_reason != BTC_RSN_LPS) { @@ -2204,7 +2307,12 @@ halbtc8822b2ant_tdma(struct btc_coexist *btc, boolean force_exec, type); BTC_TRACE(trace_buf); - halbtc8822b2ant_write_scbd(btc, BT_8822B_2ANT_SCBD_TDMA, TRUE); + if (coex_sta->a2dp_exist && coex_sta->bt_inq_page_remain) + halbtc8822b2ant_write_scbd(btc, BT_8822B_2ANT_SCBD_TDMA, + FALSE); + else + halbtc8822b2ant_write_scbd(btc, BT_8822B_2ANT_SCBD_TDMA, + TRUE); /* enable TBTT nterrupt */ btc->btc_write_1byte_bitmask(btc, 0x550, 0x8, 0x1); @@ -2841,13 +2949,15 @@ static u8 halbtc8822b2ant_action_algorithm(struct btc_coexist *btc) static void halbtc8822b2ant_action_freerun(struct btc_coexist *btc) { struct coex_sta_8822b_2ant *coex_sta = &btc->coex_sta_8822b_2ant; + struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; static u8 pre_wifi_rssi_state1 = BTC_RSSI_STATE_LOW, pre_wifi_rssi_state2 = BTC_RSSI_STATE_LOW, pre_wifi_rssi_state3 = BTC_RSSI_STATE_LOW; u8 wifi_rssi_state1, wifi_rssi_state2, wifi_rssi_state3; static u8 pre_bt_rssi_state = BTC_RSSI_STATE_LOW; u8 bt_rssi_state, lna_lvl = 1; - u8 bt_tx_offset = 0; + u8 bt_tx_offset = 0, level, base = 0; + u32 ap_cnt; BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], ************* freerunXXXX*************\n"); @@ -2882,34 +2992,35 @@ static void halbtc8822b2ant_action_freerun(struct btc_coexist *btc) halbtc8822b2ant_write_scbd(btc, BT_8822B_2ANT_SCBD_CQDDR, TRUE); - if (coex_sta->wl_noisy_level == 0) - bt_tx_offset = 3; - /* keep WL/BT Tx/Rx for non 2G-1port case */ if (coex_sta->wl_coex_mode != BT_8822B_2ANT_WLINK_2G1PORT) return; - /*avoid tdma off to write 0xc5b ,0xe5b */ - halbtc8822b2ant_set_bt_rx_gain(btc, FC_EXCU, TRUE); - halbtc8822b2ant_set_wl_rx_gain(btc, NM_EXCU, TRUE); + ap_cnt = coex_sta->scan_ap_num; + if (bt_link_info->hid_only) + base = 2; + else if (bt_link_info->a2dp_only) + base = 10; + else if (bt_link_info->hid_exist && bt_link_info->a2dp_exist) + base = 18; - if (BTC_RSSI_HIGH(wifi_rssi_state1)) { - halbtc8822b2ant_set_wl_tx_power(btc, NM_EXCU, 0xc8); - halbtc8822b2ant_set_bt_tx_power(btc, FC_EXCU, - 0x0 - bt_tx_offset); - } else if (BTC_RSSI_HIGH(wifi_rssi_state2)) { - halbtc8822b2ant_set_wl_tx_power(btc, NM_EXCU, 0xcc); - halbtc8822b2ant_set_bt_tx_power(btc, FC_EXCU, - 0xfa - bt_tx_offset); - } else if (BTC_RSSI_HIGH(wifi_rssi_state3)) { - halbtc8822b2ant_set_wl_tx_power(btc, NM_EXCU, 0xd0); - halbtc8822b2ant_set_bt_tx_power(btc, FC_EXCU, 0xf7 - - bt_tx_offset); - } else { - halbtc8822b2ant_set_wl_tx_power(btc, NM_EXCU, 0xd4); - halbtc8822b2ant_set_bt_tx_power(btc, FC_EXCU, 0xf3); - } + if (ap_cnt > 10) /* for office case */ + base = base + 4; + + /* decrease more BT Tx power for clear case */ + if (BTC_RSSI_HIGH(wifi_rssi_state1)) + level = 0; + else if (BTC_RSSI_HIGH(wifi_rssi_state2)) + level = 1; + else if (BTC_RSSI_HIGH(wifi_rssi_state3)) + level = 2; + else + level = 3; + + level = level + base; + + halbtc8822b2ant_set_rf_para(btc, NM_EXCU, level); } static void halbtc8822b2ant_action_coex_all_off(struct btc_coexist *btc) @@ -2943,7 +3054,6 @@ static void halbtc8822b2ant_action_bt_whql_test(struct btc_coexist *btc) static void halbtc8822b2ant_action_bt_relink(struct btc_coexist *btc) { struct coex_sta_8822b_2ant *coex_sta = &btc->coex_sta_8822b_2ant; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; halbtc8822b2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); halbtc8822b2ant_set_bt_tx_power(btc, NM_EXCU, 0); @@ -3354,7 +3464,6 @@ halbtc8822b2ant_action_wifi_native_lps(struct btc_coexist *btc) { struct wifi_link_info_8822b_2ant *wifi_link_info_ext = &btc->wifi_link_info_8822b_2ant; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; if (wifi_link_info_ext->is_all_under_5g) return; @@ -3430,7 +3539,14 @@ static void halbtc8822b2ant_action_wifi_connected(struct btc_coexist *btc) BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], Action 2-Ant, algorithm = HID.\n"); BTC_TRACE(trace_buf); - halbtc8822b2ant_action_hid(btc); + if (halbtc8822b2ant_freerun_check(btc)) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Action 2-Ant, algorithm = HID -> Freerun\n"); + BTC_TRACE(trace_buf); + halbtc8822b2ant_action_freerun(btc); + } else { + halbtc8822b2ant_action_hid(btc); + } break; case BT_8822B_2ANT_COEX_A2DP: if (halbtc8822b2ant_freerun_check(btc)) { @@ -3484,7 +3600,14 @@ static void halbtc8822b2ant_action_wifi_connected(struct btc_coexist *btc) BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], Action 2-Ant, algorithm = HID+A2DP.\n"); BTC_TRACE(trace_buf); - halbtc8822b2ant_action_hid_a2dp(btc); + if (halbtc8822b2ant_freerun_check(btc)) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Action 2-Ant, algorithm = HID -> Freerun\n"); + BTC_TRACE(trace_buf); + halbtc8822b2ant_action_freerun(btc); + } else { + halbtc8822b2ant_action_hid_a2dp(btc); + } break; default: BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, @@ -4470,12 +4593,13 @@ void ex_halbtc8822b2ant_display_coex_info(struct btc_coexist *btc) ps_tdma_case = coex_dm->cur_ps_tdma; CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %02x %02x %02x %02x %02x (case-%d, %s)", + "\r\n %-35s = %02x %02x %02x %02x %02x (case-%d, %s, Timer:%d)", "TDMA", coex_dm->ps_tdma_para[0], coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2], coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4], ps_tdma_case, - (coex_dm->cur_ps_tdma_on ? "TDMA-On" : "TDMA-Off")); + (coex_dm->cur_ps_tdma_on ? "On" : "Off"), + coex_sta->tdma_timer_base); CL_PRINTF(cli_buf); switch (coex_sta->wl_coex_mode) { @@ -4981,6 +5105,7 @@ void ex_halbtc8822b2ant_media_status_notify(struct btc_coexist *btc, u8 type) { struct coex_sta_8822b_2ant *coex_sta = &btc->coex_sta_8822b_2ant; boolean wifi_under_b_mode = FALSE; + u8 h2c_parameter[2] = {0}; if (btc->manual_control || btc->stop_coex_dm) return; @@ -5016,6 +5141,12 @@ void ex_halbtc8822b2ant_media_status_notify(struct btc_coexist *btc, u8 type) else btc->btc_write_1byte_bitmask(btc, 0x6cf, BIT(4), 0x1); + /*Leak-AP protection will reopen when connecting AP*/ + h2c_parameter[0] = 0xc; + h2c_parameter[1] = 0x0; + btc->btc_fill_h2c(btc, 0x69, 2, h2c_parameter); + coex_sta->is_no_wl_5ms_extend = FALSE; + halbtc8822b2ant_run_coex(btc, BT_8822B_2ANT_RSN_2GMEDIA); } else { BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, @@ -5030,7 +5161,7 @@ void ex_halbtc8822b2ant_media_status_notify(struct btc_coexist *btc, u8 type) halbtc8822b2ant_run_coex(btc, BT_8822B_2ANT_RSN_MEDIADISCON); } - + btc->btc_get(btc, BTC_GET_U1_IOT_PEER, &coex_sta->wl_iot_peer); halbtc8822b2ant_update_wifi_ch_info(btc, type); } @@ -5193,6 +5324,14 @@ void ex_halbtc8822b2ant_bt_info_notify(struct btc_coexist *btc, u8 *tmp_buf, coex_sta->c2h_bt_inquiry_page = ((coex_sta->bt_info_lb2 & BIT(2)) ? TRUE : FALSE); + if (coex_sta->bt_inq_page_pre != coex_sta->c2h_bt_inquiry_page) { + coex_sta->bt_inq_page_pre = coex_sta->c2h_bt_inquiry_page; + coex_sta->bt_inq_page_remain = TRUE; + + if (!coex_sta->c2h_bt_inquiry_page) + coex_sta->bt_inq_page_downcount = 2; + } + if ((coex_sta->bt_info_lb2 & 0x49) == 0x49) coex_sta->a2dp_bit_pool = (coex_sta->bt_info_hb3 & 0x7f); else @@ -5216,6 +5355,7 @@ void ex_halbtc8822b2ant_bt_info_notify(struct btc_coexist *btc, u8 *tmp_buf, if (coex_sta->hid_pair_cnt > 0 && coex_sta->hid_busy_num >= 2) { coex_sta->bt_418_hid_exist = TRUE; } else if (coex_sta->hid_busy_num == 1 && + coex_sta->bt_ctr_ok && (coex_sta->high_priority_rx + 100 < coex_sta->high_priority_tx) && coex_sta->high_priority_rx < 100) { @@ -5520,7 +5660,8 @@ void ex_halbtc8822b2ant_pnp_notify(struct btc_coexist *btc, u8 pnp_state) void ex_halbtc8822b2ant_periodical(struct btc_coexist *btc) { struct coex_sta_8822b_2ant *coex_sta = &btc->coex_sta_8822b_2ant; - boolean bt_relink_finish = FALSE, is_defreeze = FALSE; + boolean bt_relink_finish = FALSE, is_defreeze = FALSE, + bt_ctr_change = FALSE; static u8 freeze_cnt; BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, @@ -5530,7 +5671,7 @@ void ex_halbtc8822b2ant_periodical(struct btc_coexist *btc) if (!btc->auto_report) halbtc8822b2ant_query_bt_info(btc); - halbtc8822b2ant_monitor_bt_ctr(btc); + bt_ctr_change = halbtc8822b2ant_monitor_bt_ctr(btc); halbtc8822b2ant_monitor_wifi_ctr(btc); halbtc8822b2ant_update_wifi_link_info(btc, BT_8822B_2ANT_RSN_PERIODICAL); @@ -5544,6 +5685,12 @@ void ex_halbtc8822b2ant_periodical(struct btc_coexist *btc) } } + if (coex_sta->bt_inq_page_downcount != 0) { + coex_sta->bt_inq_page_downcount--; + if (coex_sta->bt_relink_downcount == 0) + coex_sta->bt_inq_page_remain = FALSE; + } + if (coex_sta->freeze_coexrun_by_btinfo) { freeze_cnt++; @@ -5589,7 +5736,7 @@ void ex_halbtc8822b2ant_periodical(struct btc_coexist *btc) } if (halbtc8822b2ant_moniter_wifibt_status(btc) || bt_relink_finish || - coex_sta->is_set_ps_state_fail || is_defreeze) + coex_sta->is_set_ps_state_fail || is_defreeze || bt_ctr_change) halbtc8822b2ant_run_coex(btc, BT_8822B_2ANT_RSN_PERIODICAL); } diff --git a/hal/btc/halbtc8822b2ant.h b/hal/btc/halbtc8822b2ant.h index e6a34e0..6b62c1e 100644 --- a/hal/btc/halbtc8822b2ant.h +++ b/hal/btc/halbtc8822b2ant.h @@ -273,6 +273,7 @@ struct coex_sta_8822b_2ant { u32 high_priority_rx; u32 low_priority_tx; u32 low_priority_rx; + boolean bt_ctr_ok; boolean is_hi_pri_rx_overhead; u8 bt_rssi; u8 pre_bt_rssi_state; @@ -281,6 +282,8 @@ struct coex_sta_8822b_2ant { u32 bt_info_c2h_cnt[BT_8822B_2ANT_INFO_SRC_MAX]; boolean bt_whck_test; boolean c2h_bt_inquiry_page; + boolean bt_inq_page_pre; + boolean bt_inq_page_remain; boolean c2h_bt_remote_name_req; u8 bt_info_lb2; @@ -365,6 +368,7 @@ struct coex_sta_8822b_2ant { u8 bt_afh_map[10]; u8 bt_relink_downcount; + u8 bt_inq_page_downcount; boolean is_tdma_btautoslot; boolean is_esco_mode; @@ -421,6 +425,7 @@ struct coex_sta_8822b_2ant { u8 tdma_timer_base; boolean wl_slot_toggle; boolean wl_slot_toggle_change; /* if toggle to no-toggle */ + u8 wl_iot_peer; }; #define BT_8822B_2ANT_EXT_BAND_SWITCH_USE_DPDT 0 diff --git a/hal/btc/halbtcoutsrc.h b/hal/btc/halbtcoutsrc.h index 859e98e..a420ec2 100644 --- a/hal/btc/halbtcoutsrc.h +++ b/hal/btc/halbtcoutsrc.h @@ -174,6 +174,37 @@ do {\ #define BTC_ANT_WIFI_AT_CPL_MAIN 0 #define BTC_ANT_WIFI_AT_CPL_AUX 1 +/* for common code request */ +#define REG_LTE_IDR_COEX_CTRL 0x0038 +#define REG_SYS_SDIO_CTRL 0x0070 +#define REG_SYS_SDIO_CTRL3 0x0073 +/* #define REG_RETRY_LIMIT 0x042a */ +/* #define REG_DARFRC 0x0430 */ +#define REG_DARFRCH 0x0434 +#define REG_CCK_CHECK 0x0454 +#define REG_AMPDU_MAX_TIME_V1 0x0455 +#define REG_TX_HANG_CTRL 0x045E +#define REG_LIFETIME_EN 0x0426 +#define REG_BT_COEX_TABLE0 0x06C0 +#define REG_BT_COEX_TABLE1 0x06C4 +#define REG_BT_COEX_BRK_TABLE 0x06C8 +#define REG_BT_COEX_TABLE_H 0x06CC +#define REG_BT_ACT_STATISTICS 0x0770 +#define REG_BT_ACT_STATISTICS_1 0x0774 +#define REG_BT_STAT_CTRL 0x0778 + +#define BIT_EN_GNT_BT_AWAKE BIT(3) +#define BIT_EN_BCN_FUNCTION BIT(3) +#define BIT_EN_BCN_PKT_REL BIT(6) +#define BIT_FEN_BB_GLB_RST BIT(1) +#define BIT_FEN_BB_RSTB BIT(0) + +#define TDMA_4SLOT BIT(8) + +/* for 2T2R -> 2T1R coex MIMO-PS mechanism tranlation */ +#define BTC_2GTDD_MAX_TRY 3 /* the max retry count for 1R->2R */ +#define BTC_2GFDD_MAX_STAY 300 /* the max stay time at 1R if 2R try-able (unit: 2s) */ + typedef enum _BTC_POWERSAVE_TYPE { BTC_PS_WIFI_NATIVE = 0, /* wifi original power save behavior */ BTC_PS_LPS_ON = 1, @@ -212,6 +243,7 @@ typedef enum _BTC_CHIP_TYPE { BTC_CHIP_RTL8723D = 10, BTC_CHIP_RTL8703B = 11, BTC_CHIP_RTL8725A = 12, + BTC_CHIP_RTL8723F = 13, BTC_CHIP_MAX } BTC_CHIP_TYPE, *PBTC_CHIP_TYPE; @@ -233,15 +265,14 @@ static const char *const glbt_info_src[] = { "BT Info[bt auto report]", }; -#define TDMA_4SLOT BIT(8) -#define BTC_INFO_FTP BIT(7) -#define BTC_INFO_A2DP BIT(6) -#define BTC_INFO_HID BIT(5) +#define BTC_INFO_FTP BIT(7) +#define BTC_INFO_A2DP BIT(6) +#define BTC_INFO_HID BIT(5) #define BTC_INFO_SCO_BUSY BIT(4) #define BTC_INFO_ACL_BUSY BIT(3) #define BTC_INFO_INQ_PAGE BIT(2) #define BTC_INFO_SCO_ESCO BIT(1) -#define BTC_INFO_CONNECTION BIT(0) +#define BTC_INFO_CONNECTION BIT(0) #define BTC_BTINFO_LENGTH_MAX 10 @@ -253,9 +284,9 @@ enum btc_gnt_setup_state { }; enum btc_gnt_setup_state_2 { - BTC_GNT_SW_LOW = 0x0, - BTC_GNT_SW_HIGH = 0x1, - BTC_GNT_HW_PTA = 0x2, + BTC_GNT_HW_PTA = 0x0, + BTC_GNT_SW_LOW = 0x1, + BTC_GNT_SW_HIGH = 0x3, BTC_GNT_MAX }; @@ -379,6 +410,7 @@ enum btc_ext_ant_switch_type { BTC_SWITCH_NONE = 0x0, BTC_SWITCH_SPDT = 0x1, BTC_SWITCH_SP3T = 0x2, + BTC_SWITCH_DPDT = 0x3, BTC_SWITCH_ANTMAX }; @@ -428,13 +460,19 @@ enum btc_wl2bt_scoreboard { BTC_SCBD_EXTFEM = BIT(8), BTC_SCBD_TDMA = BIT(9), BTC_SCBD_FIX2M = BIT(10), - BTC_SCBD_ALL = 0xffff + BTC_SCBD_MAILBOX_DBG = BIT(14), + BTC_SCBD_ALL = 0xffff, + BTC_SCBD_ALL_32BIT = 0xffffffff }; enum btc_bt2wl_scoreboard { BTC_SCBD_BT_ONOFF = BIT(1), BTC_SCBD_BT_LPS = BIT(7) }; +enum btc_scoreboard_bit_num { + BTC_SCBD_16_BIT = BIT(0), + BTC_SCBD_32_BIT = BIT(1) +}; enum btc_runreason { BTC_RSN_2GSCANSTART = 0x0, @@ -457,6 +495,8 @@ enum btc_runreason { BTC_RSN_LPS = 0x11, BTC_RSN_TIMERUP = 0x12, BTC_RSN_WLSTATUS = 0x13, + BTC_RSN_BTCNT = 0x14, + BTC_RSN_RFK = 0x15, BTC_RSN_MAX }; @@ -481,6 +521,9 @@ static const char *const run_reason_string[] = { "LPSNotify", "TimerUp", "WL_STATUS_CHANGE", + "BT_CNT_CHANGE", + "WL_RFK", + "Reason Max" }; enum btc_wl_link_mode { @@ -491,6 +534,7 @@ enum btc_wl_link_mode { BTC_WLINK_2GGO = 0x4, BTC_WLINK_2GGC = 0x5, BTC_WLINK_BTMR = 0x6, + BTC_WLINK_2GFREE = 0x7, BTC_WLINK_MAX }; @@ -501,7 +545,9 @@ static const char *const coex_mode_string[] = { "5G", "2G-P2P-GO", "2G-P2P-GC", - "BT-MR" + "BT-MR", + "2G1RFREE", + "unknow" }; enum btc_bt_state_cnt { @@ -518,6 +564,7 @@ enum btc_bt_state_cnt { BTC_CNT_BT_INFOUPDATE = 0xa, BTC_CNT_BT_IQK = 0xb, BTC_CNT_BT_IQKFAIL = 0xc, + BTC_CNT_BT_TRX = 0xd, BTC_CNT_BT_MAX }; @@ -534,8 +581,10 @@ enum btc_wl_state_cnt { BTC_CNT_WL_NOISY1 = 0x9, BTC_CNT_WL_NOISY2 = 0xa, BTC_CNT_WL_ACTIVEPORT = 0xb, - BTC_CNT_WL_5MS_NOEXTEND = 0xc, + BTC_CNT_WL_LEAKAP_NORX = 0xc, BTC_CNT_WL_FW_NOTIFY = 0xd, + BTC_CNT_WL_2G_TDDTRY = 0xe, + BTC_CNT_WL_2G_FDDSTAY = 0xf, BTC_CNT_WL_MAX }; @@ -562,6 +611,8 @@ enum btc_timer_cnt { BTC_TIMER_BT_RELINK = 0x7, BTC_TIMER_BT_REENABLE = 0x8, BTC_TIMER_BT_MULTILINK = 0x9, + BTC_TIMER_BT_INQPAGE = 0xa, + BTC_TIMER_BT_A2DP_ACT = 0xb, BTC_TIMER_MAX }; @@ -572,6 +623,8 @@ enum btc_wl_status_change { BTC_WLSTATUS_CHANGE_LINKINFO = 0x3, BTC_WLSTATUS_CHANGE_DIR = 0x4, BTC_WLSTATUS_CHANGE_NOISY = 0x5, + BTC_WLSTATUS_CHANGE_BTCNT = 0x6, + BTC_WLSTATUS_CHANGE_LOCKTRY = 0x7, BTC_WLSTATUS_CHANGE_MAX }; @@ -585,6 +638,7 @@ enum btc_commom_chip_setup { BTC_CSETUP_WL_TX_POWER = 0x6, BTC_CSETUP_WL_RX_GAIN = 0x7, BTC_CSETUP_WLAN_ACT_IPS = 0x8, + BTC_CSETUP_BT_CTRL_ACT = 0x9, BTC_CSETUP_MAX }; @@ -618,6 +672,33 @@ enum btc_wl_priority_mask { BTC_WLPRI_MAX }; +enum btc_ext_chip_id{ + BTC_EXT_CHIP_NONE, + BTC_EXT_CHIP_RF4CE, + BTC_EXT_CHIP_MAX +}; + +enum btc_ext_chip_mode{ + BTC_EXTMODE_NORMAL, + BTC_EXTMODE_VOICE, + BTC_EXTMODE_MAX +}; + +enum btc_wl_rfk_type { + BTC_PWR_TRK = 0, + BTC_IQK = 1, + BTC_LCK = 2, + BTC_DPK = 3, + BTC_TXGAPK = 4, + BTC_RFK_TYPE_MAX +}; + +enum btc_wl_rfk_state { + BTC_RFK_START = 0, + BTC_RFK_END = 1, + BTC_RFK_STATE_MAX +}; + struct btc_board_info { /* The following is some board information */ u8 bt_chip_type; @@ -639,6 +720,7 @@ struct btc_board_info { u8 customerID; u8 customer_id; u8 ant_distance; /* WL-BT antenna space for non-shared antenna */ + u8 ext_chip_id; }; struct btc_coex_dm { @@ -661,10 +743,6 @@ struct btc_coex_dm { u8 bt_status; u8 wl_chnl_info[3]; u8 cur_toggle_para[6]; - u8 cur_val0x6cc; - u32 cur_val0x6c0; - u32 cur_val0x6c4; - u32 cur_val0x6c8; u32 cur_ant_pos_type; u32 cur_switch_status; u32 setting_tdma; @@ -673,15 +751,17 @@ struct btc_coex_dm { struct btc_coex_sta { boolean coex_freeze; boolean coex_freerun; - boolean tdma_bt_autoslot; boolean rf4ce_en; - boolean is_no_wl_5ms_extend; + boolean force_freerun; + boolean force_tdd; boolean bt_disabled; boolean bt_disabled_pre; boolean bt_link_exist; boolean bt_whck_test; boolean bt_inq_page; + boolean bt_inq_page_pre; + boolean bt_inq_page_remain; boolean bt_inq; boolean bt_page; boolean bt_ble_voice; @@ -703,11 +783,14 @@ struct btc_coex_sta { boolean bt_ble_scan_en; boolean bt_slave; boolean bt_a2dp_active; + boolean bt_a2dp_active_pre; + boolean bt_a2dp_active_remain; boolean bt_slave_latency; boolean bt_init_scan; boolean bt_418_hid_exist; boolean bt_ble_hid_exist; boolean bt_mesh; + boolean bt_ctr_ok; boolean wl_under_lps; boolean wl_under_ips; @@ -723,7 +806,6 @@ struct btc_coex_sta { boolean wl_gl_busy_pre; boolean wl_linkscan_proc; boolean wl_mimo_ps; - boolean wl_ps_state_fail; boolean wl_cck_dead_lock_ap; boolean wl_tx_limit_en; boolean wl_ampdu_limit_en; @@ -732,6 +814,9 @@ struct btc_coex_sta { boolean wl_pnp_wakeup; boolean wl_slot_toggle; boolean wl_slot_toggle_change; /* if toggle to no-toggle */ + boolean wl_leak_ap; /* !is_no_wl_5ms_extend */ + boolean wl_blacklist_ap; + boolean wl_rfk; u8 coex_table_type; u8 coex_run_reason; @@ -759,6 +844,7 @@ struct btc_coex_sta { u8 bt_sut_pwr_lvl[4]; u8 bt_golden_rx_shift[4]; u8 bt_ext_autoslot_thres; + u8 ext_chip_mode; u8 wl_pnp_state_pre; u8 wl_noisy_level; @@ -773,18 +859,23 @@ struct btc_coex_sta { u8 wl_coex_mode; u8 wl_iot_peer; u8 wl_ra_thres; - u8 wl_ampdulen_backup; + u8 wl_ampdulen; u8 wl_rxagg_size; u8 wl_toggle_para[6]; + u8 wl_toggle_interval; u16 score_board_BW; - u16 score_board_WB; + u32 score_board_WB; u16 bt_reg_vendor_ac; u16 bt_reg_vendor_ae; + u32 bt_reg_vendor_dac; u16 bt_reg_modem_a; u16 bt_reg_rf_2; - u16 wl_txlimit_backup; + u16 bt_reg_rf_9; + u16 wl_txlimit; + u32 score_board_BW_32bit; + u32 score_board_WB_32bit; u32 hi_pri_tx; u32 hi_pri_rx; u32 lo_pri_tx; @@ -793,8 +884,9 @@ struct btc_coex_sta { u32 bt_supported_version; u32 bt_ble_scan_para[3]; u32 bt_a2dp_device_name; - u32 wl_arfb1_backup; - u32 wl_arfb2_backup; + u32 bt_a2dp_flush_time; + u32 wl_arfb1; + u32 wl_arfb2; u32 wl_traffic_dir; u32 wl_bw; u32 cnt_bt_info_c2h[BTC_BTINFO_SRC_MAX]; @@ -1031,6 +1123,7 @@ typedef enum _BTC_GET_TYPE { BTC_GET_U1_AP_NUM, BTC_GET_U1_ANT_TYPE, BTC_GET_U1_IOT_PEER, + BTC_GET_BL_WIFI_BSSID, /* type u2Byte */ BTC_GET_U2_BEACON_PERIOD, @@ -1151,6 +1244,13 @@ typedef enum _BTC_NOTIFY_TYPE_STACK_OPERATION { BTC_STACK_OP_MAX } BTC_NOTIFY_TYPE_STACK_OPERATION, *PBTC_NOTIFY_TYPE_STACK_OPERATION; +typedef enum _BTC_LINK_CHANGE_TYPE{ + BTC_LINK_CHANGE_TYPE_NONE = 0x0, + BTC_LINK_CHANGE_TYPE_ECSA_START = 0x1, + BTC_LINK_CHANGE_TYPE_ECSA_DONE = 0x2, + BTC_LINK_CHANGE_TYPE_MAX +}BTC_LINK_CHANGE_TYPE,*PBTC_LINK_CHANGE_TYPE; + /* Bryant Add */ typedef enum _BTC_ANTENNA_POS { BTC_ANTENNA_AT_MAIN_PORT = 0x1, @@ -1385,11 +1485,16 @@ typedef u4Byte IN PVOID pBtcContext, IN u2Byte reg_addr ); -typedef VOID +typedef u2Byte (*BFP_BTC_R_SCBD)( IN PVOID pBtcContext, IN pu2Byte score_board_val ); +typedef u4Byte +(*BFP_BTC_R_SCBD_32BIT)( + IN PVOID pBtcContext, + IN pu4Byte score_board_val + ); typedef VOID (*BFP_BTC_W_SCBD)( IN PVOID pBtcContext, @@ -1397,6 +1502,12 @@ typedef VOID IN BOOLEAN state ); typedef VOID +(*BFP_BTC_W_SCBD_32BIT)( + IN PVOID pBtcContext, + IN u4Byte bitpos, + IN BOOLEAN state + ); +typedef VOID (*BFP_BTC_W_LINDIRECT)( IN PVOID pBtcContext, IN u2Byte reg_addr, @@ -1675,6 +1786,8 @@ struct btc_coexist { struct btc_coex_sta coex_sta; struct btc_rfe_type rfe_type; const struct btc_chip_para *chip_para; + u8 wifi_black_bssid[6]; + u8 wifi_bssid[6]; #ifdef CONFIG_RF4CE_COEXIST struct btc_rf4ce_info rf4ce_info; @@ -1707,7 +1820,10 @@ struct btc_coexist { BFP_BTC_R_LINDIRECT btc_read_linderct; BFP_BTC_W_LINDIRECT btc_write_linderct; BFP_BTC_R_SCBD btc_read_scbd; + BFP_BTC_R_SCBD_32BIT btc_read_scbd_32bit; BFP_BTC_W_SCBD btc_write_scbd; + BFP_BTC_W_SCBD_32BIT btc_write_scbd_32bit; + /* read/write bb related */ BFP_BTC_SET_BB_REG btc_set_bb_reg; BFP_BTC_GET_BB_REG btc_get_bb_reg; @@ -1813,7 +1929,10 @@ struct btc_chip_para { u32 para_ver_date; u32 para_ver; u32 bt_desired_ver; + u32 wl_desired_ver; boolean scbd_support; + u32 scbd_reg; + u8 scbd_bit_num; boolean mailbox_support; boolean lte_indirect_access; boolean new_scbd10_def; /* TRUE: 1:fix 2M(8822c) */ @@ -1957,6 +2076,13 @@ EXhalbtcoutsrc_WLStatusChangeNotify( IN u4Byte change_type ); VOID +EXhalbtcoutsrc_WL_RFK_Notify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte path, + IN u1Byte type, + IN u1Byte state + ); +VOID EXhalbtcoutsrc_CoexDmSwitch( IN PBTC_COEXIST pBtCoexist ); diff --git a/hal/btc/mp_precomp.h b/hal/btc/mp_precomp.h index 2625936..4264549 100644 --- a/hal/btc/mp_precomp.h +++ b/hal/btc/mp_precomp.h @@ -124,6 +124,11 @@ struct btc_coexist; #include "halbtc8822c.h" #endif +#ifdef CONFIG_RTL8723F +#include "halbtc8723fwifionly.h" +#include "halbtc8723f.h" +#endif + #ifdef CONFIG_RTL8192F #include "halbtc8192f.h" #endif @@ -150,6 +155,10 @@ struct btc_coexist; #include "halbtc8822cwifionly.h" #endif +#ifdef CONFIG_RTL8723F +#include "halbtc8723fwifionly.h" +#endif + #ifdef CONFIG_RTL8814B #include "halbtc8814bwifionly.h" #endif diff --git a/hal/efuse/efuse_mask.h b/hal/efuse/efuse_mask.h index 139a1ef..dc4fdce 100644 --- a/hal/efuse/efuse_mask.h +++ b/hal/efuse/efuse_mask.h @@ -76,6 +76,10 @@ #if defined(CONFIG_RTL8814B) #include "rtl8814b/HalEfuseMask8814B_USB.h" #endif + + #if defined(CONFIG_RTL8723F) + #include "rtl8723f/HalEfuseMask8723F_USB.h" + #endif #endif /*CONFIG_USB_HCI*/ #ifdef CONFIG_PCI_HCI @@ -178,4 +182,7 @@ #include "rtl8822c/HalEfuseMask8822C_SDIO.h" #endif + #if defined(CONFIG_RTL8723F) + #include "rtl8723f/HalEfuseMask8723F_SDIO.h" + #endif #endif /*CONFIG_SDIO_HCI*/ diff --git a/hal/hal_btcoex.c b/hal/hal_btcoex.c index e8114f1..32ef8ec 100644 --- a/hal/hal_btcoex.c +++ b/hal/hal_btcoex.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2013 - 2017 Realtek Corporation. + * Copyright(c) 2013 - 2019 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -172,6 +172,7 @@ typedef enum _bt_op_code { BT_LO_OP_GET_AFH_MAP_M = 0x1f, BT_LO_OP_GET_AFH_MAP_H = 0x20, + BT_OP_SET_BT_TRX_MASK = 0x29, BT_OP_GET_BT_COEX_SUPPORTED_FEATURE = 0x2a, BT_OP_GET_BT_COEX_SUPPORTED_VERSION = 0x2b, BT_OP_GET_BT_ANT_DET_VAL = 0x2c, @@ -533,7 +534,7 @@ u8 halbtcoutsrc_IsWifiBusy(PADAPTER padapter) { if (rtw_mi_check_status(padapter, MI_AP_ASSOC)) return _TRUE; - if (rtw_mi_busy_traffic_check(padapter, _FALSE)) + if (rtw_mi_busy_traffic_check(padapter)) return _TRUE; return _FALSE; @@ -721,6 +722,34 @@ struct btc_wifi_link_info halbtcoutsrc_getwifilinkinfo(PBTC_COEXIST pBtCoexist) wifi_link_info.link_mode = BTC_LINK_25G_MCC_GC_STA; } } + + if (sta_iface && ap_iface) { + u8 band_sta = sta_iface->mlmeextpriv.cur_channel > 14 ? BAND_ON_5G : BAND_ON_2_4G; + u8 band_ap = ap_iface->mlmeextpriv.cur_channel > 14 ? BAND_ON_5G : BAND_ON_2_4G; + + if (band_sta == band_ap) { + switch (band_sta) { + case BAND_ON_2_4G: + #ifdef CONFIG_MCC_MODE + wifi_link_info.link_mode = + mcc_en == _TRUE ? BTC_LINK_2G_MCC_GO_STA : BTC_LINK_2G_SCC_GO_STA; + #else /* !CONFIG_MCC_MODE */ + wifi_link_info.link_mode = BTC_LINK_2G_SCC_GO_STA; + #endif /* CONFIG_MCC_MODE */ + break; + case BAND_ON_5G: + #ifdef CONFIG_MCC_MODE + wifi_link_info.link_mode = + mcc_en == _TRUE ? BTC_LINK_5G_MCC_GO_STA : BTC_LINK_5G_SCC_GO_STA; + #else /* !CONFIG_MCC_MODE */ + wifi_link_info.link_mode = BTC_LINK_5G_SCC_GO_STA; + #endif /* CONFIG_MCC_MODE */ + break; + } + } else { + wifi_link_info.link_mode = BTC_LINK_25G_MCC_GO_STA; + } + } } else { if (pBtCoexist->board_info.btdm_ant_num == 1) RTW_ERR("%s do not support n_assoc_iface > 2 (ant_num == 1)", __func__); @@ -782,7 +811,7 @@ static u8 _btmpoper_cmd(PBTC_COEXIST pBtCoexist, u8 opcode, u8 opcodever, u8 *cm /* GLBtcBtMpRptWait should be _FALSE here*/ if (GLBtcBtMpRptWiFiOK == _FALSE) { - RTW_ERR("%s: Didn't get H2C Rsp Event!\n", __FUNCTION__); + RTW_DBG("%s: Didn't get H2C Rsp Event!\n", __FUNCTION__); ret = BT_STATUS_H2C_TIMTOUT; goto exit; } @@ -1059,6 +1088,11 @@ u32 halbtcoutsrc_GetPhydmVersion(void *pBtcContext) #ifdef CONFIG_RTL8814B return RELEASE_VERSION_8814B; #endif + +#ifdef CONFIG_RTL8723F + return RELEASE_VERSION_8723F; +#endif + } u8 halbtcoutsrc_Get(void *pBtcContext, u8 getType, void *pOutBuf) @@ -1123,10 +1157,10 @@ u8 halbtcoutsrc_Get(void *pBtcContext, u8 getType, void *pOutBuf) case BTC_GET_BL_WIFI_SCAN: #if 0 - *pu8 = (rtw_mi_check_fwstate(padapter, WIFI_SITE_MONITOR)) ? _TRUE : _FALSE; + *pu8 = (rtw_mi_check_fwstate(padapter, WIFI_UNDER_SURVEY)) ? _TRUE : _FALSE; #else /* Use the value of the new variable GLBtcWiFiInScanState to judge whether WiFi is in scan state or not, since the originally used flag - WIFI_SITE_MONITOR in fwstate may not be cleared in time */ + WIFI_UNDER_SURVEY in fwstate may not be cleared in time */ *pu8 = GLBtcWiFiInScanState; #endif break; @@ -1143,6 +1177,10 @@ u8 halbtcoutsrc_Get(void *pBtcContext, u8 getType, void *pOutBuf) *pu8 = _FALSE; break; + case BTC_GET_BL_WIFI_BSSID: + _rtw_memcpy(pu8, get_bssid(&padapter->mlmepriv), ETH_ALEN); + break; + case BTC_GET_BL_WIFI_UNDER_5G: *pu8 = (pHalData->current_band_type == BAND_ON_5G) ? _TRUE : _FALSE; break; @@ -1996,7 +2034,7 @@ void halbtcoutsrc_DisplayWifiStatus(PBTC_COEXIST pBtCoexist) pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Link/ Roam/ Scan", bLink, bRoam, bScan); - CL_PRINTF(cliBuf); + CL_PRINTF(cliBuf); pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_IQK_TOTAL, &iqk_cnt_total); pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_IQK_OK, &iqk_cnt_ok); @@ -2005,9 +2043,9 @@ void halbtcoutsrc_DisplayWifiStatus(PBTC_COEXIST pBtCoexist) "IQK All/ OK/ Fail/AutoLoad/FWDL", iqk_cnt_total, iqk_cnt_ok, iqk_cnt_fail, ((halbtcoutsrc_is_autoload_fail(pBtCoexist) == _TRUE) ? "fail":"ok"), ((halbtcoutsrc_is_fw_ready(pBtCoexist) == _TRUE) ? "ok":"fail")); CL_PRINTF(cliBuf); - + if (wifiLinkStatus & WIFI_STA_CONNECTED) { - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "IOT Peer", GLBtcIotPeerString[padapter->mlmeextpriv.mlmext_info.assoc_AP_vendor]); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ "MAC_FMT"", "IOT Peer/BSSID", GLBtcIotPeerString[padapter->mlmeextpriv.mlmext_info.assoc_AP_vendor], MAC_ARG(get_bssid(&padapter->mlmepriv))); CL_PRINTF(cliBuf); } @@ -2291,17 +2329,36 @@ void halbtcoutsrc_WriteLIndirectReg(void *pBtcContext, u16 reg_addr, u32 bit_mas } } -void halbtcoutsrc_Read_scbd(void *pBtcContext, u16* score_board_val) +u16 halbtcoutsrc_Read_scbd(void *pBtcContext, u16* score_board_val) { PBTC_COEXIST btc = (PBTC_COEXIST)pBtcContext; struct btc_coex_sta *coex_sta = &btc->coex_sta; const struct btc_chip_para *chip_para = btc->chip_para; if (!chip_para->scbd_support) - return; + return 0; - *score_board_val = (btc->btc_read_2byte(btc, 0xaa)) & 0x7fff; + *score_board_val = (btc->btc_read_2byte(btc, chip_para->scbd_reg)) + & 0x7fff; coex_sta->score_board_BW = *score_board_val; + + return coex_sta->score_board_BW; +} + +u32 halbtcoutsrc_Read_scbd_32bit(void *pBtcContext, u32* score_board_val) +{ + PBTC_COEXIST btc = (PBTC_COEXIST)pBtcContext; + struct btc_coex_sta *coex_sta = &btc->coex_sta; + const struct btc_chip_para *chip_para = btc->chip_para; + + if (!chip_para->scbd_support) + return 0; + + *score_board_val = (btc->btc_read_4byte(btc, chip_para->scbd_reg)) + & 0x7fffffff; + coex_sta->score_board_BW_32bit = *score_board_val; + + return coex_sta->score_board_BW_32bit; } void halbtcoutsrc_Write_scbd(void *pBtcContext, u16 bitpos, u8 state) @@ -2310,7 +2367,6 @@ void halbtcoutsrc_Write_scbd(void *pBtcContext, u16 bitpos, u8 state) struct btc_coex_sta *coex_sta = &btc->coex_sta; const struct btc_chip_para *chip_para = btc->chip_para; u16 val = 0x2; - u8* btc_dbg_buf = &gl_btc_trace_buf[0]; if (!chip_para->scbd_support) return; @@ -2335,16 +2391,52 @@ void halbtcoutsrc_Write_scbd(void *pBtcContext, u16 bitpos, u8 state) if (val != coex_sta->score_board_WB) { coex_sta->score_board_WB = val; val = val | 0x8000; - btc->btc_write_2byte(btc, 0xaa, val); - BTC_SPRINTF(btc_dbg_buf, BT_TMP_BUF_SIZE, - "[BTCoex], write scoreboard 0x%x\n", val); + btc->btc_write_2byte(btc, chip_para->scbd_reg, val); + + RTW_DBG("[BTC], write scoreboard 0x%x\n", val); } else { - BTC_SPRINTF(btc_dbg_buf, BT_TMP_BUF_SIZE, - "[BTCoex], %s: return for nochange\n", __func__); + RTW_DBG("[BTC], return for nochange\n"); + } +} + +void halbtcoutsrc_Write_scbd_32bit(void *pBtcContext, u32 bitpos, u8 state) +{ + PBTC_COEXIST btc = (PBTC_COEXIST)pBtcContext; + struct btc_coex_sta *coex_sta = &btc->coex_sta; + const struct btc_chip_para *chip_para = btc->chip_para; + u32 val = 0x2; + + if (!chip_para->scbd_support) + return; + + val = val | coex_sta->score_board_WB_32bit; + + /* for 8822b, Scoreboard[10]: 0: CQDDR off, 1: CQDDR on + * for 8822c, Scoreboard[10]: 0: CQDDR on, 1:CQDDR fix 2M + */ + if (!btc->chip_para->new_scbd10_def && (bitpos & BTC_SCBD_FIX2M)) { + if (state) + val = val & (~BTC_SCBD_FIX2M); + else + val = val | BTC_SCBD_FIX2M; + } else { + if (state) + val = val | bitpos; + else + val = val & (~bitpos); } - BTC_TRACE(btc_dbg_buf); + if (val != coex_sta->score_board_WB_32bit) { + coex_sta->score_board_WB_32bit = val; + val = val | 0x80000000; + + btc->btc_write_4byte(btc, chip_para->scbd_reg, val); + + RTW_DBG("[BTC], write scoreboard 0x%x\n", val); + } else { + RTW_DBG("[BTC], return for nochange\n"); + } } void halbtcoutsrc_SetBbReg(void *pBtcContext, u32 RegAddr, u32 BitMask, u32 Data) @@ -2451,36 +2543,50 @@ u8 halbtcoutsrc_SetBtAntDetection(void *pBtcContext, u8 txTime, u8 btChnl) #endif } -BOOLEAN -halbtcoutsrc_SetBtTRXMASK( - void *pBtcContext, - u8 bt_trx_mask - ) +u8 halbtcoutsrc_SetBtTRXMASK(void *pBtcContext, u8 bt_trx_mask) { - /* Always return _FALSE since we don't implement this yet */ -#if 0 - struct btc_coexist *pBtCoexist = (struct btc_coexist *)pBtcContext; - PADAPTER Adapter = pBtCoexist->Adapter; - BOOLEAN bStatus = FALSE; - u8 btCanTx = 0; + PBTC_COEXIST pBtCoexist; + u8 bStatus = _FALSE; + u8 btCanTx = 0; + u16 ret = BT_STATUS_BT_OP_SUCCESS; + + pBtCoexist = (PBTC_COEXIST)pBtcContext; if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter) || IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter) || IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) { - if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) - bStatus = NDBG_SetBtTRXMASK(Adapter, 1, bt_trx_mask, &btCanTx); - else - bStatus = NDBG_SetBtTRXMASK(Adapter, 2, bt_trx_mask, &btCanTx); + if (halbtcoutsrc_IsHwMailboxExist(pBtCoexist) == _TRUE) { + u8 buf[3] = {0}; + u8 len = 0; + _irqL irqL; + u8 op_code; + u8 status; + + if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) { + buf[0] = bt_trx_mask; + len = 1; + } else { + buf[0] = (bt_trx_mask & 0x80) >> 7; + buf[1] = bt_trx_mask & 0x7f; + len = 2; + } + + _enter_critical_mutex(&GLBtcBtMpOperLock, &irqL); + + op_code = BT_OP_SET_BT_TRX_MASK; + status = _btmpoper_cmd(pBtCoexist, op_code, 0, buf, len); + if (status != BT_STATUS_BT_OP_SUCCESS) + ret = SET_BT_MP_OPER_RET(op_code, status); + + _exit_critical_mutex(&GLBtcBtMpOperLock, &irqL); + } else + ret = BT_STATUS_NOT_IMPLEMENT; } - - if (bStatus) - return TRUE; + if (ret == BT_STATUS_BT_OP_SUCCESS) + return _TRUE; else - return FALSE; -#else - return _FALSE; -#endif + return _FALSE; } u16 halbtcoutsrc_GetBtReg_with_status(void *pBtcContext, u8 RegType, u32 RegAddr, u32 *data) @@ -2887,7 +2993,7 @@ void halbtcoutsrc_reduce_wl_tx_power(void *pBtcContext, s8 tx_power) HAL_DATA_TYPE *pHalData = GET_HAL_DATA((PADAPTER)pBtCoexist->Adapter); /* The reduction of wl tx pwr should be processed inside the set tx pwr lvl function */ - if (IS_HARDWARE_TYPE_8822C(pBtCoexist->Adapter)) + if (IS_HARDWARE_TYPE_8822C(pBtCoexist->Adapter) || IS_HARDWARE_TYPE_8723F(pBtCoexist->Adapter)) rtw_hal_set_tx_power_level(pBtCoexist->Adapter, pHalData->current_channel); } @@ -3006,6 +3112,114 @@ void BT_CoexOffloadC2hCheck(PADAPTER Adapter, u8 *Buffer, u8 Length) } #endif +#if (CONFIG_BTCOEX_SUPPORT_BTC_CMN == 1) +static void halbtcoutsrc_wl_noisy_detect(struct btc_coexist *btc) +{ + struct btc_coex_sta *coex_sta = &btc->coex_sta; + u32 cnt_cck, ok_11b, err_11b; + + ok_11b = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_CCK); + err_11b = btc->btc_phydm_query_PHY_counter(btc, + PHYDM_INFO_CRC32_ERROR_CCK); + + /* WiFi environment noisy identification */ + cnt_cck = ok_11b + err_11b; + + if (!coex_sta->wl_gl_busy && !coex_sta->wl_cck_lock) { + if (cnt_cck > 250) { + if (coex_sta->cnt_wl[BTC_CNT_WL_NOISY2] < 5) + coex_sta->cnt_wl[BTC_CNT_WL_NOISY2]++; + + if (coex_sta->cnt_wl[BTC_CNT_WL_NOISY2] == 5) { + coex_sta->cnt_wl[BTC_CNT_WL_NOISY0] = 0; + coex_sta->cnt_wl[BTC_CNT_WL_NOISY1] = 0; + } + } else if (cnt_cck < 100) { + if (coex_sta->cnt_wl[BTC_CNT_WL_NOISY0] < 5) + coex_sta->cnt_wl[BTC_CNT_WL_NOISY0]++; + + if (coex_sta->cnt_wl[BTC_CNT_WL_NOISY0] == 5) { + coex_sta->cnt_wl[BTC_CNT_WL_NOISY1] = 0; + coex_sta->cnt_wl[BTC_CNT_WL_NOISY2] = 0; + } + } else { + if (coex_sta->cnt_wl[BTC_CNT_WL_NOISY1] < 5) + coex_sta->cnt_wl[BTC_CNT_WL_NOISY1]++; + + if (coex_sta->cnt_wl[BTC_CNT_WL_NOISY1] == 5) { + coex_sta->cnt_wl[BTC_CNT_WL_NOISY0] = 0; + coex_sta->cnt_wl[BTC_CNT_WL_NOISY2] = 0; + } + } + + if (coex_sta->cnt_wl[BTC_CNT_WL_NOISY2] == 5) + coex_sta->wl_noisy_level = 2; + else if (coex_sta->cnt_wl[BTC_CNT_WL_NOISY1] == 5) + coex_sta->wl_noisy_level = 1; + else + coex_sta->wl_noisy_level = 0; + + RTW_DBG("[BTC], wl_noisy_level = %d\n", + coex_sta->wl_noisy_level); + } +} + +static boolean halbtcoutsrc_btc_monitor_bt_ctr(struct btc_coexist *btc) +{ + struct btc_coex_sta *coex_sta = &btc->coex_sta; + struct btc_coex_dm *coex_dm = &btc->coex_dm; + u32 cnt_bt_hi_pri, cnt_bt_lo_pri, cnt_bt_all; + boolean is_run_coex = _FALSE; + + cnt_bt_hi_pri = btc->btc_read_4byte(btc, REG_BT_ACT_STATISTICS); + coex_sta->hi_pri_tx = cnt_bt_hi_pri & MASKLWORD; + coex_sta->hi_pri_rx = (cnt_bt_hi_pri & MASKHWORD) >> 16; + + cnt_bt_lo_pri = btc->btc_read_4byte(btc, REG_BT_ACT_STATISTICS_1); + coex_sta->lo_pri_tx = cnt_bt_lo_pri & MASKLWORD; + coex_sta->lo_pri_rx = (cnt_bt_lo_pri & MASKHWORD) >> 16; + + RTW_DBG("[BTC], Hi-Pri Rx/Tx: %d/%d, Lo-Pri Rx/Tx: %d/%d\n", + coex_sta->hi_pri_rx, coex_sta->hi_pri_tx, + coex_sta->lo_pri_rx, coex_sta->lo_pri_tx); + + /* reset counter */ + btc->btc_write_1byte(btc, 0x76e, 0xc); + + if (coex_sta->wl_under_lps || coex_sta->wl_under_ips || + (coex_sta->hi_pri_rx == 65535 && coex_sta->hi_pri_tx == 65535 && + coex_sta->lo_pri_rx == 65535 && coex_sta->lo_pri_tx == 65535)) + coex_sta->bt_ctr_ok = _FALSE; + else + coex_sta->bt_ctr_ok = _TRUE; + + if (!coex_sta->bt_ctr_ok) + return _FALSE; + + if (coex_sta->hi_pri_rx == 0 && coex_sta->hi_pri_tx == 0 && + coex_sta->lo_pri_rx == 0 && coex_sta->lo_pri_tx == 0) { + coex_sta->cnt_bt[BTC_CNT_BT_DISABLE]++; + + if (coex_sta->cnt_bt[BTC_CNT_BT_DISABLE] > 2) + coex_sta->cnt_bt[BTC_CNT_BT_DISABLE] = 2; + } else { + coex_sta->cnt_bt[BTC_CNT_BT_DISABLE] = 0; + } + + cnt_bt_all = coex_sta->hi_pri_rx + coex_sta->hi_pri_tx + + coex_sta->lo_pri_rx + coex_sta->lo_pri_tx; + + if ((coex_sta->cnt_bt[BTC_CNT_BT_TRX] > (cnt_bt_all + 50) || + cnt_bt_all > (coex_sta->cnt_bt[BTC_CNT_BT_TRX] + 50)) && + coex_dm->bt_status == BTC_BTSTATUS_NCON_IDLE) + is_run_coex = _TRUE; + + coex_sta->cnt_bt[BTC_CNT_BT_TRX] = cnt_bt_all; + + return is_run_coex; +} +#endif + /* ************************************ * Extern functions called by other module * ************************************ */ @@ -3044,6 +3258,14 @@ u8 EXhalbtcoutsrc_BindBtCoexWithAdapter(void *padapter) pBtCoexist->chip_type = BTC_CHIP_RTL8725A; pBtCoexist->chip_para = &btc_chip_para_8192f; } +#endif +#ifdef PLATFORM_LINUX +#ifdef CONFIG_RTL8723F + else if (IS_HARDWARE_TYPE_8723F(padapter)) { + pBtCoexist->chip_type = BTC_CHIP_RTL8723F; + pBtCoexist->chip_para = &btc_chip_para_8723f; + } +#endif #endif else { pBtCoexist->chip_type = BTC_CHIP_UNDEF; @@ -3119,7 +3341,9 @@ u8 EXhalbtcoutsrc_InitlizeVariables(void *padapter) pBtCoexist->btc_write_linderct = halbtcoutsrc_WriteLIndirectReg; pBtCoexist->btc_read_scbd = halbtcoutsrc_Read_scbd; + pBtCoexist->btc_read_scbd_32bit = halbtcoutsrc_Read_scbd_32bit; pBtCoexist->btc_write_scbd = halbtcoutsrc_Write_scbd; + pBtCoexist->btc_write_scbd_32bit = halbtcoutsrc_Write_scbd_32bit; pBtCoexist->btc_set_bb_reg = halbtcoutsrc_SetBbReg; pBtCoexist->btc_get_bb_reg = halbtcoutsrc_GetBbReg; @@ -4689,15 +4913,19 @@ u32 EXhalbtcoutsrc_CoexTimerCheck(PBTC_COEXIST pBtCoexist) u32 EXhalbtcoutsrc_WLStatusCheck(PBTC_COEXIST pBtCoexist) { struct btc_wifi_link_info link_info; + struct btc_coex_sta *coex_sta = &pBtCoexist->coex_sta; const struct btc_chip_para *chip_para = pBtCoexist->chip_para; u32 change_map = 0; static bool wl_busy_pre; - bool wl_busy = _FALSE; + bool wl_busy = _FALSE, bt_ctr_change = _FALSE; s32 wl_rssi; u32 traffic_dir; u8 i, tmp; static u8 rssi_step_pre = 5, wl_noisy_level_pre = 4; + halbtcoutsrc_wl_noisy_detect(pBtCoexist); + bt_ctr_change = halbtcoutsrc_btc_monitor_bt_ctr(pBtCoexist); + /* WL busy to idle or idle to busy */ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &wl_busy); if (wl_busy != wl_busy_pre) { @@ -4743,9 +4971,30 @@ u32 EXhalbtcoutsrc_WLStatusCheck(PBTC_COEXIST pBtCoexist) } /* Noisy Detect */ - if (pBtCoexist->coex_sta.wl_noisy_level != wl_noisy_level_pre) { + if (coex_sta->wl_noisy_level != wl_noisy_level_pre) { change_map |= BIT(BTC_WLSTATUS_CHANGE_NOISY); - wl_noisy_level_pre = pBtCoexist->coex_sta.wl_noisy_level; + wl_noisy_level_pre = coex_sta->wl_noisy_level; + } + + /* BT Counter change > 50 */ + if (bt_ctr_change) + change_map |= BIT(BTC_WLSTATUS_CHANGE_BTCNT); + + /* CCK Lock Try */ + if (coex_sta->wl_coex_mode == BTC_WLINK_2GFREE) + coex_sta->cnt_wl[BTC_CNT_WL_2G_FDDSTAY]++; + + if (coex_sta->wl_coex_mode == BTC_WLINK_2GFREE && + coex_sta->cnt_wl[BTC_CNT_WL_2G_FDDSTAY] > BTC_2GFDD_MAX_STAY && + coex_sta->cnt_wl[BTC_CNT_WL_2G_TDDTRY] < BTC_2GTDD_MAX_TRY) { + coex_sta->cnt_wl[BTC_CNT_WL_2G_TDDTRY]++; + + RTW_DBG("[BTC], Try 2.4G coex from FDD to TDD (FDD:%d, TRY:%d)\n", + coex_sta->cnt_wl[BTC_CNT_WL_2G_FDDSTAY], + coex_sta->cnt_wl[BTC_CNT_WL_2G_TDDTRY]); + + coex_sta->cnt_wl[BTC_CNT_WL_2G_FDDSTAY] = 0; + change_map |= BIT(BTC_WLSTATUS_CHANGE_LOCKTRY); } RTW_DBG("[BTC], %s(): change_map = 0x%x\n", __func__, change_map); @@ -4769,6 +5018,14 @@ void EXhalbtcoutsrc_status_monitor(PBTC_COEXIST pBtCoexist) } #endif +void EXhalbtcoutsrc_WL_RFK_Notify(PBTC_COEXIST pBtCoexist, u8 path, u8 type, u8 state) +{ + #if (CONFIG_BTCOEX_SUPPORT_BTC_CMN == 1) + rtw_btc_ex_wl_rfk_notify(pBtCoexist, path, type, state); + #endif + return; +} + void EXhalbtcoutsrc_periodical(PBTC_COEXIST pBtCoexist) { if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) @@ -5714,6 +5971,11 @@ void hal_btcoex_IQKNotify(PADAPTER padapter, u8 state) GLBtcWiFiInIQKState = state; } +void hal_btcoex_WLRFKNotify(PADAPTER padapter, u8 path, u8 type, u8 state) +{ + EXhalbtcoutsrc_WL_RFK_Notify(&GLBtCoexist, path, type, state); +} + void hal_btcoex_BtInfoNotify(PADAPTER padapter, u8 length, u8 *tmpBuf) { if (GLBtcWiFiInIQKState == _TRUE) @@ -5836,6 +6098,24 @@ void hal_btcoex_SetManualControl(PADAPTER padapter, u8 bmanual) GLBtCoexist.manual_control = bmanual; } +void hal_btcoex_set_policy_control(PADAPTER padapter, u8 btc_policy) +{ + switch (btc_policy) { + case BTCOEX_POLICY_CONTROL_AUTO: + GLBtCoexist.coex_sta.force_freerun = _FALSE; + GLBtCoexist.coex_sta.force_tdd = _FALSE; + break; + case BTCOEX_POLICY_CONTROL_FORCE_FREERUN: + GLBtCoexist.coex_sta.force_freerun = _TRUE; + GLBtCoexist.coex_sta.force_tdd = _FALSE; + break; + case BTCOEX_POLICY_CONTROL_FORCE_TDMA: + GLBtCoexist.coex_sta.force_freerun = _FALSE; + GLBtCoexist.coex_sta.force_tdd = _TRUE; + break; + } +} + u8 hal_btcoex_1Ant(PADAPTER padapter) { if (hal_btcoex_IsBtExist(padapter) == _FALSE) diff --git a/hal/hal_btcoex_wifionly.c b/hal/hal_btcoex_wifionly.c index 4752bc3..a9ef07f 100644 --- a/hal/hal_btcoex_wifionly.c +++ b/hal/hal_btcoex_wifionly.c @@ -132,6 +132,11 @@ void hal_btcoex_wifionly_switchband_notify(PADAPTER padapter) else if (IS_HARDWARE_TYPE_8814B(padapter)) ex_hal8814b_wifi_only_switchbandnotify(&GLBtCoexistWifiOnly, is_5g); #endif + +#ifdef CONFIG_RTL8723F + else if (IS_HARDWARE_TYPE_8723F(padapter)) + ex_hal8723f_wifi_only_switchbandnotify(&GLBtCoexistWifiOnly, is_5g); +#endif } void hal_btcoex_wifionly_scan_notify(PADAPTER padapter) @@ -192,6 +197,11 @@ void hal_btcoex_wifionly_connect_notify(PADAPTER padapter) else if (IS_HARDWARE_TYPE_8814B(padapter)) ex_hal8814b_wifi_only_connectnotify(&GLBtCoexistWifiOnly, is_5g); #endif + +#ifdef CONFIG_RTL8723F + else if (IS_HARDWARE_TYPE_8723F(padapter)) + ex_hal8723f_wifi_only_connectnotify(&GLBtCoexistWifiOnly, is_5g); +#endif } void hal_btcoex_wifionly_hw_config(PADAPTER padapter) @@ -223,6 +233,11 @@ void hal_btcoex_wifionly_hw_config(PADAPTER padapter) else if (IS_HARDWARE_TYPE_8814B(padapter)) ex_hal8814b_wifi_only_hw_config(pwifionlycfg); #endif + +#ifdef CONFIG_RTL8723F + else if (IS_HARDWARE_TYPE_8723F(padapter)) + ex_hal8723f_wifi_only_hw_config(pwifionlycfg); +#endif } void hal_btcoex_wifionly_initlizevariables(PADAPTER padapter) diff --git a/hal/hal_com.c b/hal/hal_com.c index db3dba5..eee4824 100644 --- a/hal/hal_com.c +++ b/hal/hal_com.c @@ -20,7 +20,7 @@ #include "hal_data.h" #ifdef RTW_HALMAC -#include "../hal/hal_halmac.h" +#include "../../hal/hal_halmac.h" #endif void rtw_dump_fw_info(void *sel, _adapter *adapter) @@ -40,10 +40,14 @@ void rtw_dump_fw_info(void *sel, _adapter *adapter) bool rsvd_page_cache_update_all(struct rsvd_page_cache_t *cache, u8 loc , u8 txdesc_len, u32 page_size, u8 *info, u32 info_len) { - u8 page_num = (u8)PageNum(txdesc_len + info_len, page_size); + u8 page_num; bool modified = 0; bool loc_mod = 0, size_mod = 0, page_num_mod = 0; - + + page_num = info_len ? (u8)PageNum(txdesc_len + info_len, page_size) : 0; + if (!info_len) + loc = 0; + if (cache->loc != loc) { RTW_INFO("%s %s loc change (%u -> %u)\n" , __func__, cache->name, cache->loc, loc); @@ -60,7 +64,7 @@ bool rsvd_page_cache_update_all(struct rsvd_page_cache_t *cache, u8 loc page_num_mod = 1; } - if (info) { + if (info && info_len) { if (cache->data) { if (cache->size == info_len) { if (_rtw_memcmp(cache->data, info, info_len) != _TRUE) { @@ -265,6 +269,10 @@ void dump_chip_info(HAL_VERSION ChipVersion) cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192F_"); else if (IS_8822C_SERIES(ChipVersion)) cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822C_"); + else if (IS_8814B_SERIES(ChipVersion)) + cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814B_"); + else if (IS_8723F_SERIES(ChipVersion)) + cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723F_"); else cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_"); @@ -334,12 +342,14 @@ u8 rtw_hal_get_port(_adapter *adapter) rtw_warn_on(1); } } + #ifdef CONFIG_AP_MODE else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) { if (hw_port != HW_PORT0) { RTW_ERR(ADPT_FMT" @@@@@ AP / MESH port != 0 @@@@@\n", ADPT_ARG(adapter)); rtw_warn_on(1); } } + #endif if (0) RTW_INFO(ADPT_FMT" - HP:%d,CP:%d\n", ADPT_ARG(adapter), get_hw_port(adapter), get_clt_port(adapter)); #endif /*DBG_HW_PORT*/ @@ -482,539 +492,333 @@ HAL_IsLegalChannel( return bLegalChannel; } -u8 MRateToHwRate(u8 rate) +static const u8 _MRateToHwRate[MGN_UNKNOWN] = { + [MGN_1M] = DESC_RATE1M, + [MGN_2M] = DESC_RATE2M, + [MGN_5_5M] = DESC_RATE5_5M, + [MGN_11M] = DESC_RATE11M, + [MGN_6M] = DESC_RATE6M, + [MGN_9M] = DESC_RATE9M, + [MGN_12M] = DESC_RATE12M, + [MGN_18M] = DESC_RATE18M, + [MGN_24M] = DESC_RATE24M, + [MGN_36M] = DESC_RATE36M, + [MGN_48M] = DESC_RATE48M, + [MGN_54M] = DESC_RATE54M, + [MGN_MCS0] = DESC_RATEMCS0, + [MGN_MCS1] = DESC_RATEMCS1, + [MGN_MCS2] = DESC_RATEMCS2, + [MGN_MCS3] = DESC_RATEMCS3, + [MGN_MCS4] = DESC_RATEMCS4, + [MGN_MCS5] = DESC_RATEMCS5, + [MGN_MCS6] = DESC_RATEMCS6, + [MGN_MCS7] = DESC_RATEMCS7, + [MGN_MCS8] = DESC_RATEMCS8, + [MGN_MCS9] = DESC_RATEMCS9, + [MGN_MCS10] = DESC_RATEMCS10, + [MGN_MCS11] = DESC_RATEMCS11, + [MGN_MCS12] = DESC_RATEMCS12, + [MGN_MCS13] = DESC_RATEMCS13, + [MGN_MCS14] = DESC_RATEMCS14, + [MGN_MCS15] = DESC_RATEMCS15, + [MGN_MCS16] = DESC_RATEMCS16, + [MGN_MCS17] = DESC_RATEMCS17, + [MGN_MCS18] = DESC_RATEMCS18, + [MGN_MCS19] = DESC_RATEMCS19, + [MGN_MCS20] = DESC_RATEMCS20, + [MGN_MCS21] = DESC_RATEMCS21, + [MGN_MCS22] = DESC_RATEMCS22, + [MGN_MCS23] = DESC_RATEMCS23, + [MGN_MCS24] = DESC_RATEMCS24, + [MGN_MCS25] = DESC_RATEMCS25, + [MGN_MCS26] = DESC_RATEMCS26, + [MGN_MCS27] = DESC_RATEMCS27, + [MGN_MCS28] = DESC_RATEMCS28, + [MGN_MCS29] = DESC_RATEMCS29, + [MGN_MCS30] = DESC_RATEMCS30, + [MGN_MCS31] = DESC_RATEMCS31, + [MGN_VHT1SS_MCS0] = DESC_RATEVHTSS1MCS0, + [MGN_VHT1SS_MCS1] = DESC_RATEVHTSS1MCS1, + [MGN_VHT1SS_MCS2] = DESC_RATEVHTSS1MCS2, + [MGN_VHT1SS_MCS3] = DESC_RATEVHTSS1MCS3, + [MGN_VHT1SS_MCS4] = DESC_RATEVHTSS1MCS4, + [MGN_VHT1SS_MCS5] = DESC_RATEVHTSS1MCS5, + [MGN_VHT1SS_MCS6] = DESC_RATEVHTSS1MCS6, + [MGN_VHT1SS_MCS7] = DESC_RATEVHTSS1MCS7, + [MGN_VHT1SS_MCS8] = DESC_RATEVHTSS1MCS8, + [MGN_VHT1SS_MCS9] = DESC_RATEVHTSS1MCS9, + [MGN_VHT2SS_MCS0] = DESC_RATEVHTSS2MCS0, + [MGN_VHT2SS_MCS1] = DESC_RATEVHTSS2MCS1, + [MGN_VHT2SS_MCS2] = DESC_RATEVHTSS2MCS2, + [MGN_VHT2SS_MCS3] = DESC_RATEVHTSS2MCS3, + [MGN_VHT2SS_MCS4] = DESC_RATEVHTSS2MCS4, + [MGN_VHT2SS_MCS5] = DESC_RATEVHTSS2MCS5, + [MGN_VHT2SS_MCS6] = DESC_RATEVHTSS2MCS6, + [MGN_VHT2SS_MCS7] = DESC_RATEVHTSS2MCS7, + [MGN_VHT2SS_MCS8] = DESC_RATEVHTSS2MCS8, + [MGN_VHT2SS_MCS9] = DESC_RATEVHTSS2MCS9, + [MGN_VHT3SS_MCS0] = DESC_RATEVHTSS3MCS0, + [MGN_VHT3SS_MCS1] = DESC_RATEVHTSS3MCS1, + [MGN_VHT3SS_MCS2] = DESC_RATEVHTSS3MCS2, + [MGN_VHT3SS_MCS3] = DESC_RATEVHTSS3MCS3, + [MGN_VHT3SS_MCS4] = DESC_RATEVHTSS3MCS4, + [MGN_VHT3SS_MCS5] = DESC_RATEVHTSS3MCS5, + [MGN_VHT3SS_MCS6] = DESC_RATEVHTSS3MCS6, + [MGN_VHT3SS_MCS7] = DESC_RATEVHTSS3MCS7, + [MGN_VHT3SS_MCS8] = DESC_RATEVHTSS3MCS8, + [MGN_VHT3SS_MCS9] = DESC_RATEVHTSS3MCS9, + [MGN_VHT4SS_MCS0] = DESC_RATEVHTSS4MCS0, + [MGN_VHT4SS_MCS1] = DESC_RATEVHTSS4MCS1, + [MGN_VHT4SS_MCS2] = DESC_RATEVHTSS4MCS2, + [MGN_VHT4SS_MCS3] = DESC_RATEVHTSS4MCS3, + [MGN_VHT4SS_MCS4] = DESC_RATEVHTSS4MCS4, + [MGN_VHT4SS_MCS5] = DESC_RATEVHTSS4MCS5, + [MGN_VHT4SS_MCS6] = DESC_RATEVHTSS4MCS6, + [MGN_VHT4SS_MCS7] = DESC_RATEVHTSS4MCS7, + [MGN_VHT4SS_MCS8] = DESC_RATEVHTSS4MCS8, + [MGN_VHT4SS_MCS9] = DESC_RATEVHTSS4MCS9, +}; + +u8 MRateToHwRate(enum MGN_RATE rate) { - u8 ret = DESC_RATE1M; + u8 hw_rate = DESC_RATE1M; /* default value, also is zero */ - switch (rate) { - case MGN_1M: - ret = DESC_RATE1M; - break; - case MGN_2M: - ret = DESC_RATE2M; - break; - case MGN_5_5M: - ret = DESC_RATE5_5M; - break; - case MGN_11M: - ret = DESC_RATE11M; - break; - case MGN_6M: - ret = DESC_RATE6M; - break; - case MGN_9M: - ret = DESC_RATE9M; - break; - case MGN_12M: - ret = DESC_RATE12M; - break; - case MGN_18M: - ret = DESC_RATE18M; - break; - case MGN_24M: - ret = DESC_RATE24M; - break; - case MGN_36M: - ret = DESC_RATE36M; - break; - case MGN_48M: - ret = DESC_RATE48M; - break; - case MGN_54M: - ret = DESC_RATE54M; - break; + if (rate < MGN_UNKNOWN) + hw_rate = _MRateToHwRate[rate]; - case MGN_MCS0: - ret = DESC_RATEMCS0; - break; - case MGN_MCS1: - ret = DESC_RATEMCS1; - break; - case MGN_MCS2: - ret = DESC_RATEMCS2; - break; - case MGN_MCS3: - ret = DESC_RATEMCS3; - break; - case MGN_MCS4: - ret = DESC_RATEMCS4; - break; - case MGN_MCS5: - ret = DESC_RATEMCS5; - break; - case MGN_MCS6: - ret = DESC_RATEMCS6; - break; - case MGN_MCS7: - ret = DESC_RATEMCS7; - break; - case MGN_MCS8: - ret = DESC_RATEMCS8; - break; - case MGN_MCS9: - ret = DESC_RATEMCS9; - break; - case MGN_MCS10: - ret = DESC_RATEMCS10; - break; - case MGN_MCS11: - ret = DESC_RATEMCS11; - break; - case MGN_MCS12: - ret = DESC_RATEMCS12; - break; - case MGN_MCS13: - ret = DESC_RATEMCS13; - break; - case MGN_MCS14: - ret = DESC_RATEMCS14; - break; - case MGN_MCS15: - ret = DESC_RATEMCS15; - break; - case MGN_MCS16: - ret = DESC_RATEMCS16; - break; - case MGN_MCS17: - ret = DESC_RATEMCS17; - break; - case MGN_MCS18: - ret = DESC_RATEMCS18; - break; - case MGN_MCS19: - ret = DESC_RATEMCS19; - break; - case MGN_MCS20: - ret = DESC_RATEMCS20; - break; - case MGN_MCS21: - ret = DESC_RATEMCS21; - break; - case MGN_MCS22: - ret = DESC_RATEMCS22; - break; - case MGN_MCS23: - ret = DESC_RATEMCS23; - break; - case MGN_MCS24: - ret = DESC_RATEMCS24; - break; - case MGN_MCS25: - ret = DESC_RATEMCS25; - break; - case MGN_MCS26: - ret = DESC_RATEMCS26; - break; - case MGN_MCS27: - ret = DESC_RATEMCS27; - break; - case MGN_MCS28: - ret = DESC_RATEMCS28; - break; - case MGN_MCS29: - ret = DESC_RATEMCS29; - break; - case MGN_MCS30: - ret = DESC_RATEMCS30; - break; - case MGN_MCS31: - ret = DESC_RATEMCS31; - break; + if (rate != MGN_1M && hw_rate == DESC_RATE1M) + RTW_WARN("Invalid rate 0x%x in %s\n", rate, __FUNCTION__); - case MGN_VHT1SS_MCS0: - ret = DESC_RATEVHTSS1MCS0; - break; - case MGN_VHT1SS_MCS1: - ret = DESC_RATEVHTSS1MCS1; - break; - case MGN_VHT1SS_MCS2: - ret = DESC_RATEVHTSS1MCS2; - break; - case MGN_VHT1SS_MCS3: - ret = DESC_RATEVHTSS1MCS3; - break; - case MGN_VHT1SS_MCS4: - ret = DESC_RATEVHTSS1MCS4; - break; - case MGN_VHT1SS_MCS5: - ret = DESC_RATEVHTSS1MCS5; - break; - case MGN_VHT1SS_MCS6: - ret = DESC_RATEVHTSS1MCS6; - break; - case MGN_VHT1SS_MCS7: - ret = DESC_RATEVHTSS1MCS7; - break; - case MGN_VHT1SS_MCS8: - ret = DESC_RATEVHTSS1MCS8; - break; - case MGN_VHT1SS_MCS9: - ret = DESC_RATEVHTSS1MCS9; - break; - case MGN_VHT2SS_MCS0: - ret = DESC_RATEVHTSS2MCS0; - break; - case MGN_VHT2SS_MCS1: - ret = DESC_RATEVHTSS2MCS1; - break; - case MGN_VHT2SS_MCS2: - ret = DESC_RATEVHTSS2MCS2; - break; - case MGN_VHT2SS_MCS3: - ret = DESC_RATEVHTSS2MCS3; - break; - case MGN_VHT2SS_MCS4: - ret = DESC_RATEVHTSS2MCS4; - break; - case MGN_VHT2SS_MCS5: - ret = DESC_RATEVHTSS2MCS5; - break; - case MGN_VHT2SS_MCS6: - ret = DESC_RATEVHTSS2MCS6; - break; - case MGN_VHT2SS_MCS7: - ret = DESC_RATEVHTSS2MCS7; - break; - case MGN_VHT2SS_MCS8: - ret = DESC_RATEVHTSS2MCS8; - break; - case MGN_VHT2SS_MCS9: - ret = DESC_RATEVHTSS2MCS9; - break; - case MGN_VHT3SS_MCS0: - ret = DESC_RATEVHTSS3MCS0; - break; - case MGN_VHT3SS_MCS1: - ret = DESC_RATEVHTSS3MCS1; - break; - case MGN_VHT3SS_MCS2: - ret = DESC_RATEVHTSS3MCS2; - break; - case MGN_VHT3SS_MCS3: - ret = DESC_RATEVHTSS3MCS3; - break; - case MGN_VHT3SS_MCS4: - ret = DESC_RATEVHTSS3MCS4; - break; - case MGN_VHT3SS_MCS5: - ret = DESC_RATEVHTSS3MCS5; - break; - case MGN_VHT3SS_MCS6: - ret = DESC_RATEVHTSS3MCS6; - break; - case MGN_VHT3SS_MCS7: - ret = DESC_RATEVHTSS3MCS7; - break; - case MGN_VHT3SS_MCS8: - ret = DESC_RATEVHTSS3MCS8; - break; - case MGN_VHT3SS_MCS9: - ret = DESC_RATEVHTSS3MCS9; - break; - case MGN_VHT4SS_MCS0: - ret = DESC_RATEVHTSS4MCS0; - break; - case MGN_VHT4SS_MCS1: - ret = DESC_RATEVHTSS4MCS1; - break; - case MGN_VHT4SS_MCS2: - ret = DESC_RATEVHTSS4MCS2; - break; - case MGN_VHT4SS_MCS3: - ret = DESC_RATEVHTSS4MCS3; - break; - case MGN_VHT4SS_MCS4: - ret = DESC_RATEVHTSS4MCS4; - break; - case MGN_VHT4SS_MCS5: - ret = DESC_RATEVHTSS4MCS5; - break; - case MGN_VHT4SS_MCS6: - ret = DESC_RATEVHTSS4MCS6; - break; - case MGN_VHT4SS_MCS7: - ret = DESC_RATEVHTSS4MCS7; - break; - case MGN_VHT4SS_MCS8: - ret = DESC_RATEVHTSS4MCS8; - break; - case MGN_VHT4SS_MCS9: - ret = DESC_RATEVHTSS4MCS9; - break; - default: - break; - } - - return ret; + return hw_rate; } -u8 hw_rate_to_m_rate(u8 rate) +const char * const _HDATA_RATE[DESC_RATE_NUM + 1] = { + [DESC_RATE1M] = "CCK_1M", + [DESC_RATE2M] = "CCK_2M", + [DESC_RATE5_5M] = "CCK5_5M", + [DESC_RATE11M] = "CCK_11M", + [DESC_RATE6M] = "OFDM_6M", + [DESC_RATE9M] = "OFDM_9M", + [DESC_RATE12M] = "OFDM_12M", + [DESC_RATE18M] = "OFDM_18M", + [DESC_RATE24M] = "OFDM_24M", + [DESC_RATE36M] = "OFDM_36M", + [DESC_RATE48M] = "OFDM_48M", + [DESC_RATE54M] = "OFDM_54M", + [DESC_RATEMCS0] = "MCS0", + [DESC_RATEMCS1] = "MCS1", + [DESC_RATEMCS2] = "MCS2", + [DESC_RATEMCS3] = "MCS3", + [DESC_RATEMCS4] = "MCS4", + [DESC_RATEMCS5] = "MCS5", + [DESC_RATEMCS6] = "MCS6", + [DESC_RATEMCS7] = "MCS7", + [DESC_RATEMCS8] = "MCS8", + [DESC_RATEMCS9] = "MCS9", + [DESC_RATEMCS10] = "MCS10", + [DESC_RATEMCS11] = "MCS11", + [DESC_RATEMCS12] = "MCS12", + [DESC_RATEMCS13] = "MCS13", + [DESC_RATEMCS14] = "MCS14", + [DESC_RATEMCS15] = "MCS15", + [DESC_RATEMCS16] = "MCS16", + [DESC_RATEMCS17] = "MCS17", + [DESC_RATEMCS18] = "MCS18", + [DESC_RATEMCS19] = "MCS19", + [DESC_RATEMCS20] = "MCS20", + [DESC_RATEMCS21] = "MCS21", + [DESC_RATEMCS22] = "MCS22", + [DESC_RATEMCS23] = "MCS23", + [DESC_RATEMCS24] = "MCS24", + [DESC_RATEMCS25] = "MCS25", + [DESC_RATEMCS26] = "MCS26", + [DESC_RATEMCS27] = "MCS27", + [DESC_RATEMCS28] = "MCS28", + [DESC_RATEMCS29] = "MCS29", + [DESC_RATEMCS30] = "MCS30", + [DESC_RATEMCS31] = "MCS31", + [DESC_RATEVHTSS1MCS0] = "VHT1SMCS0", + [DESC_RATEVHTSS1MCS1] = "VHT1SMCS1", + [DESC_RATEVHTSS1MCS2] = "VHT1SMCS2", + [DESC_RATEVHTSS1MCS3] = "VHT1SMCS3", + [DESC_RATEVHTSS1MCS4] = "VHT1SMCS4", + [DESC_RATEVHTSS1MCS5] = "VHT1SMCS5", + [DESC_RATEVHTSS1MCS6] = "VHT1SMCS6", + [DESC_RATEVHTSS1MCS7] = "VHT1SMCS7", + [DESC_RATEVHTSS1MCS8] = "VHT1SMCS8", + [DESC_RATEVHTSS1MCS9] = "VHT1SMCS9", + [DESC_RATEVHTSS2MCS0] = "VHT2SMCS0", + [DESC_RATEVHTSS2MCS1] = "VHT2SMCS1", + [DESC_RATEVHTSS2MCS2] = "VHT2SMCS2", + [DESC_RATEVHTSS2MCS3] = "VHT2SMCS3", + [DESC_RATEVHTSS2MCS4] = "VHT2SMCS4", + [DESC_RATEVHTSS2MCS5] = "VHT2SMCS5", + [DESC_RATEVHTSS2MCS6] = "VHT2SMCS6", + [DESC_RATEVHTSS2MCS7] = "VHT2SMCS7", + [DESC_RATEVHTSS2MCS8] = "VHT2SMCS8", + [DESC_RATEVHTSS2MCS9] = "VHT2SMCS9", + [DESC_RATEVHTSS3MCS0] = "VHT3SMCS0", + [DESC_RATEVHTSS3MCS1] = "VHT3SMCS1", + [DESC_RATEVHTSS3MCS2] = "VHT3SMCS2", + [DESC_RATEVHTSS3MCS3] = "VHT3SMCS3", + [DESC_RATEVHTSS3MCS4] = "VHT3SMCS4", + [DESC_RATEVHTSS3MCS5] = "VHT3SMCS5", + [DESC_RATEVHTSS3MCS6] = "VHT3SMCS6", + [DESC_RATEVHTSS3MCS7] = "VHT3SMCS7", + [DESC_RATEVHTSS3MCS8] = "VHT3SMCS8", + [DESC_RATEVHTSS3MCS9] = "VHT3SMCS9", + [DESC_RATEVHTSS4MCS0] = "VHT4SMCS0", + [DESC_RATEVHTSS4MCS1] = "VHT4SMCS1", + [DESC_RATEVHTSS4MCS2] = "VHT4SMCS2", + [DESC_RATEVHTSS4MCS3] = "VHT4SMCS3", + [DESC_RATEVHTSS4MCS4] = "VHT4SMCS4", + [DESC_RATEVHTSS4MCS5] = "VHT4SMCS5", + [DESC_RATEVHTSS4MCS6] = "VHT4SMCS6", + [DESC_RATEVHTSS4MCS7] = "VHT4SMCS7", + [DESC_RATEVHTSS4MCS8] = "VHT4SMCS8", + [DESC_RATEVHTSS4MCS9] = "VHT4SMCS9", + [DESC_RATE_NUM] = "UNKNOWN", +}; + +static const u8 _hw_rate_to_m_rate[DESC_RATE_NUM] = { + [DESC_RATE1M] = MGN_1M, + [DESC_RATE2M] = MGN_2M, + [DESC_RATE5_5M] = MGN_5_5M, + [DESC_RATE11M] = MGN_11M, + [DESC_RATE6M] = MGN_6M, + [DESC_RATE9M] = MGN_9M, + [DESC_RATE12M] = MGN_12M, + [DESC_RATE18M] = MGN_18M, + [DESC_RATE24M] = MGN_24M, + [DESC_RATE36M] = MGN_36M, + [DESC_RATE48M] = MGN_48M, + [DESC_RATE54M] = MGN_54M, + [DESC_RATEMCS0] = MGN_MCS0, + [DESC_RATEMCS1] = MGN_MCS1, + [DESC_RATEMCS2] = MGN_MCS2, + [DESC_RATEMCS3] = MGN_MCS3, + [DESC_RATEMCS4] = MGN_MCS4, + [DESC_RATEMCS5] = MGN_MCS5, + [DESC_RATEMCS6] = MGN_MCS6, + [DESC_RATEMCS7] = MGN_MCS7, + [DESC_RATEMCS8] = MGN_MCS8, + [DESC_RATEMCS9] = MGN_MCS9, + [DESC_RATEMCS10] = MGN_MCS10, + [DESC_RATEMCS11] = MGN_MCS11, + [DESC_RATEMCS12] = MGN_MCS12, + [DESC_RATEMCS13] = MGN_MCS13, + [DESC_RATEMCS14] = MGN_MCS14, + [DESC_RATEMCS15] = MGN_MCS15, + [DESC_RATEMCS16] = MGN_MCS16, + [DESC_RATEMCS17] = MGN_MCS17, + [DESC_RATEMCS18] = MGN_MCS18, + [DESC_RATEMCS19] = MGN_MCS19, + [DESC_RATEMCS20] = MGN_MCS20, + [DESC_RATEMCS21] = MGN_MCS21, + [DESC_RATEMCS22] = MGN_MCS22, + [DESC_RATEMCS23] = MGN_MCS23, + [DESC_RATEMCS24] = MGN_MCS24, + [DESC_RATEMCS25] = MGN_MCS25, + [DESC_RATEMCS26] = MGN_MCS26, + [DESC_RATEMCS27] = MGN_MCS27, + [DESC_RATEMCS28] = MGN_MCS28, + [DESC_RATEMCS29] = MGN_MCS29, + [DESC_RATEMCS30] = MGN_MCS30, + [DESC_RATEMCS31] = MGN_MCS31, + [DESC_RATEVHTSS1MCS0] = MGN_VHT1SS_MCS0, + [DESC_RATEVHTSS1MCS1] = MGN_VHT1SS_MCS1, + [DESC_RATEVHTSS1MCS2] = MGN_VHT1SS_MCS2, + [DESC_RATEVHTSS1MCS3] = MGN_VHT1SS_MCS3, + [DESC_RATEVHTSS1MCS4] = MGN_VHT1SS_MCS4, + [DESC_RATEVHTSS1MCS5] = MGN_VHT1SS_MCS5, + [DESC_RATEVHTSS1MCS6] = MGN_VHT1SS_MCS6, + [DESC_RATEVHTSS1MCS7] = MGN_VHT1SS_MCS7, + [DESC_RATEVHTSS1MCS8] = MGN_VHT1SS_MCS8, + [DESC_RATEVHTSS1MCS9] = MGN_VHT1SS_MCS9, + [DESC_RATEVHTSS2MCS0] = MGN_VHT2SS_MCS0, + [DESC_RATEVHTSS2MCS1] = MGN_VHT2SS_MCS1, + [DESC_RATEVHTSS2MCS2] = MGN_VHT2SS_MCS2, + [DESC_RATEVHTSS2MCS3] = MGN_VHT2SS_MCS3, + [DESC_RATEVHTSS2MCS4] = MGN_VHT2SS_MCS4, + [DESC_RATEVHTSS2MCS5] = MGN_VHT2SS_MCS5, + [DESC_RATEVHTSS2MCS6] = MGN_VHT2SS_MCS6, + [DESC_RATEVHTSS2MCS7] = MGN_VHT2SS_MCS7, + [DESC_RATEVHTSS2MCS8] = MGN_VHT2SS_MCS8, + [DESC_RATEVHTSS2MCS9] = MGN_VHT2SS_MCS9, + [DESC_RATEVHTSS3MCS0] = MGN_VHT3SS_MCS0, + [DESC_RATEVHTSS3MCS1] = MGN_VHT3SS_MCS1, + [DESC_RATEVHTSS3MCS2] = MGN_VHT3SS_MCS2, + [DESC_RATEVHTSS3MCS3] = MGN_VHT3SS_MCS3, + [DESC_RATEVHTSS3MCS4] = MGN_VHT3SS_MCS4, + [DESC_RATEVHTSS3MCS5] = MGN_VHT3SS_MCS5, + [DESC_RATEVHTSS3MCS6] = MGN_VHT3SS_MCS6, + [DESC_RATEVHTSS3MCS7] = MGN_VHT3SS_MCS7, + [DESC_RATEVHTSS3MCS8] = MGN_VHT3SS_MCS8, + [DESC_RATEVHTSS3MCS9] = MGN_VHT3SS_MCS9, + [DESC_RATEVHTSS4MCS0] = MGN_VHT4SS_MCS0, + [DESC_RATEVHTSS4MCS1] = MGN_VHT4SS_MCS1, + [DESC_RATEVHTSS4MCS2] = MGN_VHT4SS_MCS2, + [DESC_RATEVHTSS4MCS3] = MGN_VHT4SS_MCS3, + [DESC_RATEVHTSS4MCS4] = MGN_VHT4SS_MCS4, + [DESC_RATEVHTSS4MCS5] = MGN_VHT4SS_MCS5, + [DESC_RATEVHTSS4MCS6] = MGN_VHT4SS_MCS6, + [DESC_RATEVHTSS4MCS7] = MGN_VHT4SS_MCS7, + [DESC_RATEVHTSS4MCS8] = MGN_VHT4SS_MCS8, + [DESC_RATEVHTSS4MCS9] = MGN_VHT4SS_MCS9, +}; + +u8 hw_rate_to_m_rate(u8 hw_rate) { - u8 ret_rate = MGN_1M; + u8 rate = MGN_1M; /* default value */ - switch (rate) { + if (hw_rate < DESC_RATE_NUM) + rate = _hw_rate_to_m_rate[hw_rate]; + else + RTW_WARN("Invalid hw_rate 0x%x in %s\n", hw_rate, __FUNCTION__); - case DESC_RATE1M: - ret_rate = MGN_1M; - break; - case DESC_RATE2M: - ret_rate = MGN_2M; - break; - case DESC_RATE5_5M: - ret_rate = MGN_5_5M; - break; - case DESC_RATE11M: - ret_rate = MGN_11M; - break; - case DESC_RATE6M: - ret_rate = MGN_6M; - break; - case DESC_RATE9M: - ret_rate = MGN_9M; - break; - case DESC_RATE12M: - ret_rate = MGN_12M; - break; - case DESC_RATE18M: - ret_rate = MGN_18M; - break; - case DESC_RATE24M: - ret_rate = MGN_24M; - break; - case DESC_RATE36M: - ret_rate = MGN_36M; - break; - case DESC_RATE48M: - ret_rate = MGN_48M; - break; - case DESC_RATE54M: - ret_rate = MGN_54M; - break; - case DESC_RATEMCS0: - ret_rate = MGN_MCS0; - break; - case DESC_RATEMCS1: - ret_rate = MGN_MCS1; - break; - case DESC_RATEMCS2: - ret_rate = MGN_MCS2; - break; - case DESC_RATEMCS3: - ret_rate = MGN_MCS3; - break; - case DESC_RATEMCS4: - ret_rate = MGN_MCS4; - break; - case DESC_RATEMCS5: - ret_rate = MGN_MCS5; - break; - case DESC_RATEMCS6: - ret_rate = MGN_MCS6; - break; - case DESC_RATEMCS7: - ret_rate = MGN_MCS7; - break; - case DESC_RATEMCS8: - ret_rate = MGN_MCS8; - break; - case DESC_RATEMCS9: - ret_rate = MGN_MCS9; - break; - case DESC_RATEMCS10: - ret_rate = MGN_MCS10; - break; - case DESC_RATEMCS11: - ret_rate = MGN_MCS11; - break; - case DESC_RATEMCS12: - ret_rate = MGN_MCS12; - break; - case DESC_RATEMCS13: - ret_rate = MGN_MCS13; - break; - case DESC_RATEMCS14: - ret_rate = MGN_MCS14; - break; - case DESC_RATEMCS15: - ret_rate = MGN_MCS15; - break; - case DESC_RATEMCS16: - ret_rate = MGN_MCS16; - break; - case DESC_RATEMCS17: - ret_rate = MGN_MCS17; - break; - case DESC_RATEMCS18: - ret_rate = MGN_MCS18; - break; - case DESC_RATEMCS19: - ret_rate = MGN_MCS19; - break; - case DESC_RATEMCS20: - ret_rate = MGN_MCS20; - break; - case DESC_RATEMCS21: - ret_rate = MGN_MCS21; - break; - case DESC_RATEMCS22: - ret_rate = MGN_MCS22; - break; - case DESC_RATEMCS23: - ret_rate = MGN_MCS23; - break; - case DESC_RATEMCS24: - ret_rate = MGN_MCS24; - break; - case DESC_RATEMCS25: - ret_rate = MGN_MCS25; - break; - case DESC_RATEMCS26: - ret_rate = MGN_MCS26; - break; - case DESC_RATEMCS27: - ret_rate = MGN_MCS27; - break; - case DESC_RATEMCS28: - ret_rate = MGN_MCS28; - break; - case DESC_RATEMCS29: - ret_rate = MGN_MCS29; - break; - case DESC_RATEMCS30: - ret_rate = MGN_MCS30; - break; - case DESC_RATEMCS31: - ret_rate = MGN_MCS31; - break; - case DESC_RATEVHTSS1MCS0: - ret_rate = MGN_VHT1SS_MCS0; - break; - case DESC_RATEVHTSS1MCS1: - ret_rate = MGN_VHT1SS_MCS1; - break; - case DESC_RATEVHTSS1MCS2: - ret_rate = MGN_VHT1SS_MCS2; - break; - case DESC_RATEVHTSS1MCS3: - ret_rate = MGN_VHT1SS_MCS3; - break; - case DESC_RATEVHTSS1MCS4: - ret_rate = MGN_VHT1SS_MCS4; - break; - case DESC_RATEVHTSS1MCS5: - ret_rate = MGN_VHT1SS_MCS5; - break; - case DESC_RATEVHTSS1MCS6: - ret_rate = MGN_VHT1SS_MCS6; - break; - case DESC_RATEVHTSS1MCS7: - ret_rate = MGN_VHT1SS_MCS7; - break; - case DESC_RATEVHTSS1MCS8: - ret_rate = MGN_VHT1SS_MCS8; - break; - case DESC_RATEVHTSS1MCS9: - ret_rate = MGN_VHT1SS_MCS9; - break; - case DESC_RATEVHTSS2MCS0: - ret_rate = MGN_VHT2SS_MCS0; - break; - case DESC_RATEVHTSS2MCS1: - ret_rate = MGN_VHT2SS_MCS1; - break; - case DESC_RATEVHTSS2MCS2: - ret_rate = MGN_VHT2SS_MCS2; - break; - case DESC_RATEVHTSS2MCS3: - ret_rate = MGN_VHT2SS_MCS3; - break; - case DESC_RATEVHTSS2MCS4: - ret_rate = MGN_VHT2SS_MCS4; - break; - case DESC_RATEVHTSS2MCS5: - ret_rate = MGN_VHT2SS_MCS5; - break; - case DESC_RATEVHTSS2MCS6: - ret_rate = MGN_VHT2SS_MCS6; - break; - case DESC_RATEVHTSS2MCS7: - ret_rate = MGN_VHT2SS_MCS7; - break; - case DESC_RATEVHTSS2MCS8: - ret_rate = MGN_VHT2SS_MCS8; - break; - case DESC_RATEVHTSS2MCS9: - ret_rate = MGN_VHT2SS_MCS9; - break; - case DESC_RATEVHTSS3MCS0: - ret_rate = MGN_VHT3SS_MCS0; - break; - case DESC_RATEVHTSS3MCS1: - ret_rate = MGN_VHT3SS_MCS1; - break; - case DESC_RATEVHTSS3MCS2: - ret_rate = MGN_VHT3SS_MCS2; - break; - case DESC_RATEVHTSS3MCS3: - ret_rate = MGN_VHT3SS_MCS3; - break; - case DESC_RATEVHTSS3MCS4: - ret_rate = MGN_VHT3SS_MCS4; - break; - case DESC_RATEVHTSS3MCS5: - ret_rate = MGN_VHT3SS_MCS5; - break; - case DESC_RATEVHTSS3MCS6: - ret_rate = MGN_VHT3SS_MCS6; - break; - case DESC_RATEVHTSS3MCS7: - ret_rate = MGN_VHT3SS_MCS7; - break; - case DESC_RATEVHTSS3MCS8: - ret_rate = MGN_VHT3SS_MCS8; - break; - case DESC_RATEVHTSS3MCS9: - ret_rate = MGN_VHT3SS_MCS9; - break; - case DESC_RATEVHTSS4MCS0: - ret_rate = MGN_VHT4SS_MCS0; - break; - case DESC_RATEVHTSS4MCS1: - ret_rate = MGN_VHT4SS_MCS1; - break; - case DESC_RATEVHTSS4MCS2: - ret_rate = MGN_VHT4SS_MCS2; - break; - case DESC_RATEVHTSS4MCS3: - ret_rate = MGN_VHT4SS_MCS3; - break; - case DESC_RATEVHTSS4MCS4: - ret_rate = MGN_VHT4SS_MCS4; - break; - case DESC_RATEVHTSS4MCS5: - ret_rate = MGN_VHT4SS_MCS5; - break; - case DESC_RATEVHTSS4MCS6: - ret_rate = MGN_VHT4SS_MCS6; - break; - case DESC_RATEVHTSS4MCS7: - ret_rate = MGN_VHT4SS_MCS7; - break; - case DESC_RATEVHTSS4MCS8: - ret_rate = MGN_VHT4SS_MCS8; - break; - case DESC_RATEVHTSS4MCS9: - ret_rate = MGN_VHT4SS_MCS9; - break; - - default: - RTW_INFO("hw_rate_to_m_rate(): Non supported Rate [%x]!!!\n", rate); - break; - } - - return ret_rate; + return rate; } +#ifdef CONFIG_RTW_DEBUG +void dump_hw_rate_map_test(void *sel) +{ + RATE_SECTION rs; + u8 hw_rate; + enum MGN_RATE m_rate; + int i; + + for (rs = 0; rs < RATE_SECTION_NUM; rs++) { + for (i = 0; i < rates_by_sections[rs].rate_num; i++) { + hw_rate = MRateToHwRate(rates_by_sections[rs].rates[i]); + RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n" + , MGN_RATE_STR(rates_by_sections[rs].rates[i]), rates_by_sections[rs].rates[i] + , HDATA_RATE(hw_rate), hw_rate + ); + } + if (rs == HT_4SS) { /* show MCS32 after MCS31 */ + hw_rate = MRateToHwRate(MGN_MCS32); + RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n" + , MGN_RATE_STR(MGN_MCS32), MGN_MCS32 + , HDATA_RATE(hw_rate), hw_rate + ); + } + } + hw_rate = MRateToHwRate(MGN_UNKNOWN); + RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n" + , MGN_RATE_STR(MGN_UNKNOWN), MGN_UNKNOWN + , HDATA_RATE(hw_rate), hw_rate + ); + + for (i = DESC_RATE1M; i <= DESC_RATE_NUM; i++) { + m_rate = hw_rate_to_m_rate(i); + RTW_PRINT_SEL(sel, "hw_rate:%s(%d) to m_rate:%s(%d)\n" + , HDATA_RATE(i), i + , MGN_RATE_STR(m_rate), m_rate + ); + } +} +#endif /* CONFIG_RTW_DEBUG */ + void HalSetBrateCfg( PADAPTER Adapter, u8 *mBratesOS, @@ -1268,14 +1072,7 @@ void rtw_hal_dump_macaddr(void *sel, _adapter *adapter) #ifdef CONFIG_MI_WITH_MBSSID_CAM rtw_mbid_cam_dump(sel, __func__, adapter); #else - for (i = 0; i < dvobj->iface_nums; i++) { - iface = dvobj->padapters[i]; - if (iface) { - rtw_hal_get_hwreg(iface, HW_VAR_MAC_ADDR, mac_addr); - RTW_PRINT_SEL(sel, ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", - ADPT_ARG(iface), iface->hw_port, MAC_ARG(mac_addr)); - } - } + rtw_mi_hal_dump_macaddr(sel, adapter); #endif } @@ -1343,7 +1140,7 @@ void rtw_mi_set_mac_addr(_adapter *adapter) rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface)); } #endif - if (1) + if (0) rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter); } @@ -1526,6 +1323,26 @@ int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms) return rtw_sctx_wait(iqk_sctx, __func__); } +#ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX +void c2h_txpwr_idx_offload_done(_adapter *adapter, u8 *data, u8 len) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx; + + if (0) + RTW_INFO("txpwr_idx offload finish in %dms\n", rtw_get_passing_time_ms(sctx->submit_time)); + rtw_sctx_done(&sctx); +} + +int c2h_txpwr_idx_offload_wait(_adapter *adapter) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx; + + return rtw_sctx_wait(sctx, __func__); +} +#endif + #define GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8) #define GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8) #define GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5) @@ -1550,6 +1367,7 @@ int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len) HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); enum rf_type rf_type; + u8 tx_path_num, rx_path_num; int ret = _FAIL; u8 uuid_x; @@ -1625,6 +1443,8 @@ int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len) #if defined(CONFIG_RTL8822C) if (IS_8822C_SERIES(hal_data->version_id)) { + if (ant_num == 1) + hal_spec->rf_reg_trx_path_bmp = 0x22; /* 1T1R pathB */ if (hw_stype == 0xE) hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, 1); /* limit 1TX only */ } @@ -1634,24 +1454,34 @@ int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len) hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func); hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw); hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol); - hal_spec->rf_reg_path_num = rtw_min(hal_spec->rf_reg_path_num, ant_num); - rf_type = rtw_chip_rftype_to_hal_rftype(adapter, hal_spec->rf_reg_path_num); + rf_type = rtw_chip_rftype_to_hal_rftype(adapter, 0); if (!RF_TYPE_VALID(rf_type)) { RTW_ERR("%s rtw_chip_rftype_to_hal_rftype failed\n", __func__); goto exit; } + hal_spec->rf_reg_path_avail_num = rtw_min(hal_spec->rf_reg_path_num, ant_num); + tx_path_num = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->rf_reg_path_avail_num); + rx_path_num = rtw_min(rf_type_to_rf_rx_cnt(rf_type), hal_spec->rf_reg_path_avail_num); + hal_spec->rf_reg_trx_path_bmp = rtw_restrict_trx_path_bmp_by_trx_num_lmt( + hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num, &tx_path_num, &rx_path_num); + if (!hal_spec->rf_reg_trx_path_bmp) { + RTW_ERR("%s rtw_restrict_trx_path_bmp_by_trx_num_lmt(0x%x, %u, %u) failed\n" + , __func__, hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num); + goto exit; + } + hal_spec->rf_reg_path_avail_num = rtw_max(tx_path_num, rx_path_num); /* * RF TX path num >= max_tx_cnt >= tx_nss_num * ex: RF TX path num(4) >= max_tx_cnt(2) >= tx_nss_num(1) * Select at most 2 out of 4 TX RF path to do 1SS 2TX */ - hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, rf_type_to_rf_tx_cnt(rf_type)); + hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, tx_path_num); hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, hal_spec->max_tx_cnt); hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ss_num); - hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, rf_type_to_rf_rx_cnt(rf_type)); + hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, rx_path_num); hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ss_num); ret = _SUCCESS; @@ -2145,8 +1975,12 @@ int c2h_lps_status_rpt(PADAPTER adapter, u8 *data, u8 len) status_code = GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(data); /* action=0: report force leave null data status */ + /* action=1: report Rf on status when receiving a SetPwrMode H2C with PwrState = RFON */ switch (action) { - case 0: + case 0: + /* status code 0: success, 1: no ack, 2: timeout, 3: cancel */ + case 1: + /* status code 0: FW has already turn to RFON */ pwrpriv->lps_ack_status = status_code; if (DBG_LPS_STATUS_RPT) @@ -2176,10 +2010,10 @@ void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta) if ((psta->wireless_mode & WIRELESS_11G) || (psta->wireless_mode & WIRELESS_11A)) w_set |= WIRELESS_OFDM; - if (psta->wireless_mode & WIRELESS_11_24N) + if ((psta->wireless_mode & WIRELESS_11_24N) || (psta->wireless_mode & WIRELESS_11_5N)) w_set |= WIRELESS_HT; - if ((psta->wireless_mode & WIRELESS_11AC) || (psta->wireless_mode & WIRELESS_11_5N)) + if (psta->wireless_mode & WIRELESS_11AC) w_set |= WIRELESS_VHT; psta->cmn.support_wireless_set = w_set; @@ -3258,8 +3092,12 @@ void rtw_ap_multi_bcn_cfg(_adapter *adapter) rtw_write8(adapter, REG_ATIMWND, 0x0c); /* 12ms */ #ifndef CONFIG_HW_P0_TSF_SYNC + #ifdef CONFIG_RTL8192F + rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x640);/*unit:32us*/ + #else/*not CONFIG_RTL8192F*/ rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */ #endif + #endif /*reset TSF*/ rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0)); @@ -3412,7 +3250,6 @@ static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *mac_addr) } #endif /* !RTW_HALMAC */ } -#endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/ static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr) { @@ -3435,9 +3272,10 @@ static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr) } #endif /* !RTW_HALMAC */ - RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__, + RTW_DBG("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__, ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr)); } +#endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/ #ifndef RTW_HALMAC static u32 _get_bssid_reg(enum _hw_port hw_port) @@ -3478,6 +3316,7 @@ static void rtw_hal_set_bssid(_adapter *adapter, u8 *val) __func__, ADPT_ARG(adapter), hw_port, MAC_ARG(val)); } +#ifndef CONFIG_MI_WITH_MBSSID_CAM static void rtw_hal_set_tsf_update(_adapter *adapter, u8 en) { u32 addr = 0; @@ -3506,7 +3345,7 @@ static void rtw_hal_set_tsf_update(_adapter *adapter, u8 en) rtw_warn_on(1); } } - +#endif /*CONFIG_MI_WITH_MBSSID_CAM*/ static void rtw_hal_set_hw_update_tsf(PADAPTER padapter) { #ifdef CONFIG_MI_WITH_MBSSID_CAM @@ -3845,6 +3684,15 @@ void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action) #endif #endif /* CONFIG_MI_WITH_MBSSID_CAM */ +#ifdef CONFIG_RTW_MULTI_AP + if (MSTATE_AP_NUM(&mstate) + && rtw_unassoc_sta_src_chk(adapter, UNASOC_STA_SRC_RX_NMY_UC) + ) { + rcr_new |= RCR_AAP; + } else + rcr_new &= ~RCR_AAP; +#endif + if (rcr == rcr_new) return; @@ -3860,6 +3708,11 @@ void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action) rtw_hal_tsf_update_restore(adapter); } +void rtw_hal_rcr_set_chk_bssid_act_non(_adapter *adapter) +{ + rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE); +} + static void hw_var_set_rcr_am(_adapter *adapter, u8 enable) { u32 rcr = RCR_AM; @@ -4044,9 +3897,6 @@ void rtw_hal_set_tx_aclt_conf(_adapter *adapter, u8 conf_idx, struct tx_aclt_con void rtw_hal_update_tx_aclt(_adapter *adapter) { -#ifdef CONFIG_TX_MCAST2UNI - extern int rtw_mc2u_disable; -#endif struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct macid_ctl_t *macid_ctl = adapter_to_macidctl(adapter); u8 lt_en = 0, lt_en_ori; @@ -4054,6 +3904,24 @@ void rtw_hal_update_tx_aclt(_adapter *adapter) u32 lt, lt_ori; struct tx_aclt_conf_t *conf; int i; +#ifdef CONFIG_AP_MODE +#if CONFIG_RTW_AP_DATA_BMC_TO_UC + _adapter *iface; + u8 ap_m2u_num = 0; + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (!iface) + continue; + + if (MLME_IS_AP(iface) + && ((iface->b2u_flags_ap_src & RTW_AP_B2U_IP_MCAST) + || (iface->b2u_flags_ap_fwd & RTW_AP_B2U_IP_MCAST)) + ) + ap_m2u_num++; + } +#endif +#endif /* CONFIG_AP_MODE */ lt_en_ori = rtw_read8(adapter, REG_LIFETIME_EN); lt_ori = rtw_read32(adapter, REG_PKT_LIFE_TIME); @@ -4072,11 +3940,12 @@ void rtw_hal_update_tx_aclt(_adapter *adapter) if (conf->be_bk) lt_be_bk = conf->be_bk; } - #if defined(CONFIG_TX_MCAST2UNI) || defined(CONFIG_RTW_MESH) + #ifdef CONFIG_AP_MODE + #if CONFIG_RTW_AP_DATA_BMC_TO_UC || defined(CONFIG_RTW_MESH) else if (0 - #ifdef CONFIG_TX_MCAST2UNI + #if CONFIG_RTW_AP_DATA_BMC_TO_UC || (i == TX_ACLT_CONF_AP_M2U - && !rtw_mc2u_disable + && ap_m2u_num && macid_ctl->op_num[H2C_MSR_ROLE_STA] /* having AP mode with STA connected */) #endif #ifdef CONFIG_RTW_MESH @@ -4092,6 +3961,7 @@ void rtw_hal_update_tx_aclt(_adapter *adapter) lt_be_bk = conf->be_bk; } #endif + #endif /* CONFIG_AP_MODE */ } if (dvobj->tx_aclt_force_val.en != 0xFF) @@ -4443,7 +4313,7 @@ _adapter * _rtw_search_dp_iface(_adapter *adapter) iface = dvobj->padapters[i]; if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) { - if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) { + if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) { sta_ifs[sta_num++] = iface; #ifdef CONFIG_TDLS @@ -4457,7 +4327,7 @@ _adapter * _rtw_search_dp_iface(_adapter *adapter) } #ifdef CONFIG_AP_MODE } else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) { - if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) { + if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) { ap_ifs[ap_num++] = iface; #ifdef CONFIG_P2P if (MLME_IS_GO(iface)) @@ -4466,13 +4336,13 @@ _adapter * _rtw_search_dp_iface(_adapter *adapter) } #endif } else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE - && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE + && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE ) { adhoc_num++; #ifdef CONFIG_RTW_MESH } else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE - && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE + && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE ) { mesh_ifs[mesh_num++] = iface; #endif @@ -4675,6 +4545,49 @@ void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state) #endif /* RTW_HALMAC */ #endif /* CONFIG_P2P */ +#if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR) +static void _rtw_hal_dtp_macid_set( + _adapter *padapter, u8 opmode, u8 mac_id) +{ + struct macid_ctl_t *macid_ctl = &(padapter->dvobj->macid_ctl); + struct sta_info *psta; + u8 h2c_cmd[H2C_FW_CRC5_SEARCH_LEN] = {0}; + u8 mac_addr[ETH_ALEN] = {0}; + + if (opmode) { + psta = macid_ctl->sta[mac_id]; + if (psta) + _rtw_memcpy(mac_addr, psta->cmn.mac_addr, ETH_ALEN); + + if (rtw_check_invalid_mac_address(mac_addr, _FALSE)) + return; + } + /* else DON'T CARE H2C_FW_CRC5_SEARCH mac addr in disconnected case */ + + if (rtw_get_chip_type(padapter) == RTL8822C) { + SET_H2CCMD_FW_CRC5_SEARCH_EN(h2c_cmd, opmode); + SET_H2CCMD_FW_CRC5_SEARCH_MACID(h2c_cmd, mac_id); + SET_H2CCMD_FW_CRC5_SEARCH_MAC(&h2c_cmd[1], mac_addr); + if (rtw_hal_fill_h2c_cmd(padapter, H2C_FW_CRC5_SEARCH, + H2C_FW_CRC5_SEARCH_LEN, h2c_cmd) != _SUCCESS) + RTW_WARN("%s : set h2c - 0x%02x fail!\n", __func__, H2C_FW_CRC5_SEARCH); + } +} + +static void rtw_hal_dtp_macid_set(_adapter *padapter, u8 opmode, + bool macid_ind, u8 mac_id, u8 macid_end) +{ + int i; + + if (macid_ind == 0) { + _rtw_hal_dtp_macid_set(padapter, opmode, mac_id); + } else { + for (i = mac_id; i <= macid_end; i++) + _rtw_hal_dtp_macid_set(padapter, opmode, i); + } +} +#endif + /* * rtw_hal_set_FwMediaStatusRpt_cmd - * @@ -4698,6 +4611,10 @@ s32 rtw_hal_set_FwMediaStatusRpt_cmd(_adapter *adapter, bool opmode, bool miraca #endif u8 op_num_change_bmp = 0; +#if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR) + rtw_hal_dtp_macid_set(adapter, opmode, macid_ind, macid, macid_end); +#endif + SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode); SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind); SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast); @@ -4833,7 +4750,7 @@ void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable) void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval) { #if defined(CONFIG_RTL8192F) - rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&index)); + rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&outputval)); #else if (index <= 7) { /* config GPIO mode */ @@ -4942,7 +4859,7 @@ void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc __func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo, rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList); - if (check_fwstate(pmlmepriv, _FW_LINKED)) { + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) { SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo); SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp); SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm, @@ -5073,6 +4990,7 @@ int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset, void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num) { +#if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG) u32 page_size = 0; u8 *buffer = NULL; u32 buf_size = 0; @@ -5098,6 +5016,7 @@ void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_nu RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n"); RTW_PRINT_SEL(sel, "==========================\n"); +#endif } #ifdef CONFIG_SUPPORT_FIFO_DUMP @@ -5671,13 +5590,37 @@ static void rtw_hal_update_sw_security_info(_adapter *adapter) rtw_hal_update_tx_iv(adapter); #ifdef CONFIG_GTK_OL if (psecpriv->binstallKCK_KEK == _TRUE && - psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) + (psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))) rtw_hal_update_gtk_offload_info(adapter); #else _rtw_memset(psecpriv->iv_seq, 0, sz); #endif } +#ifdef CONFIG_CUSTOM_PULSE +static u8 rtw_hal_set_gpio_custom_cmd(_adapter *adapter, u8 enable) +{ + u8 H2CGpioCustomParm[H2C_GPIO_CUSTOM_LEN] = {0}; + u8 customid = 0x2, special_wakeup_reason = RX_MAGIC_PKT, custom_for_wakeup_reason=0x1; + u8 ret = _FAIL; + RTW_INFO("%s(): enable = %d\n", __func__, enable); + + if(enable) { + SET_H2CCMD_CUSTOMERID(H2CGpioCustomParm, customid); + SET_H2CCMD_SPECIAL_WAKE_REASON(H2CGpioCustomParm, special_wakeup_reason); + SET_H2CCMD_CUSTOM_WAKE_REASON(H2CGpioCustomParm, custom_for_wakeup_reason); + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_GPIO_CUSTOM, + H2C_GPIO_CUSTOM_LEN, + H2CGpioCustomParm); + RTW_DBG("%s(): H2C_cmd=%x, cmd=%02x, %02x, %02x\n", __func__, H2C_GPIO_CUSTOM, + H2CGpioCustomParm[0], H2CGpioCustomParm[1], H2CGpioCustomParm[2]); + } + + return ret; +} +#endif /* CONFIG_CUSTOM_PULSE */ static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type) { u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0}; @@ -5703,16 +5646,78 @@ static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type) return ret; } +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +static u8 rtw_hal_set_keep_alive_pattern_cmd(PADAPTER adapter, u8 enable) +{ + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter); + u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_PATTERN_LEN] = {0}; + u8 ret = _FAIL; + int i; + + /* If keep alive pattern is set, FW will use pattern for keep alive action */ + if(enable == 0 || (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_disable)) { + SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _FALSE); + SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _FALSE); + SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE); + return ret; + } + /*step1:set keep alive period*/ + SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_LOW_BIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_period & 0x00FF); + SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_HI_BIT(u1H2CKeepAliveParm, ((pwrctl->wowlan_keep_alive_period & 0xFF00)>> 8)); + + if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_tx) { + SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE); + SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _FALSE); + SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE); + SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc); + goto exit; + } + if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_trx) { + SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE); + SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _TRUE); + SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE); + SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc); + SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_ack_index); + SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_interval); + SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_counter); + goto exit; + } + if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_trx_with_ack) { + SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE); + SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _TRUE); + SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _TRUE); + SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc); + SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_ack_index); + SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_wake_pattern_index); + SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_interval); + SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_counter); + goto exit; + } +exit: + for(i=0; iregistrypriv; u8 hw_port = rtw_hal_get_port(adapter); SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable); SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt); - /* SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt); */ + if (!(pregistry->wakeup_event & BIT(2))) + SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt); SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period); SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num); #ifdef CONFIG_FW_MULTI_PORT_SUPPORT @@ -5750,23 +5755,18 @@ static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_un #ifdef CONFIG_GPIO_WAKEUP gpio_high_active = ppwrpriv->is_high_active; - gpionum = WAKEUP_GPIO_IDX; + gpionum = ppwrpriv->wowlan_gpio_index; sdio_wakeup_enable = 0; #endif /* CONFIG_GPIO_WAKEUP */ if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && - !check_fwstate(pmlmepriv, _FW_LINKED)) + !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) no_wake = 1; if (!ppwrpriv->wowlan_pno_enable && registry_par->wakeup_event & BIT(0) && !no_wake) magic_pkt = enable; - if ((registry_par->wakeup_event & BIT(1)) && - (psecpriv->dot11PrivacyAlgrthm == _WEP40_ || - psecpriv->dot11PrivacyAlgrthm == _WEP104_) && !no_wake) - hw_unicast = 1; - if (registry_par->wakeup_event & BIT(2) && !no_wake) discont_wake = enable; @@ -5797,7 +5797,7 @@ static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_un #ifdef CONFIG_GTK_OL if (psecpriv->binstallKCK_KEK == _TRUE && - psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) + (psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))) SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0); else SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1); @@ -5854,6 +5854,7 @@ static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable) struct security_priv *psecuritypriv = &(adapter->securitypriv); struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter); struct registry_priv *pregistrypriv = &adapter->registrypriv; + u8 arp_en = pregistrypriv->wakeup_event & BIT(3); u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0}; u8 ret = _FAIL, count = 0, no_wake = 0; struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); @@ -5861,7 +5862,7 @@ static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable) RTW_INFO("%s(): enable=%d\n", __func__, enable); if(pregistrypriv->suspend_type == FW_IPS_DISABLE_BBRF && - !check_fwstate(pmlmepriv, _FW_LINKED)) + !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) no_wake = 1; if(no_wake) { SET_H2CCMD_REMOTE_WAKECTRL_ENABLE( @@ -5870,11 +5871,15 @@ static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable) if (!ppwrpriv->wowlan_pno_enable) { SET_H2CCMD_REMOTE_WAKECTRL_ENABLE( u1H2CRemoteWakeCtrlParm, enable); - SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN( - u1H2CRemoteWakeCtrlParm, 1); + if (arp_en) + SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN( + u1H2CRemoteWakeCtrlParm, 1); + else + SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN( + u1H2CRemoteWakeCtrlParm, 0); #ifdef CONFIG_GTK_OL if (psecuritypriv->binstallKCK_KEK == _TRUE && - psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) { + (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))) { SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN( u1H2CRemoteWakeCtrlParm, 1); } else { @@ -5913,22 +5918,25 @@ static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable) (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) { SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION( u1H2CRemoteWakeCtrlParm, 0); - } else { - SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION( - u1H2CRemoteWakeCtrlParm, 1); + } else { /* WEP etc. */ + if (arp_en) + SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION( + u1H2CRemoteWakeCtrlParm, 1); } - if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_ && - psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) { - SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN( + if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) { +#ifdef CONFIG_GTK_OL + if(_rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)) + SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN( u1H2CRemoteWakeCtrlParm, enable); - +#endif /* CONFIG_GTK_OL */ if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) { SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN( u1H2CRemoteWakeCtrlParm, 0); - SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION( - u1H2CRemoteWakeCtrlParm, 1); + if (arp_en) + SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION( + u1H2CRemoteWakeCtrlParm, 1); } } @@ -5963,6 +5971,67 @@ static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable) return ret; } +#ifdef CONFIG_WAR_OFFLOAD +static u8 rtw_hal_set_war_offload_ctrl_cmd(_adapter *adapter, u8 enable) +{ + struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter); + u8 u1H2CWarOffloadParm[H2C_WAR_OFFLOAD_LEN] = {0}; + u8 ret = _FAIL; + + RTW_INFO("%s(): enable=%d\n", __func__, enable); + + if (_TRUE == ppwrpriv->wowlan_war_offload_mode) { + SET_H2CCMD_WAR_CFG_EN(u1H2CWarOffloadParm, enable); + SET_H2CCMD_WAR_CFG_ARP_RSP_EN(u1H2CWarOffloadParm, 1); + +#ifdef CONFIG_OFFLOAD_MDNS_V4 + if (WAR_MDNS_V4_RSP_EN & ppwrpriv->wowlan_war_offload_ctrl) { + SET_H2CCMD_WAR_CFG_MDNSV4_RSP_EN(u1H2CWarOffloadParm, 1); + } + if (WAR_MDNS_V4_WAKEUP_EN& ppwrpriv->wowlan_war_offload_ctrl) { + SET_H2CCMD_WAR_CFG_MDNSV4_WAKE_EN(u1H2CWarOffloadParm, 1); + } +#endif /* CONFIG_OFFLOAD_MDNS_V4 */ + +#ifdef CONFIG_OFFLOAD_MDNS_V6 + if (WAR_MDNS_V6_RSP_EN & ppwrpriv->wowlan_war_offload_ctrl) { + SET_H2CCMD_WAR_CFG_MDNSV6_RSP_EN(u1H2CWarOffloadParm, 1); + } + if (WAR_MDNS_V6_WAKEUP_EN & ppwrpriv->wowlan_war_offload_ctrl) { + SET_H2CCMD_WAR_CFG_MDNSV6_WAKE_EN(u1H2CWarOffloadParm, 1); + } +#endif /* CONFIG_OFFLOAD_MDNS_V6 */ + + } + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_WAR_OFFLOAD, + H2C_WAR_OFFLOAD_LEN, + u1H2CWarOffloadParm); + return ret; +} + +static u8 rtw_hal_set_war_offload_parm(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc) +{ + struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter); + u8 u1H2CWarOfldParm[H2C_WAROFLD_RSVDPAGE1_LEN] = {0}; + u8 ret = _FAIL; + + SET_H2CCMD_WAROFLD_RSVDPAGE1_LOC_PARM(u1H2CWarOfldParm, rsvdpageloc->LocIpParm); + RTW_INFO("%s(): LocIpParm = %d\n", __func__, rsvdpageloc->LocIpParm); + + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_WAROFLD_RSVDPAGE1, + H2C_WAROFLD_RSVDPAGE1_LEN, + u1H2CWarOfldParm); + + return ret; +} +#endif /* CONFIG_WAR_OFFLOAD */ + + + static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg) { u8 ret = _FAIL; @@ -6022,7 +6091,7 @@ void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable) u8 pkt_type = 0, no_wake = 0; if(pregistry->suspend_type == FW_IPS_DISABLE_BBRF && - !check_fwstate(pmlmepriv, _FW_LINKED)) + !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) no_wake = 1; RTW_PRINT("+%s()+: enable=%d\n", __func__, enable); @@ -6036,7 +6105,7 @@ void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable) psecpriv->dot11PrivacyAlgrthm); if (!(ppwrpriv->wowlan_pno_enable)) { - if (pregistry->wakeup_event & BIT(2) && !no_wake) + if (!no_wake) rtw_hal_set_disconnect_decision_cmd(padapter, enable); #ifdef CONFIG_ARP_KEEP_ALIVE @@ -6048,13 +6117,20 @@ void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable) #else pkt_type = 0; #endif /* CONFIG_ARP_KEEP_ALIVE */ - if(!no_wake) + if(!no_wake) { + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + rtw_hal_set_keep_alive_pattern_cmd(padapter,enable); + #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type); + } } - rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable); #ifdef CONFIG_PNO_SUPPORT rtw_hal_check_pno_enabled(padapter); #endif /* CONFIG_PNO_SUPPORT */ +#ifdef CONFIG_WAR_OFFLOAD + rtw_hal_set_war_offload_ctrl_cmd(padapter, enable); +#endif /* CONFIG_WAR_OFFLOAD */ + } else { #if 0 { @@ -6063,9 +6139,11 @@ void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable) dump_TX_FIFO(padapter, 4, PageSize); } #endif - - rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable); } +#ifdef CONFIG_CUSTOM_PULSE + rtw_hal_set_gpio_custom_cmd(padapter, enable); +#endif /* CONFIG_CUSTOM_PULSE */ + rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable); RTW_PRINT("-%s()-\n", __func__); } #endif /* CONFIG_WOWLAN */ @@ -6084,7 +6162,7 @@ static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable) #ifdef CONFIG_GPIO_WAKEUP gpio_high_active = ppwrpriv->is_high_active; - gpionum = WAKEUP_GPIO_IDX; + gpionum = ppwrpriv->wowlan_gpio_index; sdio_wakeup_enable = 0; #endif /*CONFIG_GPIO_WAKEUP*/ @@ -6205,6 +6283,7 @@ static void rtw_hal_ap_wow_enable(_adapter *padapter) { struct security_priv *psecuritypriv = &padapter->securitypriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); struct sta_info *psta = NULL; PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); #ifdef DBG_CHECK_FW_PS_STATE @@ -6213,6 +6292,9 @@ static void rtw_hal_ap_wow_enable(_adapter *padapter) #endif /*DBG_CHECK_FW_PS_STATE*/ int res; u16 media_status_rpt; +#ifdef CONFIG_GPIO_WAKEUP + u8 val8 = 0; +#endif RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__); #ifdef DBG_CHECK_FW_PS_STATE @@ -6249,8 +6331,28 @@ static void rtw_hal_ap_wow_enable(_adapter *padapter) #endif #ifdef CONFIG_GPIO_WAKEUP - rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE); -#endif +#ifdef CONFIG_RTW_ONE_PIN_GPIO + rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE); + rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index); +#else +#ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE + if (pwrctrlpriv->is_high_active == 0) + rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index); + else + rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, + GPIO_OUTPUT_LOW); +#else + val8 = (pwrpriv->is_high_active == 0) ? 1 : 0; + rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, val8); + rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE); + RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow suspend and %s_ACTIVE.\n", + __func__, pwrpriv->wowlan_gpio_index, + pwrpriv->wowlan_gpio_output_state ? "HIGH" : "LOW", + pwrpriv->is_high_active ? "HIGI" : "LOW"); +#endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */ +#endif /* CONFIG_RTW_ONE_PIN_GPIO */ +#endif /* CONFIG_GPIO_WAKEUP */ + /* 5. Set Enable WOWLAN H2C command. */ RTW_PRINT("Set Enable AP WOWLan cmd\n"); rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1); @@ -6276,7 +6378,6 @@ static void rtw_hal_ap_wow_disable(_adapter *padapter) struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; #endif /*DBG_CHECK_FW_PS_STATE*/ u16 media_status_rpt; - u8 val8; RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__); /* 1. Read wakeup reason*/ @@ -6306,22 +6407,24 @@ static void rtw_hal_ap_wow_disable(_adapter *padapter) #ifdef CONFIG_GPIO_WAKEUP #ifdef CONFIG_RTW_ONE_PIN_GPIO - rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX); + rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index); #else - #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE +#ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE if (pwrctl->is_high_active == 0) - rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX); + rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index); else - rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, 0); - #else - val8 = (pwrctl->is_high_active == 0) ? 1 : 0; - RTW_PRINT("Set Wake GPIO to default(%d).\n", val8); - rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8); - - rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _FALSE); - #endif/*CONFIG_WAKEUP_GPIO_INPUT_MODE*/ + rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index + , GPIO_OUTPUT_LOW); +#else + rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index, + pwrctl->wowlan_gpio_output_state); + RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow resume and %s_ACTIVE.\n", + __func__, pwrctl->wowlan_gpio_index, + pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW", + pwrctl->is_high_active ? "HIGI" : "LOW"); +#endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/ #endif /* CONFIG_RTW_ONE_PIN_GPIO */ -#endif +#endif /* CONFIG_GPIO_WAKEUP */ media_status_rpt = RT_MEDIA_CONNECT; rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, @@ -7180,7 +7283,7 @@ static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pL + get_reg_classes_full_count(ch_list); #ifdef CONFIG_CONCURRENT_MODE - if (rtw_mi_buddy_check_fwstate(padapter, _FW_LINKED)) + if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE)) *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1); else *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr); @@ -8225,6 +8328,116 @@ static void rtw_hal_construct_ARPRsp( *pLength += 8; } } +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +/* + * Description: + * Construct the Keep Alive packet to support specific Keep Alive packet. + * */ +static void rtw_hal_construct_keepalive( PADAPTER padapter, + u8 *pframe, + u32 *pLength +){ + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + u32 pktlen; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + static u8 LLCHeader[6] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; + u8 *pKeepAlivePkt = pframe; + /* for TKIP Cal MIC */ + u8 *payload = pframe; + u8 EncryptionHeadOverhead = 0, frame_offset = 0; + int i; + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &pwlanhdr->frame_ctl; + *(fctrl) = 0; + + RTW_INFO("%s======>\n", __func__); + + + /* ------------------------------------------------------------------------- */ + /* MAC Header. */ + /* ------------------------------------------------------------------------- */ + SetFrameType(fctrl, WIFI_DATA); + /* set_frame_sub_type(fctrl, 0); */ + SetToDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pwrpriv->keep_alive_pattern+6, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3,pwrpriv->keep_alive_pattern, ETH_ALEN); + + SetSeqNum(pwlanhdr, 0); + set_duration(pwlanhdr, 0); + +#ifdef CONFIG_WAPI_SUPPORT + *pLength = sMacHdrLng; +#else + *pLength = 24; +#endif + switch (psecuritypriv->dot11PrivacyAlgrthm) { + case _WEP40_: + case _WEP104_: + EncryptionHeadOverhead = 4; + break; + case _TKIP_: + EncryptionHeadOverhead = 8; + break; + case _AES_: + EncryptionHeadOverhead = 8; + break; +#ifdef CONFIG_WAPI_SUPPORT + case _SMS4_: + EncryptionHeadOverhead = 18; + break; +#endif + default: + EncryptionHeadOverhead = 0; + } + + if (EncryptionHeadOverhead > 0) { + _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead); + *pLength += EncryptionHeadOverhead; + /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */ + SetPrivacy(fctrl); + } + + /* ------------------------------------------------------------------------- */ + /* Frame Body. */ + /* ------------------------------------------------------------------------- */ + frame_offset = *pLength; + pKeepAlivePkt = (u8 *)(pframe + frame_offset); + payload = pKeepAlivePkt; /* Get Payload pointer */ + /* LLC header */ + _rtw_memcpy(pKeepAlivePkt, LLCHeader, 6); + *pLength += 6; + + /*From protocol type*/ + pKeepAlivePkt+=6; + + _rtw_memcpy(pKeepAlivePkt,pwrpriv->keep_alive_pattern+12,pwrpriv->keep_alive_pattern_len-12); + + *pLength+=pwrpriv->keep_alive_pattern_len-12; + + if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) { + *pLength += 8; + } + + /* for debug + for (i=0; i< (*pLength) ;i++) { + RTW_INFO("KA_Pkt[0x%x]=x%0x", i,pKeepAlivePkt[i]); + if((i%8) == 7) + RTW_INFO("\n"); + } + */ + + RTW_INFO("%s <======\n", __func__); +} + +#endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ #ifdef CONFIG_IPV6 /* @@ -8582,6 +8795,270 @@ static void rtw_hal_construct_scan_info(_adapter *padapter, } #endif /* CONFIG_PNO_SUPPORT */ +#ifdef CONFIG_WAR_OFFLOAD +#ifdef CONFIG_OFFLOAD_MDNS_V4 + +/* + * Description: + * Construct the MDNS V4 response packet to support MDNS offload. + * + */ +static void rtw_hal_construct_mdns_rsp_v4( + PADAPTER padapter, + u8 *pframe, + u32 *pLength, + u8 *pIPAddress +) +{ + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + u32 pktlen; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *cur_network = &pmlmepriv->cur_network; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct security_priv *psecuritypriv = &padapter->securitypriv; + static u8 ICMPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00}; + u8 mulicast_ipv4_addr[4] = {0xe0, 0x00, 0x00, 0xfb}; + u8 mulicast_mac_addr_for_mdns[6] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb}; + u8 *pMdnsRspPkt = pframe; + /* for TKIP Cal MIC */ + u8 EncryptionHeadOverhead = 0, mdns_offset = 0; + + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &pwlanhdr->frame_ctl; + *(fctrl) = 0; + + /* ------------------------------------------------------------------------- */ + /* MAC Header. */ + /* ------------------------------------------------------------------------- */ + SetFrameType(fctrl, WIFI_DATA); + /* set_frame_sub_type(fctrl, 0); */ + SetToDs(fctrl); + //_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, mulicast_mac_addr_for_mdns, ETH_ALEN ); + + SetSeqNum(pwlanhdr, 0); + set_duration(pwlanhdr, 0); + +#ifdef CONFIG_WAPI_SUPPORT + *pLength = sMacHdrLng; +#else + *pLength = 24; +#endif + switch (psecuritypriv->dot11PrivacyAlgrthm) { + case _WEP40_: + case _WEP104_: + EncryptionHeadOverhead = 4; + break; + case _TKIP_: + EncryptionHeadOverhead = 8; + break; + case _AES_: + EncryptionHeadOverhead = 8; + break; +#ifdef CONFIG_WAPI_SUPPORT + case _SMS4_: + EncryptionHeadOverhead = 18; + break; +#endif + default: + EncryptionHeadOverhead = 0; + } + + if (EncryptionHeadOverhead > 0) { + _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead); + *pLength += EncryptionHeadOverhead; + /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */ + SetPrivacy(fctrl); + } + + /* ------------------------------------------------------------------------- */ + /* Frame Body. */ + /* ------------------------------------------------------------------------- */ + mdns_offset = *pLength; + pMdnsRspPkt = (u8 *)(pframe + mdns_offset); + /* LLC header */ + _rtw_memcpy(pMdnsRspPkt, ICMPLLCHeader, 8); + *pLength += 8; + + /* IP element */ + pMdnsRspPkt += 8; + SET_IPHDR_VERSION(pMdnsRspPkt, 0x45); + SET_IPHDR_DSCP(pMdnsRspPkt, 0); + SET_IPHDR_TOTAL_LEN(pMdnsRspPkt, 0); // filled by fw + SET_IPHDR_IDENTIFIER(pMdnsRspPkt, 0); // filled by fw + SET_IPHDR_FLAGS(pMdnsRspPkt, 0x40); + SET_IPHDR_FRAG_OFFSET(pMdnsRspPkt, 0); + SET_IPHDR_TTL(pMdnsRspPkt, 0x40); + SET_IPHDR_PROTOCOL(pMdnsRspPkt, 0x11); // ICMP-UDP + SET_IPHDR_HDR_CHECKSUM(pMdnsRspPkt, 0); // filled by fw + SET_IPHDR_SRC_IP_ADDR(pMdnsRspPkt, pIPAddress); + SET_IPHDR_DST_IP_ADDR(pMdnsRspPkt, mulicast_ipv4_addr); // filled by fw + + *pLength += 20; + + if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) { + if (IS_HARDWARE_TYPE_8188E(padapter) || + IS_HARDWARE_TYPE_8812(padapter)) { + rtw_hal_append_tkip_mic(padapter, pframe, mdns_offset); + } + *pLength += 8; + } + + /* UDP element */ + pMdnsRspPkt += 20; + SET_UDP_SRC_PORT(pMdnsRspPkt, 0xe914); // MDNS + SET_UDP_DST_PORT(pMdnsRspPkt, 0xe914); // MDNS + SET_UDP_LEN(pMdnsRspPkt, 0); // filled by fw + SET_UDP_CHECKSUM(pMdnsRspPkt, 0); // filled by fw + *pLength += 8; + + /* MDNS Header */ + pMdnsRspPkt += 8; + SET_MDNS_HDR_FLAG(pMdnsRspPkt, 0x84); + *pLength += 12; + +} + +#endif /* CONFIG_OFFLOAD_MDNS_V4 */ + +#ifdef CONFIG_OFFLOAD_MDNS_V6 + +/* + * Description: + * Construct the MDNS response V6 packet to support MDNS offload. + * + */ +static void rtw_hal_construct_mdns_rsp_v6( + PADAPTER padapter, + u8 *pframe, + u32 *pLength, + u8 *pIPAddress +) +{ + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + u32 pktlen; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *cur_network = &pmlmepriv->cur_network; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct security_priv *psecuritypriv = &padapter->securitypriv; + static u8 ICMPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD}; + u8 mulicast_ipv6_addr[16] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb}; + u8 mulicast_mac_addr_for_mdns[6] = {0x33, 0x33, 0x00, 0x00, 0x00, 0xfb}; /* could be revise by fw */ + u8 *pMdnsRspPkt = pframe; + /* for TKIP Cal MIC */ + u8 EncryptionHeadOverhead = 0, mdns_offset = 0; + /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */ + + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &pwlanhdr->frame_ctl; + *(fctrl) = 0; + + /* ------------------------------------------------------------------------- */ + /* MAC Header. */ + /* ------------------------------------------------------------------------- */ + SetFrameType(fctrl, WIFI_DATA); + /* set_frame_sub_type(fctrl, 0); */ + SetToDs(fctrl); + //_rtw_memcpy(pwlanhdr->addr1, mulicast_mac_addr_for_mdns, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + //_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, mulicast_mac_addr_for_mdns, ETH_ALEN); + + SetSeqNum(pwlanhdr, 0); + set_duration(pwlanhdr, 0); + +#ifdef CONFIG_WAPI_SUPPORT + *pLength = sMacHdrLng; +#else + *pLength = 24; +#endif + switch (psecuritypriv->dot11PrivacyAlgrthm) { + case _WEP40_: + case _WEP104_: + EncryptionHeadOverhead = 4; + break; + case _TKIP_: + EncryptionHeadOverhead = 8; + break; + case _AES_: + EncryptionHeadOverhead = 8; + break; +#ifdef CONFIG_WAPI_SUPPORT + case _SMS4_: + EncryptionHeadOverhead = 18; + break; +#endif + default: + EncryptionHeadOverhead = 0; + } + + if (EncryptionHeadOverhead > 0) { + _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead); + *pLength += EncryptionHeadOverhead; + SetPrivacy(fctrl); + } + + /* ------------------------------------------------------------------------- */ + /* Frame Body. */ + /* ------------------------------------------------------------------------- */ + mdns_offset = *pLength; + pMdnsRspPkt = (u8 *)(pframe + mdns_offset); + /* LLC header */ + _rtw_memcpy(pMdnsRspPkt, ICMPLLCHeader, 8); + *pLength += 8; + + /* ICMP element */ + pMdnsRspPkt += 8; + SET_IPHDRV6_VERSION(pMdnsRspPkt, 0x06); + SET_IPHDRV6_PAYLOAD_LENGTH(pMdnsRspPkt, 0); // filled by fw + SET_IPHDRV6_NEXT_HEADER(pMdnsRspPkt, 0x3A); + SET_IPHDRV6_HOP_LIMIT(pMdnsRspPkt, 0xFF); + SET_IPHDRV6_SRC_IP_ADDR(pMdnsRspPkt, pIPAddress); // filled by fw + SET_IPHDRV6_DST_IP_ADDR(pMdnsRspPkt, mulicast_ipv6_addr); // filled by fw + + *pLength += 40; + + if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) { + if (IS_HARDWARE_TYPE_8188E(padapter) || + IS_HARDWARE_TYPE_8812(padapter)) { + rtw_hal_append_tkip_mic(padapter, pframe, mdns_offset); + } + *pLength += 8; + } + + /* UDP element */ + pMdnsRspPkt += 40; + SET_UDP_SRC_PORT(pMdnsRspPkt, 0xe914); // SNMP + SET_UDP_DST_PORT(pMdnsRspPkt, 0xe914); // SNMP + SET_UDP_LEN(pMdnsRspPkt, 0); // filled by fw + SET_UDP_CHECKSUM(pMdnsRspPkt, 0); // filled by fw + *pLength += 8; + + /* MDNS Header */ + pMdnsRspPkt += 8; + SET_MDNS_HDR_FLAG(pMdnsRspPkt, 0x84); + *pLength += 12; + +} + +#endif /* CONFIG_OFFLOAD_MDNS_V6 */ +#endif + #ifdef CONFIG_GTK_OL static void rtw_hal_construct_GTKRsp( PADAPTER padapter, @@ -8765,304 +9242,6 @@ static void rtw_hal_construct_remote_control_info(_adapter *adapter, } } -void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index, - u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len, - RSVDPAGE_LOC *rsvd_page_loc) -{ - struct security_priv *psecuritypriv = &adapter->securitypriv; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter); - struct mlme_ext_priv *pmlmeext; - struct mlme_ext_info *pmlmeinfo; - u32 ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0; - u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0; - u8 CurtPktPageNum = 0; - -#ifdef CONFIG_GTK_OL - struct sta_priv *pstapriv = &adapter->stapriv; - struct sta_info *psta; - struct security_priv *psecpriv = &adapter->securitypriv; - u8 kek[RTW_KEK_LEN]; - u8 kck[RTW_KCK_LEN]; -#endif /* CONFIG_GTK_OL */ -#ifdef CONFIG_PNO_SUPPORT - int pno_index; - u8 ssid_num; -#endif /* CONFIG_PNO_SUPPORT */ - - pmlmeext = &adapter->mlmeextpriv; - pmlmeinfo = &pmlmeext->mlmext_info; - - if (pwrctl->wowlan_pno_enable == _FALSE) { - /* ARP RSP * 1 page */ - - rsvd_page_loc->LocArpRsp = *page_num; - - RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp); - - rtw_hal_construct_ARPRsp(adapter, &pframe[index], - &ARPLength, pmlmeinfo->ip_addr); - - rtw_hal_fill_fake_txdesc(adapter, - &pframe[index - tx_desc], - ARPLength, _FALSE, _FALSE, _TRUE); - - CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size); - - *page_num += CurtPktPageNum; - - index += (CurtPktPageNum * page_size); - RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0); - -#ifdef CONFIG_IPV6 - /* 2 NS offload and NDP Info*/ - if (pwrctl->wowlan_ns_offload_en == _TRUE) { - rsvd_page_loc->LocNbrAdv = *page_num; - RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv); - rtw_hal_construct_na_message(adapter, - &pframe[index], &ns_len); - rtw_hal_fill_fake_txdesc(adapter, - &pframe[index - tx_desc], - ns_len, _FALSE, - _FALSE, _TRUE); - CurtPktPageNum = (u8)PageNum(tx_desc + ns_len, - page_size); - *page_num += CurtPktPageNum; - index += (CurtPktPageNum * page_size); - RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0); - - rsvd_page_loc->LocNDPInfo = *page_num; - RTW_INFO("LocNDPInfo: %d\n", - rsvd_page_loc->LocNDPInfo); - - rtw_hal_construct_ndp_info(adapter, - &pframe[index - tx_desc], - &ns_len); - CurtPktPageNum = - (u8)PageNum(tx_desc + ns_len, page_size); - *page_num += CurtPktPageNum; - index += (CurtPktPageNum * page_size); - RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0); - - } -#endif /*CONFIG_IPV6*/ - /* 3 Remote Control Info. * 1 page */ - rsvd_page_loc->LocRemoteCtrlInfo = *page_num; - RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo); - rtw_hal_construct_remote_control_info(adapter, - &pframe[index - tx_desc], - &rc_len); - CurtPktPageNum = (u8)PageNum(rc_len, page_size); - *page_num += CurtPktPageNum; - *total_pkt_len = index + rc_len; - RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len); -#ifdef CONFIG_GTK_OL - index += (CurtPktPageNum * page_size); - - /* if the ap staion info. exists, get the kek, kck from staion info. */ - psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); - if (psta == NULL) { - _rtw_memset(kek, 0, RTW_KEK_LEN); - _rtw_memset(kck, 0, RTW_KCK_LEN); - RTW_INFO("%s, KEK, KCK download rsvd page all zero\n", - __func__); - } else { - _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN); - _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN); - } - - /* 3 KEK, KCK */ - rsvd_page_loc->LocGTKInfo = *page_num; - RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo); - - if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) { - struct security_priv *psecpriv = NULL; - - psecpriv = &adapter->securitypriv; - _rtw_memcpy(pframe + index - tx_desc, - &psecpriv->dot11PrivacyAlgrthm, 1); - _rtw_memcpy(pframe + index - tx_desc + 1, - &psecpriv->dot118021XGrpPrivacy, 1); - _rtw_memcpy(pframe + index - tx_desc + 2, - kck, RTW_KCK_LEN); - _rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN, - kek, RTW_KEK_LEN); - CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size); - } else { - - _rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN); - _rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN, - kek, RTW_KEK_LEN); - GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN; - - if (psta != NULL && - psecuritypriv->dot118021XGrpPrivacy == _TKIP_) { - _rtw_memcpy(pframe + index - tx_desc + 56, - &psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN); - GTKLength += RTW_TKIP_MIC_LEN; - } - CurtPktPageNum = (u8)PageNum(GTKLength, page_size); - } -#if 0 - { - int i; - printk("\ntoFW KCK: "); - for (i = 0; i < 16; i++) - printk(" %02x ", kck[i]); - printk("\ntoFW KEK: "); - for (i = 0; i < 16; i++) - printk(" %02x ", kek[i]); - printk("\n"); - } - - RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n", - __FUNCTION__, &pframe[index - tx_desc], - (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN)); -#endif - - *page_num += CurtPktPageNum; - - index += (CurtPktPageNum * page_size); - RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0); - - /* 3 GTK Response */ - rsvd_page_loc->LocGTKRsp = *page_num; - RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp); - rtw_hal_construct_GTKRsp(adapter, &pframe[index], >KLength); - - rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], - GTKLength, _FALSE, _FALSE, _TRUE); -#if 0 - { - int gj; - printk("123GTK pkt=>\n"); - for (gj = 0; gj < GTKLength + tx_desc; gj++) { - printk(" %02x ", pframe[index - tx_desc + gj]); - if ((gj + 1) % 16 == 0) - printk("\n"); - } - printk(" <=end\n"); - } - - RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n", - __FUNCTION__, &pframe[index - tx_desc], - (tx_desc + GTKLength)); -#endif - - CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size); - - *page_num += CurtPktPageNum; - - index += (CurtPktPageNum * page_size); - RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0); - - /* below page is empty for GTK extension memory */ - /* 3(11) GTK EXT MEM */ - rsvd_page_loc->LocGTKEXTMEM = *page_num; - RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM); - CurtPktPageNum = 2; - - if (page_size >= 256) - CurtPktPageNum = 1; - - *page_num += CurtPktPageNum; - /* extension memory for FW */ - *total_pkt_len = index + (page_size * CurtPktPageNum); - RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len); -#endif /* CONFIG_GTK_OL */ - - index += (CurtPktPageNum * page_size); - - /*Reserve 1 page for AOAC report*/ - rsvd_page_loc->LocAOACReport = *page_num; - RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport); - *page_num += 1; - *total_pkt_len = index + (page_size * 1); - RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len); - } else { -#ifdef CONFIG_PNO_SUPPORT - if (pwrctl->wowlan_in_resume == _FALSE && - pwrctl->pno_inited == _TRUE) { - - /* Broadcast Probe Request */ - rsvd_page_loc->LocProbePacket = *page_num; - - RTW_INFO("loc_probe_req: %d\n", - rsvd_page_loc->LocProbePacket); - - rtw_hal_construct_ProbeReq( - adapter, - &pframe[index], - &ProbeReqLength, - NULL); - - rtw_hal_fill_fake_txdesc(adapter, - &pframe[index - tx_desc], - ProbeReqLength, _FALSE, _FALSE, _FALSE); - - CurtPktPageNum = - (u8)PageNum(tx_desc + ProbeReqLength, page_size); - - *page_num += CurtPktPageNum; - - index += (CurtPktPageNum * page_size); - RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0); - - /* Hidden SSID Probe Request */ - ssid_num = pwrctl->pnlo_info->hidden_ssid_num; - - for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) { - pwrctl->pnlo_info->loc_probe_req[pno_index] = - *page_num; - - rtw_hal_construct_ProbeReq( - adapter, - &pframe[index], - &ProbeReqLength, - &pwrctl->pno_ssid_list->node[pno_index]); - - rtw_hal_fill_fake_txdesc(adapter, - &pframe[index - tx_desc], - ProbeReqLength, _FALSE, _FALSE, _FALSE); - - CurtPktPageNum = - (u8)PageNum(tx_desc + ProbeReqLength, page_size); - - *page_num += CurtPktPageNum; - - index += (CurtPktPageNum * page_size); - RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0); - } - - /* PNO INFO Page */ - rsvd_page_loc->LocPNOInfo = *page_num; - RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo); - rtw_hal_construct_PNO_info(adapter, - &pframe[index - tx_desc], - &PNOLength); - - CurtPktPageNum = (u8)PageNum(PNOLength, page_size); - *page_num += CurtPktPageNum; - index += (CurtPktPageNum * page_size); - RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0); - - /* Scan Info Page */ - rsvd_page_loc->LocScanInfo = *page_num; - RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo); - rtw_hal_construct_scan_info(adapter, - &pframe[index - tx_desc], - &ScanInfoLength); - - CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size); - *page_num += CurtPktPageNum; - *total_pkt_len = index + ScanInfoLength; - index += (CurtPktPageNum * page_size); - RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len); - } -#endif /* CONFIG_PNO_SUPPORT */ - } -} - static void rtw_hal_gate_bb(_adapter *adapter, bool stop) { struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); @@ -9210,7 +9389,30 @@ static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow return _SUCCESS; } +void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx) +{ + int j; + + RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx); + RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type); + RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc); + for (j = 0; j < 4; j++) + RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]); +} +/*bit definition of pattern match format*/ +#define WOW_VALID_BIT BIT31 +#ifndef CONFIG_WOW_PATTERN_IN_TXFIFO +#define WOW_BC_BIT BIT26 +#define WOW_MC_BIT BIT25 +#define WOW_UC_BIT BIT24 +#else +#define WOW_BC_BIT BIT18 +#define WOW_UC_BIT BIT17 +#define WOW_MC_BIT BIT16 +#endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/ + #ifndef CONFIG_WOW_PATTERN_HW_CAM +#ifndef CONFIG_WOW_PATTERN_IN_TXFIFO static void rtw_hal_reset_mac_rx(_adapter *adapter) { u8 val8 = 0; @@ -9256,7 +9458,7 @@ static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode) rtw_read16(adapter, (REG_TRXFF_BNDY + 2))); } } - +#endif /* CONFIG_WOW_PATTERN_IN_TXFIFO*/ #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx) { @@ -9402,13 +9604,13 @@ bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx, if (i == 0) { if (context->type == PATTERN_VALID) - data = BIT(31); + data = WOW_VALID_BIT; else if (context->type == PATTERN_BROADCAST) - data = BIT(31) | BIT(26); + data = WOW_VALID_BIT | WOW_BC_BIT; else if (context->type == PATTERN_MULTICAST) - data = BIT(31) | BIT(25); + data = WOW_VALID_BIT | WOW_MC_BIT; else if (context->type == PATTERN_UNICAST) - data = BIT(31) | BIT(24); + data = WOW_VALID_BIT | WOW_UC_BIT; if (context->crc != 0) data |= context->crc; @@ -9450,16 +9652,45 @@ bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx, return res; } +void rtw_fill_pattern(_adapter *adapter) +{ + int i = 0, total = 0, index; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); + struct rtl_wow_pattern wow_pattern; + + total = pwrpriv->wowlan_pattern_idx; + + if (total > MAX_WKFM_CAM_NUM) + total = MAX_WKFM_CAM_NUM; + + for (i = 0 ; i < total ; i++) { + if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) { + + index = i; + if (!pwrpriv->bInSuspend) + index += 2; + rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i); + if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE) + RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i); + } + + } + rtw_write8(adapter, REG_WKFMCAM_NUM, total); + +} #else /* CONFIG_WOW_PATTERN_IN_TXFIFO */ bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx) { - u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0; + u32 data_l = 0, data_h = 0, page_sz = 0; u16 tx_page_start, tx_buf_ptr = 0; u16 cam_start_offset = 0; u16 ctrl_l = 0, ctrl_h = 0; u8 count = 0, tmp = 0, last_entry = 0; int i = 0; bool res = _TRUE; + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter); + u32 buffer[WKFMCAM_ADDR_NUM]; + if (idx > MAX_WKFM_CAM_NUM) { RTW_INFO("[Error]: %s, pattern index is out of range\n", @@ -9479,52 +9710,70 @@ bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx) return _FALSE; } - /* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */ - tx_page_start = last_entry - 1; - cam_start_offset = tx_page_start * page_sz / 8; - ctrl_l = 0x0; - ctrl_h = 0x0; - /* Enable TX packet buffer access */ - rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT); - - /* Read the WKFM CAM */ - for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) { - /* - * Set Tx packet buffer offset. - * TxBufer pointer increases 1, we can access 8 bytes in Tx packet buffer. - * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE - * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8 - * * Index: The index of the wake up frame mask - * * WKFMCAM_SIZE: the total size of one WKFM CAM - * * per entry offset of a WKFM CAM: Addr i * 4 bytes + if(_rtw_wow_chk_cap(adapter, WOW_CAP_HALMAC_ACCESS_PATTERN_IN_TXFIFO)) { + /* 8723F cannot indirect access tx fifo + * rtw_halmac_dump_fifo(dvobj, fifo_sel, fifo_addr, buf_sz, buf) */ - tx_buf_ptr = - (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3; - rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, tx_buf_ptr); - rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l); - data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L); - data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H); + #ifdef RTW_HALMAC + rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), + 2, + (pwrctl->pattern_rsvd_page_loc * page_sz) + (idx * WKFMCAM_ADDR_NUM * 4), + WKFMCAM_ADDR_NUM*4, (u8*)buffer); + #endif - RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l); - - count = 0; - - do { - tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23; - rtw_udelay_os(2); - count++; - } while (!tmp && count < 100); - - if (count >= 100) { - RTW_INFO("%s count:%d\n", __func__, count); - res = _FALSE; + for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) { + RTW_INFO("[%d]: %08x %08x\n", i, *(buffer + i*2), *(buffer + i*2 + 1)); } + } else { + /* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */ + tx_page_start = last_entry - 1; + cam_start_offset = tx_page_start * page_sz / 8; + ctrl_l = 0x0; + ctrl_h = 0x0; + + /* Enable TX packet buffer access */ + rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT); + + /* Read the WKFM CAM */ + for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) { + /* + * Set Tx packet buffer offset. + * TxBufer pointer increases 1, we can access 8 bytes in Tx packet buffer. + * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE + * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8 + * * Index: The index of the wake up frame mask + * * WKFMCAM_SIZE: the total size of one WKFM CAM + * * per entry offset of a WKFM CAM: Addr i * 4 bytes + */ + tx_buf_ptr = + (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3; + rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, tx_buf_ptr); + rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l); + data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L); + data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H); + + RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l); + + count = 0; + + do { + tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23; + rtw_udelay_os(2); + count++; + } while (!tmp && count < 100); + + if (count >= 100) { + RTW_INFO("%s count:%d\n", __func__, count); + res = _FALSE; + } + } + + /* Disable RX packet buffer access */ + rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, + DISABLE_TRXPKT_BUF_ACCESS); } - /* Disable RX packet buffer access */ - rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, - DISABLE_TRXPKT_BUF_ACCESS); return res; } @@ -9581,13 +9830,13 @@ bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx, if (i == 0) { if (context->type == PATTERN_VALID) - data_l = BIT(31); + data_l = WOW_VALID_BIT; else if (context->type == PATTERN_BROADCAST) - data_l = BIT(31) | BIT(26); + data_l = WOW_VALID_BIT | WOW_BC_BIT; else if (context->type == PATTERN_MULTICAST) - data_l = BIT(31) | BIT(25); + data_l = WOW_VALID_BIT | WOW_MC_BIT; else if (context->type == PATTERN_UNICAST) - data_l = BIT(31) | BIT(24); + data_l = WOW_VALID_BIT | WOW_UC_BIT; if (context->crc != 0) data_l |= context->crc; @@ -9600,7 +9849,7 @@ bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx, rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data_h); } - rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, (tx_buf_ptr & 0xFFFF) | BIT23 | (0xff <<24)); + rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, (tx_buf_ptr & 0x1FFF) | BIT23 | (0xff <<24)); count = 0; do { tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23; @@ -9621,6 +9870,65 @@ bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx, rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS); return res; } +bool rtw_write_to_frame_mask_buf(_adapter *adapter, u8 idx, + struct rtl_wow_pattern *context, char *pattern_info, u32 *ppattern_info_len) +{ + + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); + u32 page_sz = 0; + int res = _FALSE, i = 0; + u32 tmp_pattern_buf[6] = {0}; + + if (pattern_info == NULL) { + RTW_ERR("[Error]: %s, pattern info is NULL\n", __func__); + } + if (idx > MAX_WKFM_CAM_NUM) { + RTW_ERR("[Error]: %s, pattern index is out of range\n", + __func__); + return _FALSE; + } + + rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz); + if (page_sz == 0) { + RTW_ERR("[Error]: %s, page_sz is 0!!\n", __func__); + return _FALSE; + } + + /* Fill WKFM */ + for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) { + if (i == 0) { + if (context->type == PATTERN_VALID) + tmp_pattern_buf[0] = WOW_VALID_BIT; + else if (context->type == PATTERN_BROADCAST) + tmp_pattern_buf[0] = WOW_VALID_BIT | WOW_BC_BIT; + else if (context->type == PATTERN_MULTICAST) + tmp_pattern_buf[0] = WOW_VALID_BIT | WOW_MC_BIT; + else if (context->type == PATTERN_UNICAST) + tmp_pattern_buf[0] = WOW_VALID_BIT | WOW_UC_BIT; + + if (context->crc != 0) + tmp_pattern_buf[0] |= context->crc; + /* pattern[1] is reserved in pattern format, dont care. */ + + } else { + tmp_pattern_buf[i * 2] = context->mask[i * 2 - 2]; + tmp_pattern_buf[i * 2 + 1] = context->mask[i * 2 - 1]; + } + } + + + /* put pattern to pattern_buf */ + _rtw_memcpy((pattern_info + idx * WKFMCAM_SIZE) , tmp_pattern_buf, WKFMCAM_SIZE); + *ppattern_info_len += WKFMCAM_SIZE; + #ifdef CONFIG_WOW_PATTERN_IN_TXFIFO_DBG + RTW_INFO("\nidx : %u pattern_info_len : %u\n", idx, *ppattern_info_len); + RTW_INFO_DUMP("", (pattern_info + idx * WKFMCAM_SIZE), WKFMCAM_SIZE); + #endif + res = _TRUE; + + + return res; +} #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */ void rtw_clean_pattern(_adapter *adapter) @@ -9632,9 +9940,7 @@ void rtw_clean_pattern(_adapter *adapter) _rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern)); zero_pattern.type = PATTERN_INVALID; - - for (i = 0; i < MAX_WKFM_CAM_NUM; i++) - rtw_write_to_frame_mask(adapter, i, &zero_pattern); + /* pattern in tx fifo do not need clear to zero*/ rtw_write8(adapter, REG_WKFMCAM_NUM, 0); } @@ -9753,42 +10059,9 @@ static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern, return res; } #endif - -void rtw_fill_pattern(_adapter *adapter) -{ - int i = 0, total = 0, index; - struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); - struct rtl_wow_pattern wow_pattern; - - total = pwrpriv->wowlan_pattern_idx; - - if (total > MAX_WKFM_CAM_NUM) - total = MAX_WKFM_CAM_NUM; - - for (i = 0 ; i < total ; i++) { - if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) { - - index = i; - if (!pwrpriv->bInSuspend) - index += 2; - - if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE) - RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i); - } - - } - rtw_write8(adapter, REG_WKFMCAM_NUM, total); - -} - #else /*CONFIG_WOW_PATTERN_HW_CAM*/ #define WOW_CAM_ACCESS_TIMEOUT_MS 200 -#define WOW_VALID_BIT BIT31 -#define WOW_BC_BIT BIT26 -#define WOW_MC_BIT BIT25 -#define WOW_UC_BIT BIT24 - static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr) { struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); @@ -9970,18 +10243,6 @@ void rtw_clean_pattern(_adapter *adapter) if (_FAIL == _rtw_wow_pattern_clean_cam(adapter)) RTW_ERR("rtw_clean_pattern failed\n"); } - -void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx) -{ - int j; - - RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx); - RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type); - RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc); - for (j = 0; j < 4; j++) - RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]); -} - void rtw_fill_pattern(_adapter *adapter) { int i = 0, total = 0; @@ -10006,9 +10267,14 @@ void rtw_wow_pattern_cam_dump(_adapter *adapter) { #ifndef CONFIG_WOW_PATTERN_HW_CAM - int i; + int i = 0, total = 0; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); + total = pwrpriv->wowlan_pattern_idx; - for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) { + if (total > MAX_WKFM_CAM_NUM) + total = MAX_WKFM_CAM_NUM; + + for (i = 0 ; i < total; i++) { RTW_INFO("=======[%d]=======\n", i); rtw_read_from_frame_mask(adapter, i); } @@ -10035,9 +10301,13 @@ static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode) RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx); break; case 1: + #if defined(CONFIG_WOW_PATTERN_IN_TXFIFO) + RTW_INFO("%s Patterns have been downloaded in rsvd pages\n", __func__); + #else rtw_set_default_pattern(adapter); rtw_fill_pattern(adapter); RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx); + #endif break; case 2: rtw_clean_pattern(adapter); @@ -10060,8 +10330,13 @@ static void rtw_hal_wow_enable(_adapter *adapter) PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter); int res; u16 media_status_rpt; - u8 no_wake = 0; - + u8 no_wake = 0, i; + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + _adapter *iface; +#ifdef CONFIG_GPIO_WAKEUP + u8 val8 = 0; +#endif + #ifdef CONFIG_LPS_PG u8 lps_pg_hdl_id = 0; #endif @@ -10069,11 +10344,21 @@ static void rtw_hal_wow_enable(_adapter *adapter) if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && - !check_fwstate(pmlmepriv, _FW_LINKED)) + !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) no_wake = 1; RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter)); rtw_hal_gate_bb(adapter, _TRUE); + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + /* Start Usb TxDMA */ + if(iface) { + RTW_INFO(ADPT_FMT "enable TX\n", ADPT_ARG(iface)); + RTW_ENABLE_FUNC(iface, DF_TX_BIT); + } + } + #ifdef CONFIG_GTK_OL if (psecuritypriv->binstallKCK_KEK == _TRUE) rtw_hal_fw_sync_cam_id(adapter); @@ -10101,7 +10386,9 @@ static void rtw_hal_wow_enable(_adapter *adapter) #ifndef CONFIG_WOW_PATTERN_HW_CAM /* Reconfig RX_FF Boundary */ + #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO rtw_hal_set_wow_rxff_boundary(adapter, _TRUE); + #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/ #endif /* redownload wow pattern */ @@ -10120,6 +10407,15 @@ static void rtw_hal_wow_enable(_adapter *adapter) if(!no_wake) rtw_sta_media_status_rpt(adapter, psta, 1); } +#ifdef CONFIG_FW_MULTI_PORT_SUPPORT + else { + if(registry_par->suspend_type == FW_IPS_WRC) { + adapter_to_dvobj(adapter)->dft.port_id = 0xFF; + adapter_to_dvobj(adapter)->dft.mac_id = 0xFF; + rtw_hal_set_default_port_id_cmd(adapter, 0); + } + } +#endif /* CONFIG_FW_MULTI_PORT_SUPPORT */ } #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) @@ -10129,8 +10425,27 @@ static void rtw_hal_wow_enable(_adapter *adapter) RTW_PRINT("[WARNING] enable cpwm2 fail\n"); #endif #ifdef CONFIG_GPIO_WAKEUP - rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _TRUE); -#endif +#ifdef CONFIG_RTW_ONE_PIN_GPIO + rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE); + rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index); +#else +#ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE + if (pwrctl->is_high_active == 0) + rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index); + else + rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, + GPIO_OUTPUT_LOW); +#else + val8 = (pwrctl->is_high_active == 0) ? 1 : 0; + rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, val8); + rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE); + RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow suspend and %s_ACTIVE.\n", + __func__, pwrctl->wowlan_gpio_index, + pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW", + pwrctl->is_high_active ? "HIGI" : "LOW"); +#endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */ +#endif /* CONFIG_RTW_ONE_PIN_GPIO */ +#endif /* CONFIG_GPIO_WAKEUP */ /* Set WOWLAN H2C command. */ RTW_PRINT("Set WOWLan cmd\n"); rtw_hal_set_fw_wow_related_cmd(adapter, 1); @@ -10219,6 +10534,12 @@ void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason) _dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle"); else if (CLK_32K_LOCK == reason) _dbg_wake_up_reason_string(adapter, "clk 32k lock"); + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + else if (WOW_KEEPALIVE_ACK_TIMEOUT == reason) + _dbg_wake_up_reason_string(adapter, "rx keep alive ack timeout"); + else if (WOW_KEEPALIVE_WAKE == reason) + _dbg_wake_up_reason_string(adapter, "rx keep alive wake pattern"); + #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ else _dbg_wake_up_reason_string(adapter, "unknown reasoen"); } @@ -10233,15 +10554,14 @@ static void rtw_hal_wow_disable(_adapter *adapter) struct registry_priv *registry_par = &adapter->registrypriv; int res; u16 media_status_rpt; - u8 val8; RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__); - - if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, _FW_LINKED)) { + + if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) { RTW_INFO("FW_IPS_DISABLE_BBRF resume\n"); return; } - + if (!pwrctl->wowlan_pno_enable) { psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv)); if (psta != NULL) @@ -10269,6 +10589,18 @@ static void rtw_hal_wow_disable(_adapter *adapter) res = rtw_hal_check_wow_ctrl(adapter, _FALSE); + #if defined(CONFIG_RTL8188E) + if (IS_HARDWARE_TYPE_8188E(adapter)) + rtw_hal_enable_tx_report(adapter); + #endif + + if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) && + (pwrctl->wowlan_wake_reason != RX_DEAUTH) && + (pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) { + rtw_hal_get_aoac_rpt(adapter); + rtw_hal_update_sw_security_info(adapter); + } + if (res == _FALSE) { RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__); rtw_hal_force_enable_rxdma(adapter); @@ -10285,43 +10617,35 @@ static void rtw_hal_wow_disable(_adapter *adapter) #ifndef CONFIG_WOW_PATTERN_HW_CAM /* config RXFF boundary to original */ + #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO rtw_hal_set_wow_rxff_boundary(adapter, _FALSE); + #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/ #endif rtw_hal_release_rx_dma(adapter); - #if defined(CONFIG_RTL8188E) - if (IS_HARDWARE_TYPE_8188E(adapter)) - rtw_hal_enable_tx_report(adapter); - #endif - - if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) && - (pwrctl->wowlan_wake_reason != RX_DEAUTH) && - (pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) { - rtw_hal_get_aoac_rpt(adapter); - rtw_hal_update_sw_security_info(adapter); - } - rtw_hal_fw_dl(adapter, _FALSE); #ifdef CONFIG_GPIO_WAKEUP #ifdef CONFIG_RTW_ONE_PIN_GPIO - rtw_hal_set_input_gpio(adapter, WAKEUP_GPIO_IDX); + rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index); #else #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE if (pwrctl->is_high_active == 0) - rtw_hal_set_input_gpio(adapter, WAKEUP_GPIO_IDX); + rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index); else - rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, 0); + rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, + GPIO_OUTPUT_LOW); #else - val8 = (pwrctl->is_high_active == 0) ? 1 : 0; - RTW_PRINT("Set Wake GPIO to default(%d).\n", val8); - - rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, val8); - rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _FALSE); -#endif + rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index + , pwrctl->wowlan_gpio_output_state); + RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow resume and %s_ACTIVE.\n", + __func__, pwrctl->wowlan_gpio_index, + pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW", + pwrctl->is_high_active ? "HIGI" : "LOW"); +#endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */ #endif /* CONFIG_RTW_ONE_PIN_GPIO */ -#endif +#endif /* CONFIG_GPIO_WAKEUP */ if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) && (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) && (pwrctl->wowlan_wake_reason != RX_DISASSOC) && @@ -10342,6 +10666,684 @@ static void rtw_hal_wow_disable(_adapter *adapter) } rtw_hal_gate_bb(adapter, _FALSE); } +#if defined(CONFIG_WOW_PATTERN_IN_TXFIFO) +static void rtw_hal_construct_pattern_info( + PADAPTER padapter, + u8 *pframe, + u32 *pLength +) +{ + + u32 pattern_info_len = 0; + int i = 0, total = 0, index; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct rtl_wow_pattern wow_pattern; + u32 page_sz = 0; + + total = pwrpriv->wowlan_pattern_idx; + + if (total > MAX_WKFM_CAM_NUM) + total = MAX_WKFM_CAM_NUM; + + /* Generate default pattern */ + rtw_set_default_pattern(padapter); + + /* Convert pattern to WKFM_CAM pattern */ + for (i = 0 ; i < total ; i++) { + if (_SUCCESS == rtw_hal_wow_pattern_generate(padapter, i, &wow_pattern)) { + + index = i; + if (!pwrpriv->bInSuspend) + index += 2; + #ifdef CONFIG_WOW_PATTERN_IN_TXFIFO_DBG + rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i); + #endif + + if (rtw_write_to_frame_mask_buf(padapter, index, &wow_pattern, + pframe, &pattern_info_len) == _FALSE) + RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i); + } + } + *pLength = pattern_info_len; + + +} +#endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */ +void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index, + u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len, + RSVDPAGE_LOC *rsvd_page_loc) +{ + struct security_priv *psecuritypriv = &adapter->securitypriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter); + struct mlme_ext_priv *pmlmeext; + struct mlme_ext_info *pmlmeinfo; + u32 ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0; + u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0; + u8 CurtPktPageNum = 0; +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + u32 keep_alive_len=0; + int i; +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN */ +#ifdef CONFIG_WAR_OFFLOAD + u16 tmp_idx = 0; + u32 buf_len = 0; +#endif + +#ifdef CONFIG_GTK_OL + struct sta_priv *pstapriv = &adapter->stapriv; + struct sta_info *psta; + struct security_priv *psecpriv = &adapter->securitypriv; + u8 kek[RTW_KEK_LEN]; + u8 kck[RTW_KCK_LEN]; +#endif /* CONFIG_GTK_OL */ +#ifdef CONFIG_PNO_SUPPORT + int pno_index; + u8 ssid_num; +#endif /* CONFIG_PNO_SUPPORT */ +#ifdef CONFIG_WOW_PATTERN_IN_TXFIFO + u32 PatternLen = 0; + u32 cam_start_offset = 0; + u32 reg_cam_start_offset_val = 0; +#endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */ + + pmlmeext = &adapter->mlmeextpriv; + pmlmeinfo = &pmlmeext->mlmext_info; + + if (pwrctl->wowlan_pno_enable == _FALSE) { + /* ARP RSP * 1 page */ + + rsvd_page_loc->LocArpRsp = *page_num; + + RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp); + +#ifdef CONFIG_WAR_OFFLOAD + if ((0 != pwrctl->wowlan_war_offload_ipv4.ip_addr[0]) && + (_FALSE == _rtw_memcmp(&pwrctl->wowlan_war_offload_ipv4.ip_addr[0], pmlmeinfo->ip_addr, 4))) { + _rtw_memcpy(pmlmeinfo->ip_addr, &pwrctl->wowlan_war_offload_ipv4.ip_addr[0], 4); + RTW_INFO("Update IP(%d.%d.%d.%d) to arp rsvd page\n", + pmlmeinfo->ip_addr[0], pmlmeinfo->ip_addr[1], + pmlmeinfo->ip_addr[2], pmlmeinfo->ip_addr[3]); + } +#endif /* CONFIG_WAR_OFFLOAD */ + + + rtw_hal_construct_ARPRsp(adapter, &pframe[index], + &ARPLength, pmlmeinfo->ip_addr); + + rtw_hal_fill_fake_txdesc(adapter, + &pframe[index - tx_desc], + ARPLength, _FALSE, _FALSE, _TRUE); + + CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size); + + *page_num += CurtPktPageNum; + + index += (CurtPktPageNum * page_size); + RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0); +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + /* Keep Alive * ? page*/ + if(pwrctl->keep_alive_pattern_len){ + rsvd_page_loc->LocKeepAlive = *page_num; + pwrctl->keep_alive_pattern_loc = rsvd_page_loc->LocKeepAlive; + RTW_INFO("pwrctl->keep_alive_pattern_loc: %d\n", pwrctl->keep_alive_pattern_loc); + rtw_hal_construct_keepalive(adapter,&pframe[index],&keep_alive_len); + rtw_hal_fill_fake_txdesc(adapter, + &pframe[index - tx_desc], + keep_alive_len, _FALSE, _FALSE, _TRUE); + CurtPktPageNum = (u8)PageNum(tx_desc + keep_alive_len, page_size); + *page_num += CurtPktPageNum; + index += (CurtPktPageNum * page_size); + RSVD_PAGE_CFG("WOW-KeepAlive:", CurtPktPageNum, *page_num, 0); + } +#endif /* CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + +#ifdef CONFIG_IPV6 + /* 2 NS offload and NDP Info*/ + if (pwrctl->wowlan_ns_offload_en == _TRUE) { + rsvd_page_loc->LocNbrAdv = *page_num; + RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv); + rtw_hal_construct_na_message(adapter, + &pframe[index], &ns_len); + rtw_hal_fill_fake_txdesc(adapter, + &pframe[index - tx_desc], + ns_len, _FALSE, + _FALSE, _TRUE); + CurtPktPageNum = (u8)PageNum(tx_desc + ns_len, + page_size); + *page_num += CurtPktPageNum; + index += (CurtPktPageNum * page_size); + RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0); + + rsvd_page_loc->LocNDPInfo = *page_num; + RTW_INFO("LocNDPInfo: %d\n", + rsvd_page_loc->LocNDPInfo); + + rtw_hal_construct_ndp_info(adapter, + &pframe[index - tx_desc], + &ns_len); + CurtPktPageNum = + (u8)PageNum(tx_desc + ns_len, page_size); + *page_num += CurtPktPageNum; + index += (CurtPktPageNum * page_size); + RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0); + + } +#endif /*CONFIG_IPV6*/ + /* 3 Remote Control Info. * 1 page */ + rsvd_page_loc->LocRemoteCtrlInfo = *page_num; + RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo); + rtw_hal_construct_remote_control_info(adapter, + &pframe[index - tx_desc], + &rc_len); + CurtPktPageNum = (u8)PageNum(rc_len, page_size); + *page_num += CurtPktPageNum; + *total_pkt_len = index + rc_len; + RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len); +#ifdef CONFIG_GTK_OL + index += (CurtPktPageNum * page_size); + + /* if the ap staion info. exists, get the kek, kck from staion info. */ + psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); + if (psta == NULL) { + _rtw_memset(kek, 0, RTW_KEK_LEN); + _rtw_memset(kck, 0, RTW_KCK_LEN); + RTW_INFO("%s, KEK, KCK download rsvd page all zero\n", + __func__); + } else { + _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN); + _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN); + } + + /* 3 KEK, KCK */ + rsvd_page_loc->LocGTKInfo = *page_num; + RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo); + + if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) { + struct security_priv *psecpriv = NULL; + + psecpriv = &adapter->securitypriv; + _rtw_memcpy(pframe + index - tx_desc, + &psecpriv->dot11PrivacyAlgrthm, 1); + _rtw_memcpy(pframe + index - tx_desc + 1, + &psecpriv->dot118021XGrpPrivacy, 1); + _rtw_memcpy(pframe + index - tx_desc + 2, + kck, RTW_KCK_LEN); + _rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN, + kek, RTW_KEK_LEN); + CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size); + } else { + + _rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN); + _rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN, + kek, RTW_KEK_LEN); + GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN; + + if (psta != NULL && + psecuritypriv->dot118021XGrpPrivacy == _TKIP_) { + _rtw_memcpy(pframe + index - tx_desc + 56, + &psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN); + GTKLength += RTW_TKIP_MIC_LEN; + } + CurtPktPageNum = (u8)PageNum(GTKLength, page_size); + } +#if 0 + { + int i; + printk("\ntoFW KCK: "); + for (i = 0; i < 16; i++) + printk(" %02x ", kck[i]); + printk("\ntoFW KEK: "); + for (i = 0; i < 16; i++) + printk(" %02x ", kek[i]); + printk("\n"); + } + + RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n", + __FUNCTION__, &pframe[index - tx_desc], + (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN)); +#endif + + *page_num += CurtPktPageNum; + + index += (CurtPktPageNum * page_size); + RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0); + + /* 3 GTK Response */ + rsvd_page_loc->LocGTKRsp = *page_num; + RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp); + rtw_hal_construct_GTKRsp(adapter, &pframe[index], >KLength); + + rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], + GTKLength, _FALSE, _FALSE, _TRUE); +#if 0 + { + int gj; + printk("123GTK pkt=>\n"); + for (gj = 0; gj < GTKLength + tx_desc; gj++) { + printk(" %02x ", pframe[index - tx_desc + gj]); + if ((gj + 1) % 16 == 0) + printk("\n"); + } + printk(" <=end\n"); + } + + RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n", + __FUNCTION__, &pframe[index - tx_desc], + (tx_desc + GTKLength)); +#endif + + CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size); + + *page_num += CurtPktPageNum; + + index += (CurtPktPageNum * page_size); + RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0); + + /* below page is empty for GTK extension memory */ + /* 3(11) GTK EXT MEM */ + rsvd_page_loc->LocGTKEXTMEM = *page_num; + RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM); + CurtPktPageNum = 2; + + if (page_size >= 256) + CurtPktPageNum = 1; + + *page_num += CurtPktPageNum; + /* extension memory for FW */ + *total_pkt_len = index + (page_size * CurtPktPageNum); + RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len); +#endif /* CONFIG_GTK_OL */ + + index += (CurtPktPageNum * page_size); + +#ifdef CONFIG_WAR_OFFLOAD + if(_TRUE == pwrctl->wowlan_war_offload_mode) { + u8 zero_ary[16] = {0x00}; + u8 war_tmp_cnt = 0; + + /* Reserve 2 page for Ip parameters */ + /* First page + | Byte 15 -----------Byte 0 | + | IP-4 | IP-3 | IP-2 | IP-1 | + | location of each feature | mac addr | + | NetBIOS name | + | location of each feature | + Second page + | IPv6 - 1 | + | IPv6 - 2 | + | IPv6 - 3 | + | IPv6 - 4 | + | IPv6 - 5 | + | IPv6 - 6 | + | IPv6 - 7 | + | IPv6 - 8 | + */ + + /* location of each feature : Byte 22 ~ Byte 31 + * Byte22 : location of SNMP RX + * Byte23 : location of SNMP V4 + * Byte24 : location of SNMP V6 + * Byte25 : location of MDNS Param + * Byte26 : location of MDNS V4 + * Byte27 : location of MDNS V6 + * Byte28 : location of SSDP pattern + * Byte29 : location of WSD pattern + * Byte30 : location of SLP pattern + * Byte31 : location of LLMNR + */ + + /* ipv4 : 4 */ + if (0 == pwrctl->wowlan_war_offload_ipv4.ip_addr[0]) + _rtw_memcpy(&pwrctl->wowlan_war_offload_ipv4.ip_addr[0], pmlmeinfo->ip_addr, 4); + for(war_tmp_cnt=0; war_tmp_cnt<4 ;war_tmp_cnt++) + _rtw_memcpy(pframe + index - tx_desc + (war_tmp_cnt*4), &pwrctl->wowlan_war_offload_ipv4.ip_addr[war_tmp_cnt], 4); + + if (is_zero_mac_addr(pwrctl->wowlan_war_offload_mac)) { + _rtw_memcpy(pwrctl->wowlan_war_offload_mac, adapter_mac_addr(adapter), 6); + } + _rtw_memcpy(pframe + index + 16 - tx_desc, pwrctl->wowlan_war_offload_mac, 6); + + + /* ipv6 : 8 */ + if (_TRUE == _rtw_memcmp(pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], zero_ary, RTW_IPv6_ADDR_LEN)) + _rtw_memcpy(pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], pmlmeinfo->ip6_addr, RTW_IPv6_ADDR_LEN); + + for(war_tmp_cnt=0; war_tmp_cnt<8 ;war_tmp_cnt++) + _rtw_memcpy(pframe + index + page_size - tx_desc + (war_tmp_cnt*16), pwrctl->wowlan_war_offload_ipv6.ipv6_addr[war_tmp_cnt], 16); + + rsvd_page_loc->LocIpParm = *page_num; + + tmp_idx = index; + CurtPktPageNum = 2; + *page_num += CurtPktPageNum; + *total_pkt_len = index + (page_size * CurtPktPageNum); + index += (CurtPktPageNum * page_size); + + +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) + if ( (WAR_MDNS_V4_RSP_EN & pwrctl->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_RSP_EN & pwrctl->wowlan_war_offload_ctrl) || + (WAR_MDNS_V4_WAKEUP_EN & pwrctl->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_WAKEUP_EN & pwrctl->wowlan_war_offload_ctrl)) { + + struct war_mdns_service_info *psinfo = pwrctl->wowlan_war_offload_mdns_service; + u8 txt_in_ptr[31]={ 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x13, 0x09, 0x74, 0x78, 0x74, 0x76, 0x65, 0x72, 0x73, + 0x3d, 0x31, 0x08, 0x71, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x3d, 0x31}; + u16 mdns_offset = index - tx_desc; + u8 i = 0; + + rsvd_page_loc->LocMdnsPara = *page_num; + RTW_INFO("LocMdnsPara : %d\n", rsvd_page_loc->LocMdnsPara); + + /* 1. service info */ + pframe[mdns_offset] = 0x01; // TLV(T) + mdns_offset += 1; + _rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_service_info_num, 1); + mdns_offset += 1; + + for(i=0; iwowlan_war_offload_mdns_service_info_num ;i++) + { + u16 srv_rsp_len = 0; + + // 1.1 : construct service name string + // : length of total service name string (service+transport+domain) + pframe[mdns_offset] = psinfo[i].service_len + psinfo[i].transport_len + psinfo[i].domain_len + 4; + mdns_offset += 1; + + // : service name + pframe[mdns_offset] = psinfo[i].service_len; + mdns_offset += 1; + _rtw_memcpy(pframe + mdns_offset, &psinfo[i].service, psinfo[i].service_len); + mdns_offset += psinfo[i].service_len; + + // : transport name + pframe[mdns_offset] = psinfo[i].transport_len; + mdns_offset += 1; + _rtw_memcpy(pframe + mdns_offset, &psinfo[i].transport, psinfo[i].transport_len); + mdns_offset += psinfo[i].transport_len; + + // : domain name + pframe[mdns_offset] = psinfo[i].domain_len; + mdns_offset += 1; + _rtw_memcpy(pframe + mdns_offset, &psinfo[i].domain, psinfo[i].domain_len); + mdns_offset += psinfo[i].domain_len; + + // : delimiter + mdns_offset += 1; + + // 1.2 : construct type srv rsp + pframe[mdns_offset] = psinfo[i].target_len + 19; // length + pframe[mdns_offset + 2] = 0x21; // rsp type (srv) + pframe[mdns_offset + 4] = 0x01; // cache flush + class + _rtw_memcpy(pframe + mdns_offset + 5, &psinfo[i].ttl, 4); // ttl + pframe[mdns_offset + 5] = (u8) ( (psinfo[i].ttl & 0xff000000) >> 24); // ttl - byte0 + pframe[mdns_offset + 6] = (u8) ( (psinfo[i].ttl & 0x00ff0000) >> 16); // ttl - byte1 + pframe[mdns_offset + 7] = (u8) ( (psinfo[i].ttl & 0x0000ff00) >> 8 ); // ttl - byte2 + pframe[mdns_offset + 8] = (u8) (psinfo[i].ttl & 0x000000ff); // ttl - byte3 + pframe[mdns_offset + 10] = psinfo[i].target_len + 9; // data length + _rtw_memcpy(pframe + mdns_offset + 15, &psinfo[i].port, 2); // port + _rtw_memcpy(pframe + mdns_offset + 17, &psinfo[i].target_len, 1); // target len + _rtw_memcpy(pframe + mdns_offset + 18, &psinfo[i].target, psinfo[i].target_len); // target + pframe[mdns_offset + 18 + psinfo[i].target_len] = 0xc0; // message compresion, offset will be filled by fw. + mdns_offset += (1 + psinfo[i].target_len + 19); + + // 1.3 : set the idx of txt rsp + pframe[mdns_offset] = psinfo[i].txt_rsp_idx; + mdns_offset += 1; + } + + /* 2. machine name */ + pframe[mdns_offset] = 0x02; // TLV(T) + mdns_offset += 1; + _rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_mnane_num, 1); // NUM + mdns_offset += 1; + + for(i=0; iwowlan_war_offload_mdns_mnane_num; i++) + { + pframe[mdns_offset] = pwrctl->wowlan_war_offload_mdns_mnane[i].name_len; + _rtw_memcpy(pframe + mdns_offset + 1, pwrctl->wowlan_war_offload_mdns_mnane[i].name, + pwrctl->wowlan_war_offload_mdns_mnane[i].name_len); // machine name + mdns_offset += (1+pwrctl->wowlan_war_offload_mdns_mnane[i].name_len); + } + + /* 3. A rsp */ + pframe[mdns_offset] = 0x03; // TLV(T) + pframe[mdns_offset + 1] = 14; // TLV(L) + pframe[mdns_offset + 3] = 0x01; // rsp type (a) + pframe[mdns_offset + 5] = 0x01; // cache flush + class + pframe[mdns_offset + 9] = 0xf0; // ttl (240 sec) + pframe[mdns_offset + 11] = 4; // length of ipv4 addr. + _rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_ipv4.ip_addr[0], 4); + mdns_offset += (2 + 14); + + /* 4. AAAA rsp */ + pframe[mdns_offset] = 0x04; // TLV(T) + pframe[mdns_offset + 1] = 26; // TLV(L) + pframe[mdns_offset + 3] = 0x1c; // rsp type (aaaa) + pframe[mdns_offset + 5] = 0x01; // cache flush + class + pframe[mdns_offset + 9] = 0xf0; // ttl (240 sec) + pframe[mdns_offset + 11] = 16; // length of ipv6 addr. + _rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], 16); + mdns_offset += (2 + 26); + + /* 5. PTR rsp */ + pframe[mdns_offset] = 0x05; // TLV(T) + pframe[mdns_offset + 1] = 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len; // TLV(L) + pframe[mdns_offset + 3] = 0x0c; // rsp type (aaaa) + pframe[mdns_offset + 5] = 0x01; // cache flush + class + pframe[mdns_offset + 8] = 0x1c; // ttl + pframe[mdns_offset + 9] = 0x20; // ttl (7200 sec) + pframe[mdns_offset + 11] = 3 + pwrctl->wowlan_war_offload_mdns_domain_name_len; // data length + pframe[mdns_offset + 12] = pwrctl->wowlan_war_offload_mdns_domain_name_len; // domain name length + _rtw_memcpy(pframe + mdns_offset + 13, &pwrctl->wowlan_war_offload_mdns_domain_name, + pwrctl->wowlan_war_offload_mdns_domain_name_len); + pframe[mdns_offset + 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len] = 0xc0; // message compression + mdns_offset += (2 + 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len); + + /* 6. TXT in PTR rsp */ + pframe[mdns_offset] = 0x06; // TLV(T) + pframe[mdns_offset + 1] = 31; // TLV(L) + _rtw_memcpy(pframe + mdns_offset + 2, &txt_in_ptr, 31); + mdns_offset += (2 + 31); + + /* 7. TXT rsp */ + pframe[mdns_offset] = 0x07; // TLV(T) + mdns_offset += 1; + _rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_txt_rsp_num, 1); // NUM + mdns_offset += 1; + + for(i=0; iwowlan_war_offload_mdns_txt_rsp_num; i++) + { + u16 txt_rsp_len = pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len; + + if(pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len==0) + { + _rtw_memcpy(pframe + mdns_offset, &txt_rsp_len, 2); + mdns_offset += ( 2 + txt_rsp_len ); + continue; + } + + txt_rsp_len += 10; + _rtw_memcpy(pframe + mdns_offset, &txt_rsp_len, 2); + pframe[mdns_offset + 3] = 0x10; // rsp type (txt) + pframe[mdns_offset + 5] = 0x01; // cache flush + class + pframe[mdns_offset + 8] = 0x1c; // ttl + pframe[mdns_offset + 9] = 0x20; // ttl (7200 sec) + pframe[mdns_offset + 10] = (u8) ((pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len & 0xff00) >> 8); + pframe[mdns_offset + 11] = (u8) (pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len & 0x00ff); + _rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt, + pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len); + mdns_offset += ( 2 + txt_rsp_len ); + } + + CurtPktPageNum = (u8)PageNum(mdns_offset - index, page_size)+1; + *page_num += CurtPktPageNum; + *total_pkt_len = index + (page_size * CurtPktPageNum); + index += (CurtPktPageNum * page_size); + } +#endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */ + +#ifdef CONFIG_OFFLOAD_MDNS_V4 + if (WAR_MDNS_V4_RSP_EN & pwrctl->wowlan_war_offload_ctrl) { + rsvd_page_loc->LocMdnsv4 = *page_num; + RTW_INFO("LocMdnsv4: %d\n", rsvd_page_loc->LocMdnsv4); + + rtw_hal_construct_mdns_rsp_v4(adapter, &pframe[index], &buf_len, pmlmeinfo->ip_addr); + rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], buf_len, _FALSE, _FALSE, _TRUE); + CurtPktPageNum = 16; + *page_num += CurtPktPageNum; + index += (CurtPktPageNum * page_size); + } +#endif /* CONFIG_OFFLOAD_MDNS_V4 */ + +#ifdef CONFIG_OFFLOAD_MDNS_V6 + if (WAR_MDNS_V6_RSP_EN & pwrctl->wowlan_war_offload_ctrl) { + rsvd_page_loc->LocMdnsv6 = *page_num; + RTW_INFO("LocMdnsv6: %d\n", rsvd_page_loc->LocMdnsv6); + + rtw_hal_construct_mdns_rsp_v6(adapter, &pframe[index], &buf_len, pmlmeinfo->ip_addr); + rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], buf_len, _FALSE, _FALSE, _TRUE); + CurtPktPageNum = 16; + *page_num += CurtPktPageNum; + index += (CurtPktPageNum * page_size); + } +#endif /* CONFIG_OFFLOAD_MDNS_V6 */ + +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) + *(pframe+tmp_idx+25-tx_desc) = rsvd_page_loc->LocMdnsPara; + *(pframe+tmp_idx+26-tx_desc) = rsvd_page_loc->LocMdnsv4; + *(pframe+tmp_idx+27-tx_desc) = rsvd_page_loc->LocMdnsv6; +#endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */ + + } + //rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, rsvd_page_loc->LocIpParm, 46); +#endif /* CONFIG_WAR_OFFLOAD */ + +#if defined(CONFIG_WOW_PATTERN_IN_TXFIFO) + /* pattern_rsvd_page_loc will be used by rtw_read_from_frame_mask() */ + pwrctl->pattern_rsvd_page_loc = *page_num; + RTW_INFO("LocPatternInfo: %d\n", pwrctl->pattern_rsvd_page_loc); + rtw_hal_construct_pattern_info(adapter, + &pframe[index - tx_desc], + &PatternLen); + + /* Set cam_start_offset to REG_TXBUF_WKCAM_OFFSET + * Cam address(TxBufer pointer) access 8 bytes at a time + */ + + // Get rsvd page start page number + pattern located page + cam_start_offset = rtw_read8(adapter, REG_BCNQ_BDNY) + *page_num; + cam_start_offset *= page_size; + cam_start_offset /= 8; + + reg_cam_start_offset_val = rtw_read32(adapter, REG_TXBUF_WKCAM_OFFSET); + reg_cam_start_offset_val &= ~(WKCAM_OFFSET_BIT_MASK << WKCAM_OFFSET_BIT_MASK_OFFSET); + reg_cam_start_offset_val |= (cam_start_offset << WKCAM_OFFSET_BIT_MASK_OFFSET); + rtw_write32(adapter, REG_TXBUF_WKCAM_OFFSET, reg_cam_start_offset_val); + + /* Set pattern number to REG_WKFMCAM_NUM */ + rtw_write8(adapter, REG_WKFMCAM_NUM, PatternLen / WKFMCAM_SIZE); + + CurtPktPageNum = (u8)PageNum(PatternLen, page_size); + *page_num += CurtPktPageNum; + index += (CurtPktPageNum * page_size); + RSVD_PAGE_CFG("WOW-PatternInfo", CurtPktPageNum, *page_num, index); + +#endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */ + + /*Reserve 1 page for AOAC report*/ + rsvd_page_loc->LocAOACReport = *page_num; + RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport); + *page_num += 1; + *total_pkt_len = index + (page_size * 1); + RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len); + + + } else { +#ifdef CONFIG_PNO_SUPPORT + if (pwrctl->wowlan_in_resume == _FALSE && + pwrctl->pno_inited == _TRUE) { + + /* Broadcast Probe Request */ + rsvd_page_loc->LocProbePacket = *page_num; + + RTW_INFO("loc_probe_req: %d\n", + rsvd_page_loc->LocProbePacket); + + rtw_hal_construct_ProbeReq( + adapter, + &pframe[index], + &ProbeReqLength, + NULL); + + rtw_hal_fill_fake_txdesc(adapter, + &pframe[index - tx_desc], + ProbeReqLength, _FALSE, _FALSE, _FALSE); + + CurtPktPageNum = + (u8)PageNum(tx_desc + ProbeReqLength, page_size); + + *page_num += CurtPktPageNum; + + index += (CurtPktPageNum * page_size); + RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0); + + /* Hidden SSID Probe Request */ + ssid_num = pwrctl->pnlo_info->hidden_ssid_num; + + for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) { + pwrctl->pnlo_info->loc_probe_req[pno_index] = + *page_num; + + rtw_hal_construct_ProbeReq( + adapter, + &pframe[index], + &ProbeReqLength, + &pwrctl->pno_ssid_list->node[pno_index]); + + rtw_hal_fill_fake_txdesc(adapter, + &pframe[index - tx_desc], + ProbeReqLength, _FALSE, _FALSE, _FALSE); + + CurtPktPageNum = + (u8)PageNum(tx_desc + ProbeReqLength, page_size); + + *page_num += CurtPktPageNum; + + index += (CurtPktPageNum * page_size); + RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0); + } + + /* PNO INFO Page */ + rsvd_page_loc->LocPNOInfo = *page_num; + RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo); + rtw_hal_construct_PNO_info(adapter, + &pframe[index - tx_desc], + &PNOLength); + + CurtPktPageNum = (u8)PageNum(PNOLength, page_size); + *page_num += CurtPktPageNum; + index += (CurtPktPageNum * page_size); + RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0); + + /* Scan Info Page */ + rsvd_page_loc->LocScanInfo = *page_num; + RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo); + rtw_hal_construct_scan_info(adapter, + &pframe[index - tx_desc], + &ScanInfoLength); + + CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size); + *page_num += CurtPktPageNum; + *total_pkt_len = index + ScanInfoLength; + index += (CurtPktPageNum * page_size); + RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len); + } +#endif /* CONFIG_PNO_SUPPORT */ + } +} #endif /*CONFIG_WOWLAN*/ #ifdef CONFIG_P2P_WOWLAN @@ -10568,30 +11570,32 @@ exit: } #endif /* CONFIG_RTL8822C */ -static void rtw_hal_build_lps_pg_info_rsvd_page(_adapter *adapter, u8 *buf, u32 *buf_size) +static void rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv *dvobj, _adapter *ld_sta_iface, u8 *buf, u32 *buf_size) { #define LPS_PG_INFO_RSVD_LEN 16 - struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); - struct sta_info *psta; -#ifdef CONFIG_MBSSID_CAM - u8 cam_id = INVALID_CAM_ID; -#endif - u8 *psec_cam_id = buf + 8; - u8 sec_cam_num = 0; - u8 drv_rsvdpage_num = 0; - if (buf) { - psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv)); - if (!psta) { - RTW_ERR("%s [ERROR] sta is NULL\n", __func__); - rtw_warn_on(1); - return; - } + _adapter *adapter = dvobj_get_primary_adapter(dvobj); + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); + struct sta_info *psta; +#ifdef CONFIG_MBSSID_CAM + u8 cam_id = INVALID_CAM_ID; +#endif + u8 *psec_cam_id = buf + 8; + u8 sec_cam_num = 0; + u8 drv_rsvdpage_num = 0; - /*Byte 0 - used macid*/ - LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id); - RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id); + if (ld_sta_iface) { + psta = rtw_get_stainfo(&ld_sta_iface->stapriv, get_bssid(&ld_sta_iface->mlmepriv)); + if (!psta) { + RTW_ERR("%s [ERROR] sta is NULL\n", __func__); + rtw_warn_on(1); + goto size_chk; + } + /*Byte 0 - used macid*/ + LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id); + RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id); + } #ifdef CONFIG_MBSSID_CAM /*Byte 1 - used BSSID CAM entry*/ @@ -10603,8 +11607,8 @@ static void rtw_hal_build_lps_pg_info_rsvd_page(_adapter *adapter, u8 *buf, u32 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/ /*Btye 2 - Max used Pattern Match CAM entry*/ - if (pwrpriv->wowlan_mode == _TRUE && - check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _TRUE) { + if (pwrpriv->wowlan_mode == _TRUE + && ld_sta_iface && check_fwstate(&ld_sta_iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) { LPSPG_RSVD_PAGE_SET_PMC_NUM(buf, pwrpriv->wowlan_pattern_idx); RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx); } @@ -10632,6 +11636,7 @@ static void rtw_hal_build_lps_pg_info_rsvd_page(_adapter *adapter, u8 *buf, u32 RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num); } +size_chk: if (buf_size) *buf_size = LPS_PG_INFO_RSVD_LEN; } @@ -10646,7 +11651,7 @@ static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter) int ret = _FAIL; /* get length */ - rtw_hal_build_lps_pg_info_rsvd_page(adapter, NULL, &info_len); + rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, NULL, &info_len); if (!info_len) { RTW_ERR("get %s length fail\n", cache->name); goto exit; @@ -10660,7 +11665,7 @@ static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter) } /* get content */ - rtw_hal_build_lps_pg_info_rsvd_page(adapter, info, NULL); + rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, info, NULL); if (rsvd_page_cache_update_data(cache, info, info_len)) { @@ -10689,17 +11694,24 @@ exit: } static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index - , u8 txdesc_size, u32 page_size, u8 *total_page_num, bool is_wow_mode, bool only_get_page_num) + , u8 txdesc_size, u32 page_size, u8 *total_page_num + , bool is_wow_mode, _adapter *ld_sta_iface, bool only_get_page_num) { HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter); struct rsvd_page_cache_t *cache; + bool rsvd = 1; u8 *pos; u32 len; - /* lps_level will not change when enter wow_mode */ - if (is_wow_mode && pwrctl->lps_level != LPS_PG) - return; + if (is_wow_mode) { + /* lps_level will not change when enter wow_mode */ + if (pwrctl->lps_level != LPS_PG) + rsvd = 0; + } else { + if (!only_get_page_num && !ld_sta_iface) + rsvd = 0; + } pos = only_get_page_num ? NULL : frame + *index; @@ -10707,59 +11719,67 @@ static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index if (IS_8822C_SERIES(hal_data->version_id)) { /* LPSPG_DPK_INFO */ cache = &pwrctl->lpspg_dpk_info; - if (pwrctl->lps_level != LPS_PG) - pos = NULL; - halrf_dpk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len); - if (pos) { - #if (DBG_LPSPG_INFO_DUMP >= 1) - RTW_INFO_DUMP(cache->name, pos, len); - #endif - } - rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len); - *total_page_num += cache->page_num; - *index += page_size * cache->page_num; - pos = only_get_page_num ? NULL : frame + *index; - RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index); - - /* LPSPG_IQK_INFO */ - cache = &pwrctl->lpspg_iqk_info; - if (!(is_wow_mode && hal_data->RegIQKFWOffload)) { /* RegIQKFWOffload will not change when enter wow_mode */ - if (pwrctl->lps_level != LPS_PG || hal_data->RegIQKFWOffload) + if (rsvd) { + if (pwrctl->lps_level != LPS_PG) pos = NULL; - halrf_iqk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len); - if (pos) { - #if (DBG_LPSPG_INFO_DUMP >= 1) + len = 0; + halrf_dpk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len); + #if (DBG_LPSPG_INFO_DUMP >= 1) + if (pos) RTW_INFO_DUMP(cache->name, pos, len); - #endif - } + #endif rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len); *total_page_num += cache->page_num; *index += page_size * cache->page_num; pos = only_get_page_num ? NULL : frame + *index; RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index); } else - rsvd_page_cache_free_data(cache); + rsvd_page_cache_free(cache); + + /* LPSPG_IQK_INFO */ + cache = &pwrctl->lpspg_iqk_info; + if (rsvd + /* RegIQKFWOffload will not change when enter wow_mode */ + && !(is_wow_mode && hal_data->RegIQKFWOffload) + ) { + if (pwrctl->lps_level != LPS_PG || hal_data->RegIQKFWOffload) + pos = NULL; + len = 0; + halrf_iqk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len); + #if (DBG_LPSPG_INFO_DUMP >= 1) + if (pos) + RTW_INFO_DUMP(cache->name, pos, len); + #endif + rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len); + *total_page_num += cache->page_num; + *index += page_size * cache->page_num; + pos = only_get_page_num ? NULL : frame + *index; + RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index); + } else + rsvd_page_cache_free(cache); } #endif /* LPSPG_INFO */ cache = &pwrctl->lpspg_info; - if (pwrctl->lps_level != LPS_PG) - pos = NULL; - rtw_hal_build_lps_pg_info_rsvd_page(adapter, pos, &len); - if (pos) { + if (rsvd) { + if (pwrctl->lps_level != LPS_PG) + pos = NULL; + rtw_hal_build_lps_pg_info_rsvd_page(adapter_to_dvobj(adapter), ld_sta_iface, pos, &len); #if (DBG_LPSPG_INFO_DUMP >= 1) - RTW_INFO_DUMP(cache->name, pos, len); + if (pos) + RTW_INFO_DUMP(cache->name, pos, len); #endif - } - rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len); - *total_page_num += cache->page_num; - *index += page_size * cache->page_num; - pos = only_get_page_num ? NULL : frame + *index; - RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index); + rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len); + *total_page_num += cache->page_num; + *index += page_size * cache->page_num; + pos = only_get_page_num ? NULL : frame + *index; + RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index); + } else + rsvd_page_cache_free(cache); } -static u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter) +u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter) { struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); struct mlme_priv *pmlmepriv = &adapter->mlmepriv; @@ -10776,7 +11796,7 @@ static u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter) #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM) if (pwrpriv->wowlan_mode == _TRUE && - check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1); /*PatternMatchCAM_En*/ } @@ -10797,9 +11817,15 @@ static u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter) SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_info.loc); #ifdef CONFIG_RTL8822C - SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc); - if (!GET_HAL_DATA(adapter)->RegIQKFWOffload) - SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc); + if (pwrpriv->bFwCurrentInPSMode == _FALSE) { + SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc); + if (!GET_HAL_DATA(adapter)->RegIQKFWOffload) + SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc); + } else { + SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, 0); + if (!GET_HAL_DATA(adapter)->RegIQKFWOffload) + SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, 0); + } #endif #if (DBG_LPSPG_INFO_DUMP >= 1) @@ -10928,7 +11954,7 @@ static _adapter *_rtw_search_sta_iface(_adapter *adapter) for (i = 0; i < dvobj->iface_nums; i++) { iface = dvobj->padapters[i]; if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) { - if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) { + if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) { sta_iface = iface; break; } @@ -11098,7 +12124,7 @@ static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page BeaconLength = MAX_BEACON_LEN - TxDescLen; CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize); -#ifdef CONFIG_FW_HANDLE_TXBCN +#if defined(CONFIG_FW_HANDLE_TXBCN) || defined(CONFIG_PORT_BASED_TXBCN) CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM; #endif TotalPageNum += CurtPktPageNum; @@ -11220,7 +12246,7 @@ static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/ ap_iface = adapter; - #ifdef CONFIG_CONCURRENT_MODE + #if defined (CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE) if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) { /*DEV_AP_STARTING_NUM*/ ap_iface = _rtw_search_ap_iface(adapter); RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface)); @@ -11269,6 +12295,8 @@ static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page CurtPktPageNum = (u8)PageNum(TxDescLen + fw_dbg_msg_pkt_len, PageSize); + if (CurtPktPageNum < 2) + CurtPktPageNum = 2; /*Need at least 2 rsvd page*/ TotalPageNum += CurtPktPageNum; TotalPacketLen = BufIndex + fw_dbg_msg_pkt_len; @@ -11277,7 +12305,10 @@ static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page #ifdef CONFIG_LPS_PG rtw_lps_pg_set_rsvd_page(adapter, ReservedPagePacket, &BufIndex - , TxDescLen, PageSize, &TotalPageNum, is_wow_mode, page_num ? 1 : 0); + , TxDescLen, PageSize, &TotalPageNum, is_wow_mode + , (sta_iface && MLME_IS_STA(sta_iface) && MLME_IS_ASOC(sta_iface)) ? sta_iface : NULL + , page_num ? 1 : 0 + ); TotalPacketLen = BufIndex; #endif @@ -11285,10 +12316,13 @@ static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page /*======== WOW * n page ======== */ if (pwrctl->wowlan_mode == _TRUE && pwrctl->wowlan_in_resume == _FALSE && - !(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, _FW_LINKED))) {/*WOW mode*/ + check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {/*WOW mode*/ rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket, BufIndex, TxDescLen, PageSize, &TotalPageNum, &TotalPacketLen, &RsvdPageLoc); +#ifdef CONFIG_WAR_OFFLOAD + rtw_hal_set_war_offload_parm(adapter, &RsvdPageLoc); +#endif /* CONFIG_WAR_OFFLOAD */ } #endif /* CONFIG_WOWLAN */ @@ -11349,7 +12383,7 @@ download_page: #endif - if (check_fwstate(pmlmepriv, _FW_LINKED) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) || MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)){ rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc); #ifdef DBG_FW_DEBUG_MSG_PKT @@ -11388,12 +12422,43 @@ error: void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished) { +#ifdef CONFIG_AP_MODE if (finished) rtw_mi_tx_beacon_hdl(adapter); else +#endif _rtw_hal_set_fw_rsvd_page(adapter, finished, NULL); } +static u8 rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(struct _ADAPTER *adapter, u8 enable) +{ + u8 u1H2CSetPwrMode[H2C_PWRMODE_LEN] = {0}; + u8 ret = _FAIL; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_TDLS_CH_SW + if (ATOMIC_READ(&adapter->tdlsinfo.chsw_info.chsw_on) == _TRUE) + { + SET_H2CCMD_PWRMODE_PARM_RLBM(u1H2CSetPwrMode, 1); + SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CSetPwrMode, 0); + } +#endif +#endif + + SET_H2CCMD_PWRMODE_PARM_MODE(u1H2CSetPwrMode, 0); + SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CSetPwrMode, 0x0C); + SET_H2CCMD_PWRMODE_PARM_BCN_EARLY_C2H_RPT(u1H2CSetPwrMode, enable); + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_SET_PWR_MODE, + H2C_PWRMODE_LEN, + u1H2CSetPwrMode); + + RTW_PRINT("-%s()-\n", __func__); + + return ret; +} + /** * rtw_hal_get_rsvd_page_num() - Get needed reserved page number * @adapter: struct _ADAPTER* @@ -11568,7 +12633,7 @@ static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable) * 3. doesn't enable TSF update & buddy TSF right now to avoid HW conflict * so, we enable TSF update when rx first BCN after sitesurvey done */ - if (rtw_mi_check_fwstate(adapter, _FW_LINKED | WIFI_AP_STATE | WIFI_MESH_STATE)) { + if (rtw_mi_check_fwstate(adapter, WIFI_ASOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE)) { /* enable to rx data frame */ rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF); } @@ -11587,10 +12652,12 @@ static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable) } #endif + #ifdef CONFIG_AP_MODE if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) { ResumeTxBeacon(adapter); rtw_mi_tx_beacon_hdl(adapter); } + #endif } } @@ -11903,6 +12970,7 @@ void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state) } } break; +#ifdef CONFIG_AP_MODE case MLME_AP_STARTED : case MLME_MESH_STARTED : { @@ -11942,6 +13010,7 @@ void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state) } } break; +#endif /* CONFIG_AP_MODE */ default : RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state); break; @@ -12035,6 +13104,7 @@ static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state) if (iface == adapter) continue; + #ifdef CONFIG_AP_MODE if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface)) && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE ) { @@ -12044,7 +13114,14 @@ static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state) RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n" , __func__, ADPT_ARG(iface), iface->hw_port); #endif /* CONFIG_TSF_RESET_OFFLOAD*/ + #ifdef CONFIG_TSF_SYNC + if(iface->hw_port == HW_PORT0) + rtw_write8(iface, REG_DUAL_TSF_RST, rtw_read8(iface, REG_DUAL_TSF_RST) | BIT(2)); + else if(iface->hw_port == HW_PORT1) + rtw_write8(iface, REG_DUAL_TSF_RST, rtw_read8(iface, REG_DUAL_TSF_RST) | BIT(3)); + #endif } + #endif /* CONFIG_AP_MODE */ } } #endif /* CONFIG_CONCURRENT_MODE */ @@ -12242,8 +13319,8 @@ void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode) return; } #endif /* CONFIG_LPS_ACK */ + } } -} void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) { @@ -12299,10 +13376,10 @@ void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) { RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted); /* Set RRSR rate table. */ - temp_RRSR = rtw_read32(padapter, REG_RRSR); - temp_RRSR &=0xFFFF0000; - temp_RRSR |=BrateCfg; - rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE); + temp_RRSR = rtw_read32(padapter, REG_RRSR); + temp_RRSR &=0xFFFF0000; + temp_RRSR |=BrateCfg; + rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE); rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0); @@ -12619,6 +13696,9 @@ u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val) rtw_read8(adapter, REG_CR + 1) & ~BIT(0)); break; #endif + case HW_VAR_BCN_EARLY_C2H_RPT: + rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(adapter, *(u8 *)val); + break; default: if (0) RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n", @@ -12638,7 +13718,9 @@ void GetHwReg(_adapter *adapter, u8 variable, u8 *val) switch (variable) { case HW_VAR_MAC_ADDR: + #ifndef CONFIG_MI_WITH_MBSSID_CAM rtw_hal_get_macaddr_port(adapter, val); + #endif break; case HW_VAR_BASIC_RATE: *((u16 *)val) = hal_data->BasicRateSet; @@ -12919,24 +14001,6 @@ GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value) return bResult; } - -BOOLEAN -eqNByte( - u8 *str1, - u8 *str2, - u32 num -) -{ - if (num == 0) - return _FALSE; - while (num > 0) { - num--; - if (str1[num] != str2[num]) - return _FALSE; - } - return _TRUE; -} - /* * Description: * Translate a character to hex digit. @@ -13172,7 +14236,8 @@ void rtw_hal_check_rxfifo_full(_adapter *adapter) IS_8192E(pHalData->version_id) || IS_8703B_SERIES(pHalData->version_id) || IS_8723D_SERIES(pHalData->version_id) || - IS_8192F_SERIES(pHalData->version_id)) { + IS_8192F_SERIES(pHalData->version_id) || + IS_8822C_SERIES(pHalData->version_id)) { rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0); save_cnt = _TRUE; } else { @@ -13228,7 +14293,7 @@ void linked_info_dump(_adapter *padapter, u8 benable) void rtw_get_raw_rssi_info(void *sel, _adapter *padapter) { u8 isCCKrate, rf_path; - PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info; RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n", HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all); @@ -13237,7 +14302,9 @@ void rtw_get_raw_rssi_info(void *sel, _adapter *padapter) if (isCCKrate) psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball; - for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) { + for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) { + if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path))) + continue; RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n" , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]); @@ -13251,7 +14318,7 @@ void rtw_get_raw_rssi_info(void *sel, _adapter *padapter) void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel) { u8 isCCKrate, rf_path; - PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info; _RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n"); _RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n", HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all); @@ -13261,7 +14328,9 @@ void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel) if (isCCKrate) psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball; - for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) { + for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) { + if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path))) + continue; _RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)" , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]); @@ -13284,7 +14353,7 @@ void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel) _irqL irqL; u8 isCCKrate, rf_path; struct recv_priv *precvpriv = &(padapter->recvpriv); - PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); struct sta_priv *pstapriv = &padapter->stapriv; struct sta_info *psta; struct sta_recv_dframe_info *psta_dframe_info; @@ -13330,7 +14399,9 @@ void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel) RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", ch_width_str(psta_dframe_info->sta_bw_mode), psta_dframe_info->sta_sgi); RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate)); - for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) { + for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) { + if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path))) + continue; if (!isCCKrate) { RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]); _RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]); @@ -13356,7 +14427,7 @@ void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe) struct sta_recv_dframe_info *psta_dframe_info; #endif struct recv_priv *precvpriv = &(padapter->recvpriv); - PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; struct sta_info *psta = prframe->u.hdr.psta; struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info; @@ -13373,7 +14444,7 @@ void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe) psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all; psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power; - for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) { + for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) { psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path]; psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path]; if (!isCCKrate) { @@ -13396,7 +14467,7 @@ void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe) psta_dframe_info->sta_data_rate = pattrib->data_rate; psta_dframe_info->sta_sgi = pattrib->sgi; psta_dframe_info->sta_bw_mode = pattrib->bw; - for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) { + for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) { psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/ @@ -13572,6 +14643,15 @@ int hal_efuse_macaddr_offset(_adapter *adapter) addr_offset = EEPROM_MAC_ADDR_8814BE; break; #endif /* CONFIG_RTL8814B */ + +#ifdef CONFIG_RTL8723F + case RTL8723F: + if (interface_type == RTW_USB) + addr_offset = EEPROM_MAC_ADDR_8723FU; + else if (interface_type == RTW_SDIO) + addr_offset = EEPROM_MAC_ADDR_8723FS; + break; +#endif /* CONFIG_RTL8723F */ } if (addr_offset == -1) { @@ -13624,6 +14704,9 @@ u32 Hal_readPGDataFromConfigFile(PADAPTER padapter) HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter); u32 ret = _FALSE; u32 maplen = 0; +#ifdef CONFIG_MP_INCLUDED + struct mp_priv *pmp_priv = &padapter->mppriv; +#endif EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE); @@ -13631,8 +14714,16 @@ u32 Hal_readPGDataFromConfigFile(PADAPTER padapter) RTW_ERR("eFuse length error :%d\n", maplen); return _FALSE; } - - ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen); +#ifdef CONFIG_MP_INCLUDED + if (pmp_priv->efuse_update_file == _TRUE && (rtw_mp_mode_check(padapter))) { + RTW_INFO("%s, eFuse read from file :%s\n", __func__, pmp_priv->efuse_file_path); + ret = rtw_read_efuse_from_file(pmp_priv->efuse_file_path, hal_data->efuse_eeprom_data, maplen); + pmp_priv->efuse_update_file = _FALSE; + } else +#endif + { + ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen); + } hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED); @@ -13955,12 +15046,13 @@ void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer) #ifdef RTW_HALMAC if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter) - || IS_HARDWARE_TYPE_8822CU(padapter) || IS_HARDWARE_TYPE_8814BU(padapter)) + || IS_HARDWARE_TYPE_8822CU(padapter) || IS_HARDWARE_TYPE_8814BU(padapter) + || IS_HARDWARE_TYPE_8723FU(padapter)) rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL); #else /* !RTW_HALMAC */ if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */ /* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */ - if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) { + if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) { if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30) rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010); else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30) @@ -14002,6 +15094,7 @@ void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer) /* bus-agg check for SoftAP mode */ inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel) { +#ifdef CONFIG_AP_MODE struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); u8 chk_rst = _SUCCESS; @@ -14018,8 +15111,12 @@ inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qse chk_rst = _FAIL; } return chk_rst; +#else + return _SUCCESS; +#endif /* CONFIG_AP_MODE */ } +#ifdef CONFIG_WOWLAN /* * Description: * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload @@ -14064,6 +15161,7 @@ void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size) printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); } } +#endif #ifdef CONFIG_GPIO_API u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num) @@ -14418,7 +15516,15 @@ void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_coun vht_err = phy_query_bb_reg(padapter, 0x2c0c, 0xffff0000); CCK_FA = phy_query_bb_reg(padapter, 0x1a5c, bMaskLWord); OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord); - + } else if(IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)){ + cckok = phy_query_bb_reg(padapter, 0x2aac, 0xffff); + ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff); + htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff); + cckcrc = phy_query_bb_reg(padapter, 0x2aac, 0xffff0000); + ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000); + htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000); + CCK_FA = phy_query_bb_reg(padapter, 0x2aa8, 0xffff0000) + phy_query_bb_reg(padapter, 0x2aa8, 0x0000ffff); + OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord); } else { cckok = phy_query_bb_reg(padapter, 0xF88, bMaskDWord); ofdmok = phy_query_bb_reg(padapter, 0xF94, bMaskLWord); @@ -14428,9 +15534,9 @@ void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_coun ofdmcrc = phy_query_bb_reg(padapter, 0xF94, bMaskHWord); htcrc = phy_query_bb_reg(padapter, 0xF90, bMaskHWord); vht_err = 0; - OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF2, bMaskLWord) + - phy_query_bb_reg(padapter, 0xDA2, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) + - phy_query_bb_reg(padapter, 0xDA6, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord); + OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF0, bMaskHWord) + + phy_query_bb_reg(padapter, 0xDA0, bMaskHWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) + + phy_query_bb_reg(padapter, 0xDA4, bMaskHWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord); CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C)); } @@ -14447,7 +15553,7 @@ void rtw_reset_phy_trx_ok_counters(_adapter *padapter) if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) { phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1); phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0); - } else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)) { + } else if(IS_HARDWARE_TYPE_JAGUAR3(padapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)) { phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x1); phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x0); } else { @@ -14467,6 +15573,11 @@ void rtw_reset_phy_rx_counters(_adapter *padapter) /* reset CCK CCA counter */ phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 0); phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 2); + + } else if (IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)) { + /* reset CCK FA and CCK CCA counter */ + phy_set_bb_reg(padapter, 0x2a44, BIT21, 0); + phy_set_bb_reg(padapter, 0x2a44, BIT21, 1); rtw_reset_phy_trx_ok_counters(padapter); } else if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) { @@ -14771,6 +15882,11 @@ int hal_spec_init(_adapter *adapter) case RTL8814B: rtl8814b_init_hal_spec(adapter); break; +#endif +#ifdef CONFIG_RTL8723F + case RTL8723F: + rtl8723f_init_hal_spec(adapter); + break; #endif default: RTW_ERR("%s: unknown chip_type:%u\n" @@ -14824,6 +15940,8 @@ void dump_hal_spec(void *sel, _adapter *adapter) RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g); RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g); RTW_PRINT_SEL(sel, "rf_reg_path_num:%u\n", hal_spec->rf_reg_path_num); + RTW_PRINT_SEL(sel, "rf_reg_path_avail_num:%u\n", hal_spec->rf_reg_path_avail_num); + RTW_PRINT_SEL(sel, "rf_reg_trx_path_bmp:0x%02x\n", hal_spec->rf_reg_trx_path_bmp); RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt); RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num); @@ -14962,8 +16080,14 @@ u8 hal_largest_bw(_adapter *adapter, u8 in_bw) #ifndef CONFIG_HAS_TX_BEACON_PAUSE void ResumeTxBeacon(_adapter *padapter) { + RTW_DBG("ResumeTxBeacon\n"); + #ifdef CONFIG_STOP_RESUME_BCN_BY_TXPAUSE + rtw_write8(padapter, REG_TXPAUSE, + rtw_read8(padapter, REG_TXPAUSE) & (~BIT6)); + #else rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6)); + #endif #ifdef RTW_HALMAC /* Add this for driver using HALMAC because driver doesn't have setup time init by self */ @@ -14979,8 +16103,14 @@ void ResumeTxBeacon(_adapter *padapter) void StopTxBeacon(_adapter *padapter) { + RTW_DBG("StopTxBeacon\n"); + #ifdef CONFIG_STOP_RESUME_BCN_BY_TXPAUSE + rtw_write8(padapter, REG_TXPAUSE, + rtw_read8(padapter, REG_TXPAUSE) | BIT6); + #else rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6)); + #endif /* TBTT hold time: 0x540[19:8] */ rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF); @@ -15163,6 +16293,7 @@ void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_B } #endif +#ifdef CONFIG_PROC_DEBUG #ifdef CONFIG_PHY_CAPABILITY_QUERY void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter) { @@ -15263,6 +16394,7 @@ void rtw_dump_phy_cap(void *sel, _adapter *adapter) rtw_dump_phy_cap_by_hal(sel, adapter); #endif } +#endif inline s16 translate_dbm_to_percentage(s16 signal) { @@ -15358,6 +16490,7 @@ void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch); SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx); SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw); + SET_H2CCMD_SINGLE_CH_SWITCH_V2_IQK_UPDATE_EN(h2c, 1); rtw_sctx_init(chsw_sctx, 10); rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c); @@ -15365,21 +16498,37 @@ void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 } #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */ -u8 phy_get_current_tx_num( - PADAPTER pAdapter, - u8 Rate -) +u8 phy_get_capable_tx_num(_adapter *adapter, enum MGN_RATE rate) { - HAL_DATA_TYPE *hal_data = GET_HAL_DATA(pAdapter); - u8 tx_num = 0; + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + u8 tx_num = 0; - if (IS_1T_RATE(Rate)) + if (IS_1T_RATE(rate)) + tx_num = hal_data->txpath_cap_num_nss[0]; + else if (IS_2T_RATE(rate)) + tx_num = hal_data->txpath_cap_num_nss[1]; + else if (IS_3T_RATE(rate)) + tx_num = hal_data->txpath_cap_num_nss[2]; + else if (IS_4T_RATE(rate)) + tx_num = hal_data->txpath_cap_num_nss[3]; + else + rtw_warn_on(1); + + return tx_num == 0 ? RF_1TX : tx_num - 1; +} + +u8 phy_get_current_tx_num(_adapter *adapter, enum MGN_RATE rate) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + u8 tx_num = 0; + + if (IS_1T_RATE(rate)) tx_num = hal_data->txpath_num_nss[0]; - else if (IS_2T_RATE(Rate)) + else if (IS_2T_RATE(rate)) tx_num = hal_data->txpath_num_nss[1]; - else if (IS_3T_RATE(Rate)) + else if (IS_3T_RATE(rate)) tx_num = hal_data->txpath_num_nss[2]; - else if (IS_4T_RATE(Rate)) + else if (IS_4T_RATE(rate)) tx_num = hal_data->txpath_num_nss[3]; else rtw_warn_on(1); @@ -15531,3 +16680,17 @@ void rtw_leave_protsel_macsleep(_adapter *padapter) rtw_leave_protsel(&padapter->dvobj->protsel_macsleep); } #endif + +void rtw_hal_bcn_early_rpt_c2h_handler(_adapter *padapter) +{ + + if(0) + RTW_INFO("Recv Bcn Early report!!\n"); + +#ifdef CONFIG_TDLS +#ifdef CONFIG_TDLS_CH_SW + if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE) + rtw_tdls_ch_sw_back_to_base_chnl(padapter); +#endif +#endif +} diff --git a/hal/hal_com_c2h.h b/hal/hal_com_c2h.h index 956a526..b9aa9ff 100644 --- a/hal/hal_com_c2h.h +++ b/hal/hal_com_c2h.h @@ -75,6 +75,7 @@ typedef enum _C2H_EVT { C2H_PER_RATE_RPT = 0x2c, #endif C2H_LPS_STATUS_RPT = 0x32, + C2H_SET_TXPWR_FINISH = 0x70, C2H_DEFEATURE_RSVD = 0xFD, C2H_EXTEND = 0xff, } C2H_EVT; @@ -128,4 +129,14 @@ int c2h_per_rate_rpt_hdl(_adapter *adapter, u8 *data, u8 len); #define LPS_STATUS_RPT_LEN 2 int c2h_lps_status_rpt(PADAPTER adapter, u8 *data, u8 len); #endif /* CONFIG_LPS_ACK */ + +#ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX +/* C2H_SET_TXPWR_FINISH, 0x70 */ +#define SET_TXPWR_FINISH_LEN 1 +void c2h_txpwr_idx_offload_done(_adapter *adapter, u8 *data, u8 len); +int c2h_txpwr_idx_offload_wait(_adapter *adapter); +#endif + +void rtw_hal_bcn_early_rpt_c2h_handler(_adapter *adapter); + #endif /* __COMMON_C2H_H__ */ diff --git a/hal/hal_com_phycfg.c b/hal/hal_com_phycfg.c index 44406ed..38c07c7 100644 --- a/hal/hal_com_phycfg.c +++ b/hal/hal_com_phycfg.c @@ -410,6 +410,19 @@ static const struct map_t rtl8822c_pg_txpwr_def_info = ); #endif +#ifdef CONFIG_RTL8723F +static const struct map_t rtl8723f_pg_txpwr_def_info = + MAP_ENT(0xB8, 1, 0xFF + , MAPSEG_ARRAY_ENT(0x10, 82, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x02, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x02, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x02, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x02, 0x00, 0xFF, 0xFF, 0x00, 0xFF, + 0x00, 0x00) + ); +#endif + #ifdef CONFIG_RTL8814A static const struct map_t rtl8814a_pg_txpwr_def_info = MAP_ENT(0xB8, 1, 0xFF @@ -543,6 +556,11 @@ const struct map_t *hal_pg_txpwr_def_info(_adapter *adapter) case RTL8814B: map = &rtl8814b_pg_txpwr_def_info; break; +#endif +#ifdef CONFIG_RTL8723F + case RTL8723F: + map = &rtl8723f_pg_txpwr_def_info; + break; #endif } @@ -1085,7 +1103,15 @@ int check_phy_efuse_tx_power_info_valid(_adapter *adapter) #if CONFIG_IEEE80211_BAND_5GHZ u8 valid_5g_path_bmp = 0; #endif +#ifdef CONFIG_MP_INCLUDED + struct mp_priv *pmp_priv = &adapter->mppriv; + + if (pmp_priv->efuse_update_file == _TRUE && (rtw_mp_mode_check(adapter))) { + RTW_INFO("%s: To use efuse_update_file !!!\n", __func__); + return _FALSE; + } +#endif /* NOTE: TSSI offset use the same layout as TXPWR base */ for (path = 0; path < MAX_RF_PATH; path++) { @@ -1653,6 +1679,9 @@ static void phy_txpwr_by_rate_chk_for_path_dup(_adapter *adapter) } } +static s8 _phy_get_txpwr_by_rate(_adapter *adapter + , BAND_TYPE band, enum rf_path rfpath, enum MGN_RATE rate); + void phy_store_target_tx_power(PADAPTER pAdapter) { struct hal_spec_t *hal_spec = GET_HAL_SPEC(pAdapter); @@ -1682,7 +1711,7 @@ void phy_store_target_tx_power(PADAPTER pAdapter) if (regsty->target_tx_pwr_valid == _TRUE) base = hal_spec->txgi_pdbm * rtw_regsty_get_target_tx_power(pAdapter, band, path, rs); else - base = _PHY_GetTxPowerByRate(pAdapter, band, path, rate_sec_base[rs]); + base = _phy_get_txpwr_by_rate(pAdapter, band, path, rate_sec_base[rs]); phy_set_target_txpwr(pAdapter, band, path, rs, base); } } @@ -2112,7 +2141,7 @@ PHY_StoreTxPowerByRateNew( } for (i = 0; i < rateNum; ++i) { - u8 rate_idx = PHY_GetRateIndexOfTxPowerByRate(rates[i]); + u8 rate_idx = phy_get_rate_idx_of_txpwr_by_rate(rates[i]); pHalData->TxPwrByRate[Band][RfPath][rate_idx] = PwrByRateVal[i]; } @@ -2167,6 +2196,10 @@ PHY_TxPowerByRateConfiguration( phy_store_target_tx_power(pAdapter); } +#ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX +extern bool phy_set_txpwr_idx_offload(_adapter *adapter); +#endif + void phy_set_tx_power_index_by_rate_section( PADAPTER pAdapter, @@ -2205,6 +2238,11 @@ phy_set_tx_power_index_by_rate_section( PHY_SetTxPowerIndex(pAdapter, powerIndex, RFPath, rates_by_sections[rs].rates[i]); } +#ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX + if (!hal_data->set_entire_txpwr + && phy_set_txpwr_idx_offload(pAdapter)) + rtw_hal_set_txpwr_done(pAdapter); +#endif exit: return; @@ -2466,346 +2504,229 @@ PHY_GetTxPowerTrackingOffset( return offset; } +static const u8 _phy_get_rate_idx_of_txpwr_by_rate[MGN_UNKNOWN] = { + [MGN_1M] = 0, + [MGN_2M] = 1, + [MGN_5_5M] = 2, + [MGN_11M] = 3, + [MGN_6M] = 4, + [MGN_9M] = 5, + [MGN_12M] = 6, + [MGN_18M] = 7, + [MGN_24M] = 8, + [MGN_36M] = 9, + [MGN_48M] = 10, + [MGN_54M] = 11, + [MGN_MCS0] = 12, + [MGN_MCS1] = 13, + [MGN_MCS2] = 14, + [MGN_MCS3] = 15, + [MGN_MCS4] = 16, + [MGN_MCS5] = 17, + [MGN_MCS6] = 18, + [MGN_MCS7] = 19, + [MGN_MCS8] = 20, + [MGN_MCS9] = 21, + [MGN_MCS10] = 22, + [MGN_MCS11] = 23, + [MGN_MCS12] = 24, + [MGN_MCS13] = 25, + [MGN_MCS14] = 26, + [MGN_MCS15] = 27, + [MGN_MCS16] = 28, + [MGN_MCS17] = 29, + [MGN_MCS18] = 30, + [MGN_MCS19] = 31, + [MGN_MCS20] = 32, + [MGN_MCS21] = 33, + [MGN_MCS22] = 34, + [MGN_MCS23] = 35, + [MGN_MCS24] = 36, + [MGN_MCS25] = 37, + [MGN_MCS26] = 38, + [MGN_MCS27] = 39, + [MGN_MCS28] = 40, + [MGN_MCS29] = 41, + [MGN_MCS30] = 42, + [MGN_MCS31] = 43, + [MGN_VHT1SS_MCS0] = 44, + [MGN_VHT1SS_MCS1] = 45, + [MGN_VHT1SS_MCS2] = 46, + [MGN_VHT1SS_MCS3] = 47, + [MGN_VHT1SS_MCS4] = 48, + [MGN_VHT1SS_MCS5] = 49, + [MGN_VHT1SS_MCS6] = 50, + [MGN_VHT1SS_MCS7] = 51, + [MGN_VHT1SS_MCS8] = 52, + [MGN_VHT1SS_MCS9] = 53, + [MGN_VHT2SS_MCS0] = 54, + [MGN_VHT2SS_MCS1] = 55, + [MGN_VHT2SS_MCS2] = 56, + [MGN_VHT2SS_MCS3] = 57, + [MGN_VHT2SS_MCS4] = 58, + [MGN_VHT2SS_MCS5] = 59, + [MGN_VHT2SS_MCS6] = 60, + [MGN_VHT2SS_MCS7] = 61, + [MGN_VHT2SS_MCS8] = 62, + [MGN_VHT2SS_MCS9] = 63, + [MGN_VHT3SS_MCS0] = 64, + [MGN_VHT3SS_MCS1] = 65, + [MGN_VHT3SS_MCS2] = 66, + [MGN_VHT3SS_MCS3] = 67, + [MGN_VHT3SS_MCS4] = 68, + [MGN_VHT3SS_MCS5] = 69, + [MGN_VHT3SS_MCS6] = 70, + [MGN_VHT3SS_MCS7] = 71, + [MGN_VHT3SS_MCS8] = 72, + [MGN_VHT3SS_MCS9] = 73, + [MGN_VHT4SS_MCS0] = 74, + [MGN_VHT4SS_MCS1] = 75, + [MGN_VHT4SS_MCS2] = 76, + [MGN_VHT4SS_MCS3] = 77, + [MGN_VHT4SS_MCS4] = 78, + [MGN_VHT4SS_MCS5] = 79, + [MGN_VHT4SS_MCS6] = 80, + [MGN_VHT4SS_MCS7] = 81, + [MGN_VHT4SS_MCS8] = 82, + [MGN_VHT4SS_MCS9] = 83, +}; + /*The same as MRateToHwRate in hal_com.c*/ -u8 -PHY_GetRateIndexOfTxPowerByRate( - u8 Rate -) +u8 phy_get_rate_idx_of_txpwr_by_rate(enum MGN_RATE rate) { - u8 index = 0; - switch (Rate) { - case MGN_1M: - index = 0; - break; - case MGN_2M: - index = 1; - break; - case MGN_5_5M: - index = 2; - break; - case MGN_11M: - index = 3; - break; - case MGN_6M: - index = 4; - break; - case MGN_9M: - index = 5; - break; - case MGN_12M: - index = 6; - break; - case MGN_18M: - index = 7; - break; - case MGN_24M: - index = 8; - break; - case MGN_36M: - index = 9; - break; - case MGN_48M: - index = 10; - break; - case MGN_54M: - index = 11; - break; - case MGN_MCS0: - index = 12; - break; - case MGN_MCS1: - index = 13; - break; - case MGN_MCS2: - index = 14; - break; - case MGN_MCS3: - index = 15; - break; - case MGN_MCS4: - index = 16; - break; - case MGN_MCS5: - index = 17; - break; - case MGN_MCS6: - index = 18; - break; - case MGN_MCS7: - index = 19; - break; - case MGN_MCS8: - index = 20; - break; - case MGN_MCS9: - index = 21; - break; - case MGN_MCS10: - index = 22; - break; - case MGN_MCS11: - index = 23; - break; - case MGN_MCS12: - index = 24; - break; - case MGN_MCS13: - index = 25; - break; - case MGN_MCS14: - index = 26; - break; - case MGN_MCS15: - index = 27; - break; - case MGN_MCS16: - index = 28; - break; - case MGN_MCS17: - index = 29; - break; - case MGN_MCS18: - index = 30; - break; - case MGN_MCS19: - index = 31; - break; - case MGN_MCS20: - index = 32; - break; - case MGN_MCS21: - index = 33; - break; - case MGN_MCS22: - index = 34; - break; - case MGN_MCS23: - index = 35; - break; - case MGN_MCS24: - index = 36; - break; - case MGN_MCS25: - index = 37; - break; - case MGN_MCS26: - index = 38; - break; - case MGN_MCS27: - index = 39; - break; - case MGN_MCS28: - index = 40; - break; - case MGN_MCS29: - index = 41; - break; - case MGN_MCS30: - index = 42; - break; - case MGN_MCS31: - index = 43; - break; - case MGN_VHT1SS_MCS0: - index = 44; - break; - case MGN_VHT1SS_MCS1: - index = 45; - break; - case MGN_VHT1SS_MCS2: - index = 46; - break; - case MGN_VHT1SS_MCS3: - index = 47; - break; - case MGN_VHT1SS_MCS4: - index = 48; - break; - case MGN_VHT1SS_MCS5: - index = 49; - break; - case MGN_VHT1SS_MCS6: - index = 50; - break; - case MGN_VHT1SS_MCS7: - index = 51; - break; - case MGN_VHT1SS_MCS8: - index = 52; - break; - case MGN_VHT1SS_MCS9: - index = 53; - break; - case MGN_VHT2SS_MCS0: - index = 54; - break; - case MGN_VHT2SS_MCS1: - index = 55; - break; - case MGN_VHT2SS_MCS2: - index = 56; - break; - case MGN_VHT2SS_MCS3: - index = 57; - break; - case MGN_VHT2SS_MCS4: - index = 58; - break; - case MGN_VHT2SS_MCS5: - index = 59; - break; - case MGN_VHT2SS_MCS6: - index = 60; - break; - case MGN_VHT2SS_MCS7: - index = 61; - break; - case MGN_VHT2SS_MCS8: - index = 62; - break; - case MGN_VHT2SS_MCS9: - index = 63; - break; - case MGN_VHT3SS_MCS0: - index = 64; - break; - case MGN_VHT3SS_MCS1: - index = 65; - break; - case MGN_VHT3SS_MCS2: - index = 66; - break; - case MGN_VHT3SS_MCS3: - index = 67; - break; - case MGN_VHT3SS_MCS4: - index = 68; - break; - case MGN_VHT3SS_MCS5: - index = 69; - break; - case MGN_VHT3SS_MCS6: - index = 70; - break; - case MGN_VHT3SS_MCS7: - index = 71; - break; - case MGN_VHT3SS_MCS8: - index = 72; - break; - case MGN_VHT3SS_MCS9: - index = 73; - break; - case MGN_VHT4SS_MCS0: - index = 74; - break; - case MGN_VHT4SS_MCS1: - index = 75; - break; - case MGN_VHT4SS_MCS2: - index = 76; - break; - case MGN_VHT4SS_MCS3: - index = 77; - break; - case MGN_VHT4SS_MCS4: - index = 78; - break; - case MGN_VHT4SS_MCS5: - index = 79; - break; - case MGN_VHT4SS_MCS6: - index = 80; - break; - case MGN_VHT4SS_MCS7: - index = 81; - break; - case MGN_VHT4SS_MCS8: - index = 82; - break; - case MGN_VHT4SS_MCS9: - index = 83; - break; - default: - RTW_INFO("Invalid rate 0x%x in %s\n", Rate, __FUNCTION__); - break; - }; + u8 index = 0; + + if (rate < MGN_UNKNOWN) + index = _phy_get_rate_idx_of_txpwr_by_rate[rate]; + + if (rate != MGN_1M && index == 0) + RTW_WARN("Invalid rate 0x%x in %s\n", rate, __FUNCTION__); return index; } -s8 -_PHY_GetTxPowerByRate( - PADAPTER pAdapter, - u8 Band, - enum rf_path RFPath, - u8 Rate -) +static s8 _phy_get_txpwr_by_rate(_adapter *adapter + , BAND_TYPE band, enum rf_path rfpath, enum MGN_RATE rate) { - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter); s8 value = 0; - u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate); + u8 rate_idx = phy_get_rate_idx_of_txpwr_by_rate(rate); - if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) { - RTW_INFO("Invalid band %d in %s\n", Band, __func__); + if (band != BAND_ON_2_4G && band != BAND_ON_5G) { + RTW_INFO("Invalid band %d in %s\n", band, __func__); goto exit; } - if (RFPath > RF_PATH_D) { - RTW_INFO("Invalid RfPath %d in %s\n", RFPath, __func__); + if (rfpath > RF_PATH_D) { + RTW_INFO("Invalid RfPath %d in %s\n", rfpath, __func__); goto exit; } - if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) { - RTW_INFO("Invalid RateIndex %d in %s\n", rateIndex, __func__); + if (rate_idx >= TX_PWR_BY_RATE_NUM_RATE) { + RTW_INFO("Invalid RateIndex %d in %s\n", rate_idx, __func__); goto exit; } - value = pHalData->TxPwrByRate[Band][RFPath][rateIndex]; + value = pHalData->TxPwrByRate[band][rfpath][rate_idx]; exit: return value; } - -s8 -PHY_GetTxPowerByRate( - PADAPTER pAdapter, - u8 Band, - enum rf_path RFPath, - RATE_SECTION rs, - enum MGN_RATE rate -) +/* +* Return value in unit of TX Gain Index +*/ +s8 phy_get_txpwr_by_rate(_adapter *adapter + , BAND_TYPE band, enum rf_path rfpath, RATE_SECTION rs, enum MGN_RATE rate) { - if (phy_is_tx_power_by_rate_needed(pAdapter)) - return _PHY_GetTxPowerByRate(pAdapter, Band, RFPath, rate); - return phy_get_target_txpwr(pAdapter, Band, RFPath, rs); + if (phy_is_tx_power_by_rate_needed(adapter)) + return _phy_get_txpwr_by_rate(adapter, band, rfpath, rate); + return phy_get_target_txpwr(adapter, band, rfpath, rs); } -void -PHY_SetTxPowerByRate( - PADAPTER pAdapter, - u8 Band, - enum rf_path RFPath, - u8 Rate, - s8 Value -) +/* get txpowr in mBm for single path */ +s16 phy_get_txpwr_by_rate_single_mbm(_adapter *adapter + , BAND_TYPE band, enum rf_path rfpath, RATE_SECTION rs, enum MGN_RATE rate, bool eirp) { - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); - u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + s16 val; - if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) { - RTW_INFO("Invalid band %d in %s\n", Band, __FUNCTION__); - return; - } - if (RFPath > RF_PATH_D) { - RTW_INFO("Invalid RfPath %d in %s\n", RFPath, __FUNCTION__); - return; - } - if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) { - RTW_INFO("Invalid RateIndex %d in %s\n", rateIndex, __FUNCTION__); - return; + val = phy_get_txpwr_by_rate(adapter, band, rfpath, rs, rate); + if (val == hal_spec->txgi_max) + val = UNSPECIFIED_MBM; + else { + val = (val * MBM_PDBM) / hal_spec->txgi_pdbm; + if (eirp) + val += rfctl->antenna_gain; } - pHalData->TxPwrByRate[Band][RFPath][rateIndex] = Value; + return val; +} + +/* get txpowr in mBm with effect of N-TX */ +s16 phy_get_txpwr_by_rate_total_mbm(_adapter *adapter + , BAND_TYPE band, RATE_SECTION rs, enum MGN_RATE rate, bool cap, bool eirp) +{ + s16 val; + u8 tx_num; + + if (cap) + tx_num = phy_get_capable_tx_num(adapter, rate) + 1; + else + tx_num = phy_get_current_tx_num(adapter, rate) + 1; + + /* assume all path have same txpower target */ + val = phy_get_txpwr_by_rate_single_mbm(adapter, band, RF_PATH_A, rs, rate, eirp); + if (val != UNSPECIFIED_MBM) + val += mb_of_ntx(tx_num); + + return val; +} + +static s16 _phy_get_txpwr_by_rate_max_mbm(_adapter *adapter, BAND_TYPE band, s8 rfpath, bool cap, bool eirp) +{ + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + u8 tx_num; + RATE_SECTION rs; + int i; + s16 max = UNSPECIFIED_MBM, mbm; + + for (rs = 0; rs < RATE_SECTION_NUM; rs++) { + tx_num = rate_section_to_tx_num(rs); + if (tx_num + 1 > hal_data->tx_nss) + continue; + + if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs)) + continue; + + if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_ALL(adapter)) + continue; + + for (i = 0; i < rates_by_sections[rs].rate_num; i++) { + if (rfpath < 0) /* total */ + mbm = phy_get_txpwr_by_rate_total_mbm(adapter, band, rs, rates_by_sections[rs].rates[i], cap, eirp); + else + mbm = phy_get_txpwr_by_rate_single_mbm(adapter, band, rfpath, rs, rates_by_sections[rs].rates[i], eirp); + if (mbm == UNSPECIFIED_MBM) + continue; + if (max == UNSPECIFIED_MBM || mbm > max) + max = mbm; + } + } + + return max; +} + +/* get txpowr in mBm for single path */ +s16 phy_get_txpwr_by_rate_single_max_mbm(_adapter *adapter, BAND_TYPE band, enum rf_path rfpath, bool eirp) +{ + return _phy_get_txpwr_by_rate_max_mbm(adapter, band, rfpath, 0 /* single don't care */, eirp); +} + +/* get txpowr in mBm with effect of N-TX */ +s16 phy_get_txpwr_by_rate_total_max_mbm(_adapter *adapter, BAND_TYPE band, bool cap, bool eirp) +{ + return _phy_get_txpwr_by_rate_max_mbm(adapter, band, -1, cap, eirp); } u8 phy_check_under_survey_ch(_adapter *adapter) @@ -2861,7 +2782,7 @@ phy_set_tx_power_level_by_path( if (IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8814A(Adapter)) phy_set_tx_power_index_by_rate_section(Adapter, path, channel, VHT_1SSMCS0_1SSMCS9); - if (pHalData->NumTotalRFPath >= 2) { + if (pHalData->tx_nss >= 2) { phy_set_tx_power_index_by_rate_section(Adapter, path, channel, HT_MCS8_MCS15); if (IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8814A(Adapter)) @@ -3058,7 +2979,7 @@ inline s8 phy_get_txpwr_lmt_diff(_adapter *adapter } /* -* May search for secondary channels for min limit +* May search for secondary channels for max/min limit * @opch: used to specify operating channel position to get * cch of every bandwidths which differ from current hal_data.cch20, 40, 80... * @@ -3068,7 +2989,7 @@ inline s8 phy_get_txpwr_lmt_diff(_adapter *adapter s8 phy_get_txpwr_lmt_sub_chs(_adapter *adapter , const char *regd_name , BAND_TYPE band, enum channel_width bw - , u8 rfpath, u8 rate, u8 ntx_idx, u8 cch, u8 opch) + , u8 rfpath, u8 rate, u8 ntx_idx, u8 cch, u8 opch, bool reg_max) { struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); @@ -3081,10 +3002,17 @@ s8 phy_get_txpwr_lmt_sub_chs(_adapter *adapter u8 tmp_cch = 0; u8 tmp_bw; u8 bw_bmp = 0; - s8 min_lmt = hal_spec->txgi_max; - u8 final_bw = bw, final_cch = cch; + s8 final_lmt = reg_max ? 0 : hal_spec->txgi_max; + u8 final_bw = CHANNEL_WIDTH_MAX, final_cch = cch; _irqL irqL; + if ((adapter->registrypriv.RegEnableTxPowerLimit == 2 && hal_data->EEPROMRegulatory != 1) || + adapter->registrypriv.RegEnableTxPowerLimit == 0 + ) { + final_lmt = hal_spec->txgi_max; + goto exit; + } + #ifdef CONFIG_MP_INCLUDED /* MP mode channel don't use secondary channel */ if (rtw_mp_mode_check(adapter) == _TRUE) @@ -3121,19 +3049,31 @@ s8 phy_get_txpwr_lmt_sub_chs(_adapter *adapter } /* - * find the possible tx bandwidth bmp for this rate, and then will get center channel for each bandwidth - * if no possible tx bandwidth bmp, select valid bandwidth up to current RF bandwidth into bmp + * reg_max: + * get valid full bandwidth bmp up to @bw + * + * !reg_max: + * find the possible tx bandwidth bmp for this rate + * if no possible tx bandwidth bmp, select valid bandwidth bmp up to @bw */ if (tlrs == TXPWR_LMT_RS_CCK || tlrs == TXPWR_LMT_RS_OFDM) bw_bmp = BW_CAP_20M; /* CCK, OFDM only BW 20M */ else if (tlrs == TXPWR_LMT_RS_HT) { - bw_bmp = rtw_get_tx_bw_bmp_of_ht_rate(dvobj, rate, bw); - if (bw_bmp == 0) - bw_bmp = ch_width_to_bw_cap(bw > CHANNEL_WIDTH_40 ? CHANNEL_WIDTH_40 : bw); + if (reg_max) + bw_bmp = ch_width_to_bw_cap(bw > CHANNEL_WIDTH_40 ? CHANNEL_WIDTH_40 + 1 : bw + 1) - 1; + else { + bw_bmp = rtw_get_tx_bw_bmp_of_ht_rate(dvobj, rate, bw); + if (bw_bmp == 0) + bw_bmp = ch_width_to_bw_cap(bw > CHANNEL_WIDTH_40 ? CHANNEL_WIDTH_40 : bw); + } } else if (tlrs == TXPWR_LMT_RS_VHT) { - bw_bmp = rtw_get_tx_bw_bmp_of_vht_rate(dvobj, rate, bw); - if (bw_bmp == 0) - bw_bmp = ch_width_to_bw_cap(bw > CHANNEL_WIDTH_160 ? CHANNEL_WIDTH_160 : bw); + if (reg_max) + bw_bmp = ch_width_to_bw_cap(bw > CHANNEL_WIDTH_160 ? CHANNEL_WIDTH_160 + 1 : bw + 1) - 1; + else { + bw_bmp = rtw_get_tx_bw_bmp_of_vht_rate(dvobj, rate, bw); + if (bw_bmp == 0) + bw_bmp = ch_width_to_bw_cap(bw > CHANNEL_WIDTH_160 ? CHANNEL_WIDTH_160 : bw); + } } else rtw_warn_on(1); } @@ -3143,12 +3083,13 @@ s8 phy_get_txpwr_lmt_sub_chs(_adapter *adapter _enter_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL); - /* loop for each possible tx bandwidth to find minimum limit */ + /* loop for each possible tx bandwidth to find final limit */ for (tmp_bw = CHANNEL_WIDTH_20; tmp_bw <= bw; tmp_bw++) { if (!(ch_width_to_bw_cap(tmp_bw) & bw_bmp)) continue; if (no_sc == _FALSE) { + /* get center channel for each bandwidth */ if (tmp_bw == CHANNEL_WIDTH_20) tmp_cch = cch_20; else if (tmp_bw == CHANNEL_WIDTH_40) @@ -3163,27 +3104,34 @@ s8 phy_get_txpwr_lmt_sub_chs(_adapter *adapter lmt = phy_get_txpwr_lmt(adapter, regd_name, band, tmp_bw, tlrs, ntx_idx, tmp_cch, 0); - if (min_lmt >= lmt) { - min_lmt = lmt; - final_cch = tmp_cch; - final_bw = tmp_bw; + if (final_lmt > lmt) { + if (reg_max) + continue; + } else if (final_lmt < lmt) { + if (!reg_max) + continue; + } else { /* equal */ + if (final_bw == bw) + continue; } + final_lmt = lmt; + final_cch = tmp_cch; + final_bw = tmp_bw; } _exit_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL); -exit: - if (0) { if (final_bw != bw && (IS_HT_RATE(rate) || IS_VHT_RATE(rate))) - RTW_INFO("%s min_lmt: %s ch%u -> %s ch%u\n" + RTW_INFO("%s final_lmt: %s ch%u -> %s ch%u\n" , MGN_RATE_STR(rate) , ch_width_str(bw), cch , ch_width_str(final_bw), final_cch); } - return min_lmt; +exit: + return final_lmt; } static void phy_txpwr_lmt_cck_ofdm_mt_chk(_adapter *adapter) @@ -3627,46 +3575,46 @@ phy_set_tx_power_limit( powerLimit = ww_lmt_val + 1; } - if (eqNByte(RateSection, (u8 *)("CCK"), 3)) + if (strncmp(RateSection, "CCK", 3) == 0) tlrs = TXPWR_LMT_RS_CCK; - else if (eqNByte(RateSection, (u8 *)("OFDM"), 4)) + else if (strncmp(RateSection, "OFDM", 4) == 0) tlrs = TXPWR_LMT_RS_OFDM; - else if (eqNByte(RateSection, (u8 *)("HT"), 2)) + else if (strncmp(RateSection, "HT", 2) == 0) tlrs = TXPWR_LMT_RS_HT; - else if (eqNByte(RateSection, (u8 *)("VHT"), 3)) + else if (strncmp(RateSection, "VHT", 3) == 0) tlrs = TXPWR_LMT_RS_VHT; else { RTW_PRINT("Wrong rate section:%s\n", RateSection); return; } - if (eqNByte(ntx, (u8 *)("1T"), 2)) + if (strncmp(ntx, "1T", 2) == 0) ntx_idx = RF_1TX; - else if (eqNByte(ntx, (u8 *)("2T"), 2)) + else if (strncmp(ntx, "2T", 2) == 0) ntx_idx = RF_2TX; - else if (eqNByte(ntx, (u8 *)("3T"), 2)) + else if (strncmp(ntx, "3T", 2) == 0) ntx_idx = RF_3TX; - else if (eqNByte(ntx, (u8 *)("4T"), 2)) + else if (strncmp(ntx, "4T", 2) == 0) ntx_idx = RF_4TX; else { RTW_PRINT("Wrong tx num:%s\n", ntx); return; } - if (eqNByte(Bandwidth, (u8 *)("20M"), 3)) + if (strncmp(Bandwidth, "20M", 3) == 0) bandwidth = CHANNEL_WIDTH_20; - else if (eqNByte(Bandwidth, (u8 *)("40M"), 3)) + else if (strncmp(Bandwidth, "40M", 3) == 0) bandwidth = CHANNEL_WIDTH_40; - else if (eqNByte(Bandwidth, (u8 *)("80M"), 3)) + else if (strncmp(Bandwidth, "80M", 3) == 0) bandwidth = CHANNEL_WIDTH_80; - else if (eqNByte(Bandwidth, (u8 *)("160M"), 4)) + else if (strncmp(Bandwidth, "160M", 4) == 0) bandwidth = CHANNEL_WIDTH_160; else { RTW_PRINT("unknown bandwidth: %s\n", Bandwidth); return; } - if (eqNByte(Band, (u8 *)("2.4G"), 4)) { + if (strncmp(Band, "2.4G", 4) == 0) { band = BAND_ON_2_4G; channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_2_4G, channel); @@ -3683,7 +3631,7 @@ phy_set_tx_power_limit( rtw_txpwr_lmt_add(adapter_to_rfctl(Adapter), Regulation, band, bandwidth, tlrs, ntx_idx, channelIndex, powerLimit); } #if CONFIG_IEEE80211_BAND_5GHZ - else if (eqNByte(Band, (u8 *)("5G"), 2)) { + else if (strncmp(Band, "5G", 2) == 0) { band = BAND_ON_5G; channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_5G, channel); @@ -3702,6 +3650,169 @@ phy_set_tx_power_limit( #endif } +void +phy_set_tx_power_limit_ex( + struct dm_struct *pDM_Odm, + u8 Regulation, + u8 Band, + u8 Bandwidth, + u8 RateSection, + u8 ntx, + u8 channel, + s8 powerLimit +) +{ +#if CONFIG_TXPWR_LIMIT + PADAPTER Adapter = pDM_Odm->adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(Adapter); + u8 regd; + u8 band = 0, bandwidth = 0, tlrs = 0; + u8 ntx_idx; + s8 prevPowerLimit, channelIndex; + s8 ww_lmt_val = phy_txpwr_ww_lmt_value(Adapter); + + if (0) + RTW_INFO("Index of power limit table [regulation %d][band %d][bw %d][rate section %d][ntx %d][chnl %d][val %d]\n" + , Regulation, Band, Bandwidth, RateSection, ntx, channel, powerLimit); + + if (powerLimit != ww_lmt_val) { + if (powerLimit < -hal_spec->txgi_max || powerLimit > hal_spec->txgi_max) + RTW_PRINT("Illegal power limit value [ch %d][val %d]\n", channel, powerLimit); + + if (powerLimit > hal_spec->txgi_max) + powerLimit = hal_spec->txgi_max; + else if (powerLimit < -hal_spec->txgi_max) + powerLimit = ww_lmt_val + 1; + } + + switch (Regulation) { + case PW_LMT_REGU_FCC: + regd = TXPWR_LMT_FCC; + break; + case PW_LMT_REGU_ETSI: + regd = TXPWR_LMT_ETSI; + break; + case PW_LMT_REGU_MKK: + regd = TXPWR_LMT_MKK; + break; + case PW_LMT_REGU_IC: + regd = TXPWR_LMT_IC; + break; + case PW_LMT_REGU_KCC: + regd = TXPWR_LMT_KCC; + break; + case PW_LMT_REGU_ACMA: + regd = TXPWR_LMT_ACMA; + break; + case PW_LMT_REGU_CHILE: + regd = TXPWR_LMT_CHILE; + break; + case PW_LMT_REGU_UKRAINE: + regd = TXPWR_LMT_UKRAINE; + break; + case PW_LMT_REGU_MEXICO: + regd = TXPWR_LMT_MEXICO; + break; + case PW_LMT_REGU_CN: + regd = TXPWR_LMT_CN; + break; + case PW_LMT_REGU_WW13: + default: + RTW_PRINT("Wrong regulation:%d\n", Regulation); + return; + } + + switch (RateSection) { + case PW_LMT_RS_CCK: + tlrs = TXPWR_LMT_RS_CCK; + break; + case PW_LMT_RS_OFDM: + tlrs = TXPWR_LMT_RS_OFDM; + break; + case PW_LMT_RS_HT: + tlrs = TXPWR_LMT_RS_HT; + break; + case PW_LMT_RS_VHT: + tlrs = TXPWR_LMT_RS_VHT; + break; + default: + RTW_PRINT("Wrong rate section:%d\n", RateSection); + return; + } + + switch (ntx) { + case PW_LMT_PH_1T: + ntx_idx = RF_1TX; + break; + case PW_LMT_PH_2T: + ntx_idx = RF_2TX; + break; + case PW_LMT_PH_3T: + ntx_idx = RF_3TX; + break; + case PW_LMT_PH_4T: + ntx_idx = RF_4TX; + break; + default: + RTW_PRINT("Wrong tx num:%d\n", ntx); + return; + } + + switch (Bandwidth) { + case PW_LMT_BW_20M: + bandwidth = CHANNEL_WIDTH_20; + break; + case PW_LMT_BW_40M: + bandwidth = CHANNEL_WIDTH_40; + break; + case PW_LMT_BW_80M: + bandwidth = CHANNEL_WIDTH_80; + break; + case PW_LMT_BW_160M: + bandwidth = CHANNEL_WIDTH_160; + break; + default: + RTW_PRINT("unknown bandwidth: %d\n", Bandwidth); + return; + } + + if (Band == PW_LMT_BAND_2_4G) { + band = BAND_ON_2_4G; + channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_2_4G, channel); + + if (channelIndex == -1) { + RTW_PRINT("unsupported channel: %d at 2.4G\n", channel); + return; + } + + if (bandwidth >= MAX_2_4G_BANDWIDTH_NUM) { + RTW_PRINT("unsupported bandwidth: %s at 2.4G\n", ch_width_str(bandwidth)); + return; + } + + rtw_txpwr_lmt_add(adapter_to_rfctl(Adapter), regd_str(regd), band, bandwidth, tlrs, ntx_idx, channelIndex, powerLimit); + } +#if CONFIG_IEEE80211_BAND_5GHZ + else if (Band == PW_LMT_BAND_5G) { + band = BAND_ON_5G; + channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_5G, channel); + + if (channelIndex == -1) { + RTW_PRINT("unsupported channel: %d at 5G\n", channel); + return; + } + + rtw_txpwr_lmt_add(adapter_to_rfctl(Adapter), regd_str(regd), band, bandwidth, tlrs, ntx_idx, channelIndex, powerLimit); + } +#endif + else { + RTW_PRINT("unknown/unsupported band:%d\n", Band); + return; + } +#endif +} + u8 phy_get_tx_power_index_ex(_adapter *adapter , enum rf_path rfpath, RATE_SECTION rs, enum MGN_RATE rate , enum channel_width bw, BAND_TYPE band, u8 cch, u8 opch) @@ -3739,22 +3850,25 @@ void dump_tx_power_index_inline(void *sel, _adapter *adapter, u8 rfpath, enum ch struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); if (tic->utarget == hal_spec->txgi_max) { - RTW_PRINT_SEL(sel, "TXPWR: [%c][%s]cch:%u, %s %uT, idx:%u(0x%02x) = base(%d) + min((byr(%d) + btc(%d) + extra(%d)), lmt(%d), ulmt(%d)) + tpt(%d) + dpd(%d)\n" + RTW_PRINT_SEL(sel, "TXPWR: [%c][%s]cch:%u, %s %uT, idx:%u(0x%02x) = base(%d) + min((byr(%d) + btc(%d) + extra(%d)), rlmt(%d), lmt(%d), ulmt(%d)) + tpc(%d) + tpt(%d) + dpd(%d)\n" , rf_path_char(rfpath), ch_width_str(bw), cch , MGN_RATE_STR(rate), tic->ntx_idx + 1 , pwr_idx, pwr_idx, tic->base - , tic->by_rate, tic->btc, tic->extra, tic->limit, tic->ulimit + , tic->by_rate, tic->btc, tic->extra, tic->rlimit, tic->limit, tic->ulimit + , tic->tpc , tic->tpt, tic->dpd); } else { - RTW_PRINT_SEL(sel, "TXPWR: [%c][%s]cch:%u, %s %uT, idx:%u(0x%02x) = base(%d) + min(utgt(%d), lmt(%d), ulmt(%d)) + tpt(%d) + dpd(%d)\n" + RTW_PRINT_SEL(sel, "TXPWR: [%c][%s]cch:%u, %s %uT, idx:%u(0x%02x) = base(%d) + min(utgt(%d), rlmt(%d), lmt(%d), ulmt(%d)) + tpc(%d) + tpt(%d) + dpd(%d)\n" , rf_path_char(rfpath), ch_width_str(bw), cch , MGN_RATE_STR(rate), tic->ntx_idx + 1 , pwr_idx, pwr_idx, tic->base - , tic->utarget, tic->limit, tic->ulimit + , tic->utarget, tic->rlimit, tic->limit, tic->ulimit + , tic->tpc , tic->tpt, tic->dpd); } } +#ifdef CONFIG_PROC_DEBUG void dump_tx_power_idx_value(void *sel, _adapter *adapter, u8 rfpath, enum MGN_RATE rate, u8 pwr_idx, struct txpwr_idx_comp *tic) { struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); @@ -3764,17 +3878,19 @@ void dump_tx_power_idx_value(void *sel, _adapter *adapter, u8 rfpath, enum MGN_R if (tic->utarget == hal_spec->txgi_max) { RTW_PRINT_SEL(sel, "%4c %9s %uT %s %3u(0x%02x)" - " %4d ((%4d %3d %5d) %4d %4d) %3d %3d\n" + " %4d ((%4d %3d %5d) %4d %4d %4d) %3d %3d %3d\n" , rf_path_char(rfpath), MGN_RATE_STR(rate), tic->ntx_idx + 1 , tmp_str, pwr_idx, pwr_idx - , tic->base, tic->by_rate, tic->btc, tic->extra, tic->limit, tic->ulimit + , tic->base, tic->by_rate, tic->btc, tic->extra, tic->rlimit, tic->limit, tic->ulimit + , tic->tpc , tic->tpt, tic->dpd); } else { RTW_PRINT_SEL(sel, "%4c %9s %uT %s %3u(0x%02x)" - " %4d (%4d %4d %4d) %3d %3d\n" + " %4d (%4d %4d %4d %4d) %3d %3d %3d\n" , rf_path_char(rfpath), MGN_RATE_STR(rate), tic->ntx_idx + 1 , tmp_str, pwr_idx, pwr_idx - , tic->base, tic->utarget, tic->limit, tic->ulimit + , tic->base, tic->utarget, tic->rlimit, tic->limit, tic->ulimit + , tic->tpc , tic->tpt, tic->dpd); } } @@ -3800,15 +3916,17 @@ void dump_tx_power_idx_title(void *sel, _adapter *adapter, enum channel_width bw if (!phy_is_txpwr_user_target_specified(adapter)) { RTW_PRINT_SEL(sel, "%-4s %-9s %2s %-6s %-3s%6s" - " = %-4s + min((%-4s + %-3s + %-5s), %-4s, %-4s) + %-3s + %-3s\n" + " = %-4s + min((%-4s + %-3s + %-5s), %-4s, %-4s, %-4s) + %-3s + %-3s + %-3s\n" , "path", "rate", "", "dBm", "idx", "" - , "base", "byr", "btc", "extra", "lmt", "ulmt" + , "base", "byr", "btc", "extra", "rlmt", "lmt", "ulmt" + , "tpc" , "tpt", "dpd"); } else { RTW_PRINT_SEL(sel, "%-4s %-9s %2s %-6s %-3s%6s" - " = %-4s + min(%-4s, %-4s, %-4s) + %-3s + %-3s\n" + " = %-4s + min(%-4s, %-4s, %-4s, %-4s) + %-3s + %-3s + %-3s\n" , "path", "rate", "", "dBm", "idx", "" - , "base", "utgt", "lmt", "ulmt" + , "base", "utgt", "rlmt", "lmt", "ulmt" + , "tpc" , "tpt", "dpd"); } } @@ -3856,49 +3974,62 @@ void dump_tx_power_idx(void *sel, _adapter *adapter, enum channel_width bw, u8 c } void dump_txpwr_total_dbm_value(void *sel, _adapter *adapter, enum MGN_RATE rate, u8 ntx_idx - , s16 target, s16 byr, s16 btc, s16 extra, s16 lmt, s16 ulmt) + , s16 target, s16 byr, s16 btc, s16 extra, s16 rlmt, s16 lmt, s16 ulmt, s16 tpc) { char target_str[8]; char byr_str[8]; char btc_str[8]; char extra_str[8]; + char rlmt_str[8]; char lmt_str[8]; char ulmt_str[8]; + char tpc_str[8]; txpwr_mbm_get_dbm_str(target, 0, target_str, 8); txpwr_mbm_get_dbm_str(byr, 0, byr_str, 8); txpwr_mbm_get_dbm_str(btc, 0, btc_str, 8); txpwr_mbm_get_dbm_str(extra, 0, extra_str, 8); + txpwr_mbm_get_dbm_str(rlmt, 0, rlmt_str, 8); txpwr_mbm_get_dbm_str(lmt, 0, lmt_str, 8); txpwr_mbm_get_dbm_str(ulmt, 0, ulmt_str, 8); + txpwr_mbm_get_dbm_str(tpc, 0, tpc_str, 8); - RTW_PRINT_SEL(sel, "%9s %uT %s = ((%s %s %s), %s, %s)\n" + RTW_PRINT_SEL(sel, "%9s %uT %s = ((%s %s %s), %s, %s, %s) %s\n" , MGN_RATE_STR(rate), ntx_idx + 1 - , target_str, byr_str, btc_str, extra_str, lmt_str, ulmt_str); + , target_str, byr_str, btc_str, extra_str, rlmt_str, lmt_str, ulmt_str, tpc_str); } void dump_txpwr_total_dbm_value_utgt(void *sel, _adapter *adapter, enum MGN_RATE rate, u8 ntx_idx - , s16 target, s16 utgt, s16 lmt, s16 ulmt) + , s16 target, s16 utgt, s16 rlmt, s16 lmt, s16 ulmt, s16 tpc) { char target_str[8]; char utgt_str[8]; + char rlmt_str[8]; char lmt_str[8]; char ulmt_str[8]; + char tpc_str[8]; txpwr_mbm_get_dbm_str(target, 0, target_str, 8); txpwr_mbm_get_dbm_str(utgt, 0, utgt_str, 8); + txpwr_mbm_get_dbm_str(rlmt, 0, rlmt_str, 8); txpwr_mbm_get_dbm_str(lmt, 0, lmt_str, 8); txpwr_mbm_get_dbm_str(ulmt, 0, ulmt_str, 8); + txpwr_mbm_get_dbm_str(tpc, 0, tpc_str, 8); - RTW_PRINT_SEL(sel, "%9s %uT %s = (%s, %s, %s)\n" + RTW_PRINT_SEL(sel, "%9s %uT %s = (%s, %s, %s, %s) %s\n" , MGN_RATE_STR(rate), ntx_idx + 1 - , target_str, utgt_str, lmt_str, ulmt_str); + , target_str, utgt_str, rlmt_str, lmt_str, ulmt_str, tpc_str); } void dump_txpwr_total_dbm_title(void *sel, _adapter *adapter, enum channel_width bw, u8 cch, u8 opch) { + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + char antenna_gain_str[8]; u8 cch_20, cch_40, cch_80; + txpwr_mbm_get_dbm_str(rfctl->antenna_gain, 0, antenna_gain_str, 8); + RTW_PRINT_SEL(sel, "antenna_gain:%s\n", antenna_gain_str); + cch_80 = bw == CHANNEL_WIDTH_80 ? cch : 0; cch_40 = bw == CHANNEL_WIDTH_40 ? cch : 0; cch_20 = bw == CHANNEL_WIDTH_20 ? cch : 0; @@ -3915,11 +4046,11 @@ void dump_txpwr_total_dbm_title(void *sel, _adapter *adapter, enum channel_width _RTW_PRINT_SEL(sel, ", cch20:%u\n", cch_20); if (!phy_is_txpwr_user_target_specified(adapter)) { - RTW_PRINT_SEL(sel, "%-9s %2s %-6s = min((%-6s + %-6s + %-6s), %-6s, %-6s)\n" - , "rate", "", "target", "byr", "btc", "extra", "lmt", "ulmt"); + RTW_PRINT_SEL(sel, "%-9s %2s %-6s = min((%-6s + %-6s + %-6s), %-6s, %-6s, %-6s) + %-6s\n" + , "rate", "", "target", "byr", "btc", "extra", "rlmt", "lmt", "ulmt", "tpc"); } else { - RTW_PRINT_SEL(sel, "%-9s %2s %-6s = min(%-6s, %-6s, %-6s)\n" - , "rate", "", "target", "utgt", "lmt", "ulmt"); + RTW_PRINT_SEL(sel, "%-9s %2s %-6s = min(%-6s, %-6s, %-6s, %-6s) + %-6s\n" + , "rate", "", "target", "utgt", "rlmt", "lmt", "ulmt", "tpc"); } } @@ -3944,11 +4075,15 @@ void dump_txpwr_total_dbm_by_rs(void *sel, _adapter *adapter, u8 rs, enum channe for (i = 0; i < rates_by_sections[rs].rate_num; i++) { struct txpwr_idx_comp tic; - s16 target, byr, btc, extra, utgt, lmt, ulmt; + s16 target, byr, tpc, btc, extra, utgt, rlmt, lmt, ulmt; u8 tx_num; - target = phy_get_txpwr_total_mbm(adapter, rs, rates_by_sections[rs].rates[i], bw, cch, opch, &tic); + target = phy_get_txpwr_total_mbm(adapter, rs, rates_by_sections[rs].rates[i], bw, cch, opch, 0, 0, &tic); tx_num = tic.ntx_idx + 1; + if (tic.rlimit == hal_spec->txgi_max) + rlmt = UNSPECIFIED_MBM; + else + rlmt = ((tic.rlimit * MBM_PDBM) / hal_spec->txgi_pdbm) + mb_of_ntx(tx_num); if (tic.limit == hal_spec->txgi_max) lmt = UNSPECIFIED_MBM; else @@ -3957,17 +4092,18 @@ void dump_txpwr_total_dbm_by_rs(void *sel, _adapter *adapter, u8 rs, enum channe ulmt = UNSPECIFIED_MBM; else ulmt = ((tic.ulimit * MBM_PDBM) / hal_spec->txgi_pdbm) + mb_of_ntx(tx_num); + tpc = (tic.tpc * MBM_PDBM) / hal_spec->txgi_pdbm; if (tic.utarget == hal_spec->txgi_max) { byr = ((tic.by_rate * MBM_PDBM) / hal_spec->txgi_pdbm) + mb_of_ntx(tx_num); btc = (tic.btc * MBM_PDBM) / hal_spec->txgi_pdbm; extra = (tic.extra * MBM_PDBM) / hal_spec->txgi_pdbm; dump_txpwr_total_dbm_value(sel, adapter, rates_by_sections[rs].rates[i], tic.ntx_idx - , target, byr, btc, extra, lmt, ulmt); + , target, byr, btc, extra, rlmt, lmt, ulmt, tpc); } else { utgt = ((tic.utarget * MBM_PDBM) / hal_spec->txgi_pdbm) + mb_of_ntx(tx_num); dump_txpwr_total_dbm_value_utgt(sel, adapter, rates_by_sections[rs].rates[i], tic.ntx_idx - , target, utgt, lmt, ulmt); + , target, utgt, rlmt, lmt, ulmt, tpc); } } } @@ -3981,6 +4117,7 @@ void dump_txpwr_total_dbm(void *sel, _adapter *adapter, enum channel_width bw, u for (rs = CCK; rs < RATE_SECTION_NUM; rs++) dump_txpwr_total_dbm_by_rs(sel, adapter, rs, bw, cch, opch); } +#endif bool phy_is_tx_power_limit_needed(_adapter *adapter) { @@ -4125,13 +4262,16 @@ void phy_load_tx_power_ext_info(_adapter *adapter, u8 chk_file) inline void phy_reload_tx_power_ext_info(_adapter *adapter) { phy_load_tx_power_ext_info(adapter, 1); + op_class_pref_apply_regulatory(adapter, REG_TXPWR_CHANGE); } inline void phy_reload_default_tx_power_ext_info(_adapter *adapter) { phy_load_tx_power_ext_info(adapter, 0); + op_class_pref_apply_regulatory(adapter, REG_TXPWR_CHANGE); } +#ifdef CONFIG_PROC_DEBUG void dump_tx_power_ext_info(void *sel, _adapter *adapter) { struct registry_priv *regsty = adapter_to_regsty(adapter); @@ -4245,7 +4385,7 @@ void dump_tx_power_by_rate(void *sel, _adapter *adapter) /* dump power by rate in db */ for (n = rate_num - 1; n >= 0; n--) { - by_rate = PHY_GetTxPowerByRate(adapter, band, path, rs, rates_by_sections[rs].rates[n]); + by_rate = phy_get_txpwr_by_rate(adapter, band, path, rs, rates_by_sections[rs].rates[n]); if (by_rate % hal_spec->txgi_pdbm) { _RTW_PRINT_SEL(sel, "%2d.%d ", by_rate / hal_spec->txgi_pdbm , (by_rate % hal_spec->txgi_pdbm) * 100 / hal_spec->txgi_pdbm); @@ -4259,7 +4399,7 @@ void dump_tx_power_by_rate(void *sel, _adapter *adapter) /* dump power by rate in offset */ for (n = rate_num - 1; n >= 0; n--) { - by_rate = PHY_GetTxPowerByRate(adapter, band, path, rs, rates_by_sections[rs].rates[n]); + by_rate = phy_get_txpwr_by_rate(adapter, band, path, rs, rates_by_sections[rs].rates[n]); base = phy_get_target_txpwr(adapter, band, path, rs); _RTW_PRINT_SEL(sel, "%3d ", by_rate - base); } @@ -4269,7 +4409,7 @@ void dump_tx_power_by_rate(void *sel, _adapter *adapter) } } } - +#endif /* * phy file path is stored in global char array rtw_phy_para_file_path * need to care about racing @@ -4538,15 +4678,15 @@ phy_ParseBBPgParaFile( if (!IsCommentString(szLine)) { /* Get header info (relative value or exact value) */ if (firstLine) { - if (eqNByte(szLine, (u8 *)("#[v1]"), 5) - || eqNByte(szLine, (u8 *)("#[v2]"), 5)) + if (strncmp(szLine, "#[v1]", 5) == 0 + || strncmp(szLine, "#[v2]", 5) == 0) pHalData->odmpriv.phy_reg_pg_version = szLine[3] - '0'; else { RTW_ERR("The format in PHY_REG_PG are invalid %s\n", szLine); goto exit; } - if (eqNByte(szLine + 5, (u8 *)("[Exact]#"), 8)) { + if (strncmp(szLine + 5, "[Exact]#", 8) == 0) { pHalData->odmpriv.phy_reg_pg_value_type = PHY_REG_PG_EXACT_VALUE; firstLine = _FALSE; continue; @@ -4559,17 +4699,17 @@ phy_ParseBBPgParaFile( if (pHalData->odmpriv.phy_reg_pg_version > 0) { u32 index = 0; - if (eqNByte(szLine, "0xffff", 6)) + if (strncmp(szLine, "0xffff", 6) == 0) break; - if (!eqNByte("#[END]#", szLine, 7)) { + if (strncmp(szLine, "#[END]#", 7)) { /* load the table label info */ if (szLine[0] == '#') { index = 0; - if (eqNByte(szLine, "#[2.4G]" , 7)) { + if (strncmp(szLine, "#[2.4G]", 7) == 0) { band = BAND_ON_2_4G; index += 8; - } else if (eqNByte(szLine, "#[5G]", 5)) { + } else if (strncmp(szLine, "#[5G]", 5) == 0) { band = BAND_ON_5G; index += 6; } else { @@ -5336,7 +5476,7 @@ phy_ParsePowerLimitTableFile( while (szLine[i] == ' ' || szLine[i] == '\t') ++i; - if (!eqNByte((u8 *)(szLine + i), (u8 *)("START"), 5)) { + if (strncmp((u8 *)(szLine + i), "START", 5)) { RTW_ERR("Missing \"## START\" label\n"); goto exit; } @@ -5414,7 +5554,7 @@ phy_ParsePowerLimitTableFile( while (szLine[i] == ' ' || szLine[i] == '\t') ++i; - if (eqNByte((u8 *)(szLine + i), (u8 *)("END"), 3)) { + if (strncmp((u8 *)(szLine + i), "END", 3) == 0) { loadingStage = LD_STAGE_TAB_DEFINE; if (regulation) { for (forCnt = 0; forCnt < colNum; ++forCnt) { @@ -5636,6 +5776,36 @@ inline void phy_free_filebuf(_adapter *padapter) #endif +/* +* TX power limit of regulatory without HAL consideration +* Return value in unit of TX Gain Index +* hal_spec.txgi_max means unspecified +*/ +s8 phy_get_txpwr_regd_lmt(_adapter *adapter, struct hal_spec_t *hal_spec, u8 cch, enum channel_width bw, u8 ntx_idx) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + s16 total_mbm = UNSPECIFIED_MBM; + s8 lmt; + + if ((adapter->registrypriv.RegEnableTxPowerLimit == 2 && hal_data->EEPROMRegulatory != 1) || + adapter->registrypriv.RegEnableTxPowerLimit == 0) + goto exit; + +#ifdef CONFIG_REGD_SRC_FROM_OS + if (rfctl->regd_src == REGD_SRC_OS) + total_mbm = rtw_os_get_total_txpwr_regd_lmt_mbm(adapter, cch, bw); +#endif + +exit: + if (total_mbm != UNSPECIFIED_MBM) + lmt = (total_mbm - mb_of_ntx(ntx_idx + 1) - rfctl->antenna_gain) * hal_spec->txgi_pdbm / MBM_PDBM; + else + lmt = hal_spec->txgi_max; + + return lmt; +} + /* * check if user specified mbm is valid */ @@ -5667,6 +5837,7 @@ bool phy_is_txpwr_user_target_specified(_adapter *adapter) */ s8 phy_get_txpwr_user_target(_adapter *adapter, struct hal_spec_t *hal_spec, u8 ntx_idx) { + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); s16 total_mbm = UNSPECIFIED_MBM; s8 target; @@ -5674,7 +5845,7 @@ s8 phy_get_txpwr_user_target(_adapter *adapter, struct hal_spec_t *hal_spec, u8 total_mbm = rtw_cfg80211_dev_get_total_txpwr_target_mbm(adapter_to_dvobj(adapter)); #endif if (total_mbm != UNSPECIFIED_MBM) - target = (total_mbm - mb_of_ntx(ntx_idx + 1)) * hal_spec->txgi_pdbm / MBM_PDBM; + target = (total_mbm - mb_of_ntx(ntx_idx + 1) - rfctl->antenna_gain) * hal_spec->txgi_pdbm / MBM_PDBM; else target = hal_spec->txgi_max; @@ -5687,6 +5858,7 @@ s8 phy_get_txpwr_user_target(_adapter *adapter, struct hal_spec_t *hal_spec, u8 */ s8 phy_get_txpwr_user_lmt(_adapter *adapter, struct hal_spec_t *hal_spec, u8 ntx_idx) { + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); s16 total_mbm = UNSPECIFIED_MBM; s8 lmt; @@ -5694,32 +5866,69 @@ s8 phy_get_txpwr_user_lmt(_adapter *adapter, struct hal_spec_t *hal_spec, u8 ntx total_mbm = rtw_cfg80211_dev_get_total_txpwr_lmt_mbm(adapter_to_dvobj(adapter)); #endif if (total_mbm != UNSPECIFIED_MBM) - lmt = (total_mbm - mb_of_ntx(ntx_idx + 1)) * hal_spec->txgi_pdbm / MBM_PDBM; + lmt = (total_mbm - mb_of_ntx(ntx_idx + 1) - rfctl->antenna_gain) * hal_spec->txgi_pdbm / MBM_PDBM; else lmt = hal_spec->txgi_max; return lmt; } +/* +* Return value in unit of TX Gain Index +* 0 means unspecified +*/ +s8 phy_get_txpwr_tpc(_adapter *adapter, struct hal_spec_t *hal_spec) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + u16 cnst = 0; + + if (rfctl->tpc_mode == TPC_MODE_MANUAL) + cnst = rfctl->tpc_manual_constraint * hal_spec->txgi_pdbm / MBM_PDBM; + + return -cnst; +} + +void dump_txpwr_tpc_settings(void *sel, _adapter *adapter) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + if (rfctl->tpc_mode == TPC_MODE_DISABLE) + RTW_PRINT_SEL(sel, "mode:DISABLE(%d)\n", rfctl->tpc_mode); + else if (rfctl->tpc_mode == TPC_MODE_MANUAL) { + RTW_PRINT_SEL(sel, "mode:MANUAL(%d)\n", rfctl->tpc_mode); + RTW_PRINT_SEL(sel, "constraint:%d (mB)\n", rfctl->tpc_manual_constraint); + } +} + +void dump_txpwr_antenna_gain(void *sel, _adapter *adapter) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + RTW_PRINT_SEL(sel, "%d (mBi)\n", rfctl->antenna_gain); +} + /* * Return value in unit of TX Gain Index */ s8 phy_get_txpwr_target(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate, u8 ntx_idx - , enum channel_width bw, BAND_TYPE band, u8 cch, u8 opch, struct txpwr_idx_comp *tic) + , enum channel_width bw, BAND_TYPE band, u8 cch, u8 opch, bool reg_max, struct txpwr_idx_comp *tic) { HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); s8 target, by_rate = 0, btc_diff = 0, extra = 0; - s8 lmt, utgt, ulmt; + s8 lmt, rlmt, utgt, ulmt; + s8 tpc = 0; - lmt = utgt = ulmt = hal_spec->txgi_max; + rlmt = lmt = utgt = ulmt = hal_spec->txgi_max; if (band != BAND_ON_2_4G && IS_CCK_RATE(rate)) goto exit; - utgt = phy_get_txpwr_user_target(adapter, hal_spec, ntx_idx); - if (utgt != hal_spec->txgi_max) - goto get_lmt; + if (!reg_max) { + utgt = phy_get_txpwr_user_target(adapter, hal_spec, ntx_idx); + if (utgt != hal_spec->txgi_max) + goto get_lmt; + } #ifdef CONFIG_RTL8812A if (IS_HARDWARE_TYPE_8812(adapter) @@ -5727,33 +5936,44 @@ s8 phy_get_txpwr_target(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate, by_rate = phy_get_target_txpwr(adapter, band, rfpath, rs); else #endif - by_rate = PHY_GetTxPowerByRate(adapter, band, rfpath, rs, rate); + by_rate = phy_get_txpwr_by_rate(adapter, band, rfpath, rs, rate); if (by_rate == hal_spec->txgi_max) by_rate = 0; #ifdef CONFIG_BT_COEXIST - if (hal_data->EEPROMBluetoothCoexist == _TRUE) - btc_diff = -(rtw_btcoex_query_reduced_wl_pwr_lvl(adapter) * hal_spec->txgi_pdbm); + if (!reg_max) { + if (hal_data->EEPROMBluetoothCoexist == _TRUE) + btc_diff = -(rtw_btcoex_query_reduced_wl_pwr_lvl(adapter) * hal_spec->txgi_pdbm); + } #endif extra = rtw_hal_get_txpwr_target_extra_bias(adapter, rfpath, rs, rate, bw, band, cch); get_lmt: - lmt = phy_get_txpwr_lmt_sub_chs(adapter, NULL, band, bw, rfpath, rate, ntx_idx, cch, opch); - ulmt = phy_get_txpwr_user_lmt(adapter, hal_spec, ntx_idx); + rlmt = phy_get_txpwr_regd_lmt(adapter, hal_spec, cch, bw, ntx_idx); + lmt = phy_get_txpwr_lmt_sub_chs(adapter, NULL, band, bw, rfpath, rate, ntx_idx, cch, opch, reg_max); + if (!reg_max) + ulmt = phy_get_txpwr_user_lmt(adapter, hal_spec, ntx_idx); /* TODO: limit from outer source, ex: 11d */ + if (!reg_max) + tpc = phy_get_txpwr_tpc(adapter, hal_spec); + exit: if (utgt != hal_spec->txgi_max) target = utgt; else target = by_rate + btc_diff + extra; + if (target > rlmt) + target = rlmt; if (target > lmt) target = lmt; if (target > ulmt) target = ulmt; + target += tpc; + if (tic) { tic->target = target; if (utgt == hal_spec->txgi_max) { @@ -5762,8 +5982,10 @@ exit: tic->extra = extra; } tic->utarget = utgt; + tic->rlimit = rlmt; tic->limit = lmt; tic->ulimit = ulmt; + tic->tpc = tpc; } return target; @@ -5818,7 +6040,7 @@ s8 phy_get_tssi_txpwr_by_rate_ref(_adapter *adapter, enum rf_path path s8 pwr_idx; pwr_idx = phy_get_txpwr_target(adapter, path, HT_1SS, MGN_MCS7 - , ntx_idx, bw, band, cch, opch, NULL); + , ntx_idx, bw, band, cch, opch, 0, NULL); pwr_idx += phy_get_txpwr_amends(adapter, path, HT_1SS, MGN_MCS7 , ntx_idx, bw, band, cch, NULL); @@ -5841,7 +6063,7 @@ u8 hal_com_get_txpwr_idx(_adapter *adapter, enum rf_path rfpath u8 ntx_idx = phy_get_current_tx_num(adapter, rate); /* target */ - rate_target = phy_get_txpwr_target(adapter, rfpath, rs, rate, ntx_idx, bw, band, cch, opch, tic); + rate_target = phy_get_txpwr_target(adapter, rfpath, rs, rate, ntx_idx, bw, band, cch, opch, 0, tic); /* amends */ rate_amends = phy_get_txpwr_amends(adapter, rfpath, rs, rate, ntx_idx, bw, band, cch, tic); @@ -5866,6 +6088,8 @@ u8 hal_com_get_txpwr_idx(_adapter *adapter, enum rf_path rfpath tic->by_rate -= rs_target; else tic->utarget -= rs_target; + if (tic->rlimit != hal_spec->txgi_max) + tic->rlimit -= rs_target; if (tic->limit != hal_spec->txgi_max) tic->limit -= rs_target; if (tic->ulimit != hal_spec->txgi_max) @@ -5883,11 +6107,16 @@ u8 hal_com_get_txpwr_idx(_adapter *adapter, enum rf_path rfpath * 3. amends diff (per rate) * base is selected that power index of MCS7 == halrf_get_tssi_codeword_for_txindex() */ +#if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) s8 mcs7_idx; mcs7_idx = phy_get_tssi_txpwr_by_rate_ref(adapter, rfpath, bw, cch, opch); base = halrf_get_tssi_codeword_for_txindex(adapter_to_phydm(adapter)) - mcs7_idx; power_idx = base + rate_target + rate_amends; +#else + base = 0; + power_idx = rate_target + rate_amends; +#endif } break; #endif @@ -5912,39 +6141,64 @@ u8 hal_com_get_txpwr_idx(_adapter *adapter, enum rf_path rfpath return power_idx; } -/* get txpowr in mBm for single path */ -s16 phy_get_txpwr_single_mbm(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate - , enum channel_width bw, u8 cch, u8 opch, struct txpwr_idx_comp *tic) +static s16 phy_get_txpwr_mbm(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate + , enum channel_width bw, u8 cch, u8 opch, bool total, bool reg_max, bool eirp, struct txpwr_idx_comp *tic) { struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); BAND_TYPE band = cch <= 14 ? BAND_ON_2_4G : BAND_ON_5G; - u8 ntx_idx = phy_get_current_tx_num(adapter, rate); - s16 val; + u8 ntx_idx_max, ntx_idx, i; + s16 val, max = UNSPECIFIED_MBM; + + if (reg_max) { + ntx_idx_max = phy_get_capable_tx_num(adapter, rate); + ntx_idx = rate_section_to_tx_num(rs); + if (ntx_idx > ntx_idx_max) { + rtw_warn_on(1); + return 0; + } + } else + ntx_idx_max = ntx_idx = phy_get_current_tx_num(adapter, rate); + + for (i = 0; ntx_idx + i <= ntx_idx_max; i++) { + val = phy_get_txpwr_target(adapter, rfpath, rs, rate, ntx_idx, bw, band, cch, opch, reg_max, tic); + val = (val * MBM_PDBM) / hal_spec->txgi_pdbm; + if (total) + val += mb_of_ntx(ntx_idx + 1); + if (eirp) + val += rfctl->antenna_gain; + + if (max == UNSPECIFIED_MBM || max < val) + max = val; + } - val = phy_get_txpwr_target(adapter, rfpath, rs, rate, ntx_idx, bw, band, cch, opch, tic); - val = (val * MBM_PDBM) / hal_spec->txgi_pdbm; if (tic) tic->ntx_idx = ntx_idx; - return val; + if (max == UNSPECIFIED_MBM) { + rtw_warn_on(1); + max = 0; + } + return max; +} + +/* get txpowr in mBm for single path */ +s16 phy_get_txpwr_single_mbm(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate + , enum channel_width bw, u8 cch, u8 opch, bool reg_max, bool eirp, struct txpwr_idx_comp *tic) +{ + return phy_get_txpwr_mbm(adapter, rfpath, rs, rate, bw, cch, opch, 0, reg_max, eirp, tic); } /* get txpowr in mBm with effect of N-TX */ s16 phy_get_txpwr_total_mbm(_adapter *adapter, RATE_SECTION rs, u8 rate - , enum channel_width bw, u8 cch, u8 opch, struct txpwr_idx_comp *tic) + , enum channel_width bw, u8 cch, u8 opch, bool reg_max, bool eirp, struct txpwr_idx_comp *tic) { - s16 val; - u8 tx_num = phy_get_current_tx_num(adapter, rate) + 1; - /* assume all path have same txpower target */ - val = phy_get_txpwr_single_mbm(adapter, RF_PATH_A, rs, rate, bw, cch, opch, tic); - val += mb_of_ntx(tx_num); - - return val; + return phy_get_txpwr_mbm(adapter, RF_PATH_A, rs, rate, bw, cch, opch, 1, reg_max, eirp, tic); } static s16 _phy_get_txpwr_max_mbm(_adapter *adapter, s8 rfpath - , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht) + , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht, bool reg_max, bool eirp) { struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); @@ -5983,9 +6237,9 @@ static s16 _phy_get_txpwr_max_mbm(_adapter *adapter, s8 rfpath } if (rfpath < 0) /* total */ - mbm = phy_get_txpwr_total_mbm(adapter, rs, rates_by_sections[rs].rates[i], bw, cch, opch, NULL); + mbm = phy_get_txpwr_total_mbm(adapter, rs, rates_by_sections[rs].rates[i], bw, cch, opch, reg_max, eirp, NULL); else - mbm = phy_get_txpwr_single_mbm(adapter, rfpath, rs, rates_by_sections[rs].rates[i], bw, cch, opch, NULL); + mbm = phy_get_txpwr_single_mbm(adapter, rfpath, rs, rates_by_sections[rs].rates[i], bw, cch, opch, reg_max, eirp, NULL); if (max == UNSPECIFIED_MBM || mbm > max) max = mbm; @@ -5996,15 +6250,15 @@ static s16 _phy_get_txpwr_max_mbm(_adapter *adapter, s8 rfpath } s16 phy_get_txpwr_single_max_mbm(_adapter *adapter, u8 rfpath - , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht) + , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht, bool reg_max, bool eirp) { - return _phy_get_txpwr_max_mbm(adapter, rfpath, bw, cch, opch, bmp_cck_ofdm, bmp_ht, bmp_vht); + return _phy_get_txpwr_max_mbm(adapter, rfpath, bw, cch, opch, bmp_cck_ofdm, bmp_ht, bmp_vht, reg_max, eirp); } s16 phy_get_txpwr_total_max_mbm(_adapter *adapter - , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht) + , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht, bool reg_max, bool eirp) { - return _phy_get_txpwr_max_mbm(adapter, -1, bw, cch, opch, bmp_cck_ofdm, bmp_ht, bmp_vht); + return _phy_get_txpwr_max_mbm(adapter, -1, bw, cch, opch, bmp_cck_ofdm, bmp_ht, bmp_vht, reg_max, eirp); } s8 @@ -6017,7 +6271,7 @@ phy_get_tx_power_final_absolute_value(_adapter *adapter, u8 rfpath, u8 rate, s8 val; val = phy_get_txpwr_target(adapter, rfpath - , rs, rate, phy_get_current_tx_num(adapter, rate), bw, band, cch, 0, NULL); + , rs, rate, phy_get_current_tx_num(adapter, rate), bw, band, cch, 0, 0, NULL); val /= hal_spec->txgi_pdbm; diff --git a/hal/hal_dm.c b/hal/hal_dm.c index 64a91f8..83bf523 100644 --- a/hal/hal_dm.c +++ b/hal/hal_dm.c @@ -86,7 +86,8 @@ void rtw_hal_update_iqk_fw_offload_cap(_adapter *adapter) } } -#if ((RTL8822B_SUPPORT == 1) || (RTL8821C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8822C_SUPPORT == 1)) +#if ((RTL8822B_SUPPORT == 1) || (RTL8821C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8822C_SUPPORT == 1) \ + || (RTL8723F_SUPPORT == 1)) void rtw_phydm_iqk_trigger(_adapter *adapter) { struct dm_struct *p_dm_odm = adapter_to_phydm(adapter); @@ -95,7 +96,7 @@ void rtw_phydm_iqk_trigger(_adapter *adapter) u8 rfk_forbidden = _FALSE; halrf_cmn_info_set(p_dm_odm, HALRF_CMNINFO_RFK_FORBIDDEN, rfk_forbidden); -#if (RTL8822C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) +#if (RTL8822C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8723F_SUPPORT == 1) /* halrf_cmn_info_set(p_dm_odm, HALRF_CMNINFO_IQK_SEGMENT, segment); to do */ halrf_rf_k_connect_trigger(p_dm_odm, _TRUE, SEGMENT_FREE); #else @@ -106,6 +107,30 @@ void rtw_phydm_iqk_trigger(_adapter *adapter) } #endif +void rtw_phydm_iqk_trigger_all(_adapter *adapter) +{ + struct dm_struct *p_dm_odm = adapter_to_phydm(adapter); + u8 clear = _TRUE; + u8 segment = _FALSE; + u8 rfk_forbidden = _FALSE; + +#if ((RTL8822B_SUPPORT == 1) || (RTL8821C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8822C_SUPPORT == 1) \ + || (RTL8723F_SUPPORT == 1)) + halrf_cmn_info_set(p_dm_odm, HALRF_CMNINFO_RFK_FORBIDDEN, rfk_forbidden); +#if (RTL8822C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8723F_SUPPORT == 1) + /* halrf_cmn_info_set(p_dm_odm, HALRF_CMNINFO_IQK_SEGMENT, segment); to do */ + halrf_rf_k_connect_trigger(p_dm_odm, _TRUE, SEGMENT_FREE); +#else + /*segment = _rtw_phydm_iqk_segment_chk(adapter);*/ + halrf_cmn_info_set(p_dm_odm, HALRF_CMNINFO_IQK_SEGMENT, segment); + halrf_segment_iqk_trigger(p_dm_odm, clear, segment); +#endif /* (RTL8822C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) (RTL8723F_SUPPORT == 1) */ +#else + halrf_iqk_trigger(p_dm_odm, _FALSE); +#endif /* ((RTL8822B_SUPPORT == 1) || (RTL8821C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8822C_SUPPORT == 1)) + (RTL8723F_SUPPORT == 1) */ +} + void rtw_phydm_iqk_trigger_dbg(_adapter *adapter, bool recovery, bool clear, bool segment) { struct dm_struct *p_dm_odm = adapter_to_phydm(adapter); @@ -122,6 +147,19 @@ void rtw_phydm_lck_trigger(_adapter *adapter) halrf_lck_trigger(p_dm_odm); } + +void rtw_hal_phydm_cal_trigger(_adapter *adapter) +{ + struct dm_struct *p_dm_odm = adapter_to_phydm(adapter); + + rtw_ps_deny(adapter, PS_DENY_IOCTL); + LeaveAllPowerSaveModeDirect(adapter); + + rtw_phydm_iqk_trigger_all(adapter); + + rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL); +} + #ifdef CONFIG_DBG_RF_CAL void rtw_hal_iqk_test(_adapter *adapter, bool recovery, bool clear, bool segment) { @@ -370,7 +408,7 @@ void Init_ODM_ComInfo(_adapter *adapter) rtw_hal_set_odm_var(adapter, HAL_ODM_REGULATION, NULL, _TRUE); #ifdef CONFIG_DFS_MASTER - odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_DFS_REGION_DOMAIN, adapter_to_rfctl(adapter)->dfs_region_domain); + rtw_odm_update_dfs_region(dvobj); odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_DFS_MASTER_ENABLE, &(adapter_to_rfctl(adapter)->radar_detect_enabled)); #endif @@ -407,6 +445,7 @@ void Init_ODM_ComInfo(_adapter *adapter) /*halrf info init*/ halrf_cmn_info_init(pDM_Odm, HALRF_CMNINFO_EEPROM_THERMAL_VALUE, pHalData->eeprom_thermal_meter); halrf_cmn_info_init(pDM_Odm, HALRF_CMNINFO_PWT_TYPE, 0); + halrf_cmn_info_init(pDM_Odm, HALRF_CMNINFO_MP_POWER_TRACKING_TYPE, pHalData->txpwr_pg_mode); if (rtw_odm_adaptivity_needed(adapter) == _TRUE) rtw_odm_adaptivity_config_msg(RTW_DBGDUMP, adapter); @@ -600,7 +639,7 @@ void rtw_hal_turbo_edca(_adapter *adapter) return; } - if (pregpriv->wifi_spec == 1) { /* || (pmlmeinfo->HT_enable == 0)) */ + if ((pregpriv->wifi_spec == 1)) { /* || (pmlmeinfo->HT_enable == 0)) */ precvpriv->is_any_non_be_pkts = _FALSE; return; } @@ -1035,6 +1074,18 @@ void GetHalODMVar( #ifdef RTW_HALMAC #include "../hal_halmac.h" #endif +bool rtw_phydm_rfe_ctrl_gpio( + _adapter *adapter, + u8 gpio_num +) +{ + #ifdef RTW_HALMAC + if(rtw_halmac_rfe_ctrl_cfg(adapter_to_dvobj(adapter), gpio_num)) + return _TRUE; + else + #endif/*RTW_HALMAC*/ + return _FALSE; +} enum hal_status rtw_phydm_fw_iqk( @@ -1160,6 +1211,7 @@ rtw_phydm_cfg_phy_para( void rtw_phydm_wd_lps_lclk_hdl(_adapter *adapter) { struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter); struct sta_priv *pstapriv = &adapter->stapriv; struct sta_info *psta = NULL; @@ -1181,6 +1233,14 @@ void rtw_phydm_wd_lps_lclk_hdl(_adapter *adapter) odm_cmn_info_update(&pHalData->odmpriv, ODM_CMNINFO_LINK, is_linked); phydm_watchdog_lps_32k(&pHalData->odmpriv); + +#ifdef CONFIG_LPS_PG + if (pwrpriv->lps_level == LPS_PG) { + if (rtw_hal_set_lps_pg_info_cmd(adapter) == _FAIL) + RTW_INFO(FUNC_ADPT_FMT": Send PG H2C command Fail! \n", + FUNC_ADPT_ARG(adapter)); + } +#endif /* CONFIG_LPS_PG */ } void rtw_phydm_watchdog_in_lps_lclk(_adapter *adapter) @@ -1338,6 +1398,8 @@ void dump_sta_info(void *sel, struct sta_info *psta) void rtw_phydm_ra_registed(_adapter *adapter, struct sta_info *psta) { HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj); if (psta == NULL) { RTW_ERR(FUNC_ADPT_FMT" sta is NULL\n", FUNC_ADPT_ARG(adapter)); @@ -1345,6 +1407,9 @@ void rtw_phydm_ra_registed(_adapter *adapter, struct sta_info *psta) return; } + if (psta->cmn.mac_id >= macid_ctl->num) + return; + phydm_ra_registed(&hal_data->odmpriv, psta->cmn.mac_id, psta->cmn.rssi_stat.rssi); dump_sta_info(RTW_DBGDUMP, psta); } @@ -1375,14 +1440,7 @@ void rtw_phydm_trx_cfg(_adapter *adapter, bool tx_1ss) } #endif - -/* -* trx_mode init - 8822B / 8822C / 8192F -* 1ssNTx - 8192E / 8812A / 8822B / 8822C / 8192F -* Path-diversity - 8822B / 8822C / 8192F -* PHYDM API - phydm_api_trx_mode -*/ -static u8 rtw_phydm_config_trx_path(_adapter *adapter) +u8 rtw_hal_runtime_trx_path_decision(_adapter *adapter) { HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); enum bb_path txpath; @@ -1441,13 +1499,6 @@ static u8 rtw_phydm_config_trx_path(_adapter *adapter) } else txpath_1ss = txpath; - if (phydm_api_trx_mode(adapter_to_phydm(adapter), txpath, rxpath, txpath_1ss) == FALSE) { - RTW_ERR("%s txpath=0x%x, rxpath=0x%x, txpath_1ss=0x%x fail\n", __func__ - , txpath, rxpath, txpath_1ss); - rtw_warn_on(1); - goto exit; - } - if (hal_data->txpath_nss[0] != txpath_1ss) { hal_data->txpath_nss[0] = txpath_1ss; if (txpath_1ss == BB_PATH_AUTO) @@ -1463,23 +1514,14 @@ static u8 rtw_phydm_config_trx_path(_adapter *adapter) } #elif defined(CONFIG_RTL8814B) { - if (config_phydm_trx_mode_8814b(adapter_to_phydm(adapter), txpath, rxpath) == FALSE) { - RTW_ERR("%s txpath=0x%x, rxpath=0x%x fail\n", __func__ - , txpath, rxpath); - rtw_warn_on(1); - goto exit; - } - /* 8814B is always full-TX */ tx_path_nss_set_full_tx(hal_data->txpath_nss, hal_data->txpath_num_nss, txpath); } #elif defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8192E) { #ifdef CONFIG_RTW_TX_NPATH_EN - if (adapter->registrypriv.tx_npath == 1) { - phydm_tx_2path(adapter_to_phydm(adapter)); + if (adapter->registrypriv.tx_npath == 1) tx_path_nss_set_full_tx(hal_data->txpath_nss, hal_data->txpath_num_nss, txpath); - } #endif } #endif @@ -1493,6 +1535,61 @@ exit: return rst; } +/* +* trx_mode init - 8822B / 8822C / 8192F +* 1ssNTx - 8192E / 8812A / 8822B / 8822C / 8192F +* Path-diversity - 8822B / 8822C / 8192F +* PHYDM API - phydm_api_trx_mode +*/ +static u8 rtw_phydm_config_trx_path(_adapter *adapter) +{ + u8 rst = _SUCCESS; + +#if defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8822B) ||defined(CONFIG_RTL8822C) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + enum bb_path txpath = hal_data->txpath; + enum bb_path rxpath = hal_data->rxpath; + enum bb_path txpath_1ss = hal_data->txpath_nss[0]; + + if (phydm_api_trx_mode(adapter_to_phydm(adapter), txpath, rxpath, txpath_1ss) == FALSE) { + RTW_ERR("%s txpath=0x%x, rxpath=0x%x, txpath_1ss=0x%x fail\n", __func__ + , txpath, rxpath, txpath_1ss); + rtw_warn_on(1); + rst = _FAIL; + } +} +#elif defined(CONFIG_RTL8814B) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + enum bb_path txpath = hal_data->txpath; + enum bb_path rxpath = hal_data->rxpath; + + if (txpath == BB_PATH_ABCD && rxpath == BB_PATH_ABCD) + rst = config_phydm_trx_mode_8814b(adapter_to_phydm(adapter), txpath, rxpath); + else + rst = config_phydm_trx_mode_ext_8814b(adapter_to_phydm(adapter), txpath, + rxpath, + txpath, txpath, txpath); + if (rst == FALSE) { + RTW_ERR("%s txpath=0x%x, rxpath=0x%x fail\n", __func__ + , txpath, rxpath); + rtw_warn_on(1); + rst = _FAIL; + } +} +#elif defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8192E) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + + if (hal_data->txpath_num_nss[0] == 2) + phydm_tx_2path(adapter_to_phydm(adapter)); +} +#endif + + return rst; +} + void rtw_phydm_init(_adapter *adapter) { PHAL_DATA_TYPE hal_data = GET_HAL_DATA(adapter); @@ -1500,7 +1597,8 @@ void rtw_phydm_init(_adapter *adapter) rtw_phydm_config_trx_path(adapter); init_phydm_info(adapter); - odm_dm_init(phydm); + hal_data->phydm_init_result = odm_dm_init(phydm); + #ifdef CONFIG_CUSTOMER01_SMART_ANTENNA phydm_pathb_q_matrix_rotate_en(phydm); #endif @@ -1712,12 +1810,23 @@ void rtw_dyn_soml_config(_adapter *adapter) void rtw_phydm_set_rrsr(_adapter *adapter, u32 rrsr_value, bool write_rrsr) { + struct dm_struct *phydm = adapter_to_phydm(adapter); + u32 temp_rrsr =0xFFFFFFFF; + if (adapter->registrypriv.set_rrsr_value != 0xFFFFFFFF) + temp_rrsr = adapter->registrypriv.set_rrsr_value; + else + temp_rrsr = rrsr_value; + + odm_cmn_info_update(phydm, ODM_CMNINFO_RRSR_VAL, temp_rrsr); + if(write_rrsr) + phydm_rrsr_set_register(phydm, temp_rrsr); +} +void rtw_phydm_dyn_rrsr_en(_adapter *adapter, bool en_rrsr) +{ struct dm_struct *phydm = adapter_to_phydm(adapter); - odm_cmn_info_update(phydm, ODM_CMNINFO_RRSR_VAL, rrsr_value); - if(write_rrsr) - phydm_rrsr_set_register(phydm, rrsr_value); + phydm_rrsr_en(phydm, en_rrsr); } void rtw_phydm_read_efuse(_adapter *adapter) { @@ -1763,7 +1872,7 @@ void rtw_phydm_watchdog(_adapter *adapter, bool in_lps) RTW_DBG("%s skip due to hw_init_completed == FALSE\n", __func__); return; } - if (rtw_mi_check_fwstate(adapter, _FW_UNDER_SURVEY)) + if (rtw_mi_check_fwstate(adapter, WIFI_UNDER_SURVEY)) pHalData->bScanInProcess = _TRUE; else pHalData->bScanInProcess = _FALSE; diff --git a/hal/hal_dm.h b/hal/hal_dm.h index e4caf43..863ffb7 100644 --- a/hal/hal_dm.h +++ b/hal/hal_dm.h @@ -47,12 +47,14 @@ void rtw_dyn_soml_para_set(_adapter *adapter, u8 train_num, u8 intvl, void rtw_dyn_soml_config(_adapter *adapter); #endif void rtw_phydm_set_rrsr(_adapter *adapter, u32 rrsr_value, bool write_rrsr); +void rtw_phydm_dyn_rrsr_en(_adapter *adapter, bool en_rrsr); void rtw_phydm_watchdog(_adapter *adapter, bool in_lps); void rtw_hal_update_iqk_fw_offload_cap(_adapter *adapter); void dump_sta_info(void *sel, struct sta_info *psta); void dump_sta_traffic(void *sel, _adapter *adapter, struct sta_info *psta); +void rtw_hal_phydm_cal_trigger(_adapter *adapter); #ifdef CONFIG_DBG_RF_CAL void rtw_hal_iqk_test(_adapter *adapter, bool recovery, bool clear, bool segment); void rtw_hal_lck_test(_adapter *adapter); @@ -93,7 +95,8 @@ enum phy_cnt { CRC32_ERROR_CCK, }; u32 rtw_phydm_get_phy_cnt(_adapter *adapter, enum phy_cnt cnt); -#if ((RTL8822B_SUPPORT == 1) || (RTL8821C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8822C_SUPPORT == 1)) +#if ((RTL8822B_SUPPORT == 1) || (RTL8821C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8822C_SUPPORT == 1) \ + || (RTL8723F_SUPPORT == 1)) void rtw_phydm_iqk_trigger(_adapter *adapter); #endif void rtw_phydm_read_efuse(_adapter *adapter); @@ -113,5 +116,6 @@ void rtw_phydm_pwr_tracking_directly(_adapter *adapter); #ifdef CONFIG_CTRL_TXSS_BY_TP void rtw_phydm_trx_cfg(_adapter *adapter, bool tx_1ss); #endif - +u8 rtw_hal_runtime_trx_path_decision(_adapter *adapter); +bool rtw_phydm_rfe_ctrl_gpio(_adapter *adapter, u8 gpio_num); #endif /* __HAL_DM_H__ */ diff --git a/hal/hal_dm_acs.c b/hal/hal_dm_acs.c index 5c19d99..0fa3414 100644 --- a/hal/hal_dm_acs.c +++ b/hal/hal_dm_acs.c @@ -87,8 +87,16 @@ u8 rtw_phydm_nhm_ratio(_adapter *adapter) { struct dm_struct *phydm = adapter_to_phydm(adapter); - return phydm_cmn_info_query(phydm, (enum phydm_info_query) PHYDM_INFO_NHM_RATIO); + return phydm_cmn_info_query(phydm, (enum phydm_info_query) PHYDM_INFO_NHM_ENV_RATIO); } + +u8 rtw_phydm_nhm_noise_pwr(_adapter *adapter) +{ + struct dm_struct *phydm = adapter_to_phydm(adapter); + + return phydm_cmn_info_query(phydm, (enum phydm_info_query) PHYDM_INFO_NHM_PWR); +} + void rtw_acs_reset(_adapter *adapter) { HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); @@ -203,7 +211,8 @@ void rtw_acs_get_rst(_adapter *adapter) (rpt.clm_rpt_stamp == hal_data->acs.trig_rpt.clm_rpt_stamp) && (rpt.nhm_rpt_stamp == hal_data->acs.trig_rpt.nhm_rpt_stamp)){ hal_data->acs.clm_ratio[chan_idx] = rpt.clm_ratio; - hal_data->acs.nhm_ratio[chan_idx] = rpt.nhm_ratio; + hal_data->acs.nhm_ratio[chan_idx] = rpt.nhm_env_ratio; + hal_data->acs.env_mntr_rpt[chan_idx] = (rpt.nhm_noise_pwr -100); _rtw_memcpy(&hal_data->acs.nhm[chan_idx][0], rpt.nhm_result, NHM_RPT_NUM); /*RTW_INFO("[ACS] get_rst success (rst = 0x%02x, clm_stamp:%d:%d, nhm_stamp:%d:%d)\n", @@ -228,6 +237,8 @@ void rtw_acs_get_rst(_adapter *adapter) #ifdef CONFIG_RTW_ACS_DBG RTW_INFO("[ACS] Result CH:%d, CLM:%d NHM:%d\n", cur_chan, hal_data->acs.clm_ratio[chan_idx], hal_data->acs.nhm_ratio[chan_idx]); + RTW_INFO("[ACS] Result NHM(dBm):%d\n", + hal_data->acs.env_mntr_rpt[chan_idx] ); #endif } @@ -246,9 +257,9 @@ void _rtw_phydm_acs_select_best_chan(_adapter *adapter) for (ch_idx = 0; ch_idx < max_chan_nums; ch_idx++) { if (pbss_nums[ch_idx]) - pinterference_time[ch_idx] = (pclm_ratio[ch_idx] / 2) + pnhm_ratio[ch_idx]; + pinterference_time[ch_idx] = (pclm_ratio[ch_idx] / 2) + (pnhm_ratio[ch_idx] / 2); else - pinterference_time[ch_idx] = pclm_ratio[ch_idx] + pnhm_ratio[ch_idx]; + pinterference_time[ch_idx] = (pclm_ratio[ch_idx] / 3) + ((pnhm_ratio[ch_idx] * 2) / 3); if (rtw_get_ch_num_by_idx(adapter, ch_idx) < 14) { if (pinterference_time[ch_idx] < min_itf_24g) { @@ -358,6 +369,18 @@ u8 rtw_acs_get_nhm_ratio_by_ch_num(_adapter *adapter, u8 chan) return hal_data->acs.nhm_ratio[chan_idx]; } +u8 rtw_acs_get_nhm_noise_pwr_by_ch_idx(_adapter *adapter, u8 ch_idx) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + + if (ch_idx >= MAX_CHANNEL_NUM) { + RTW_ERR("%s [ACS] ch_idx(%d) is invalid\n", __func__, ch_idx); + return 0; + } + + return hal_data->acs.env_mntr_rpt[ch_idx]; +} + u8 rtw_acs_get_num_ratio_by_ch_idx(_adapter *adapter, u8 ch_idx) { HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); @@ -429,6 +452,36 @@ void rtw_acs_update_current_info(_adapter *adapter) rtw_acs_current_info_dump(RTW_DBGDUMP, adapter); #endif } +/* +rsni +para1:rcpi=>RSSI in dbm +para2:anpi=>nhm in dbm +range:0~255 +255: is not available (defined by 802.11k spec) + +*/ +u8 rtw_acs_get_rsni(_adapter *adapter, s8 rcpi, u8 ch) +{ + struct dm_struct *phydm = adapter_to_phydm(adapter); + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + u8 rsni = 255; + s8 anpi = 0; + int chan_idx = -1; + + if(ch == 0) + goto exit; + + chan_idx = rtw_chset_search_ch(adapter_to_chset(adapter), ch); + if(chan_idx == -1) + goto exit; + + anpi = rtw_acs_get_nhm_noise_pwr_by_ch_idx(adapter, chan_idx); + if((rcpi != 0) && (anpi != 0)) + rsni = phydm_env_mntr_get_802_11_k_rsni(phydm, rcpi, anpi); + RTW_DBG("[ACS][RSNI]ch=%d chan_idx=%d RSNI=%u RSSI=%d NHM=%d\n", ch, chan_idx, rsni,rcpi, anpi); +exit: + return rsni; +} #endif /*CONFIG_RTW_ACS*/ #ifdef CONFIG_BACKGROUND_NOISE_MONITOR diff --git a/hal/hal_dm_acs.h b/hal/hal_dm_acs.h index 871c144..f962001 100644 --- a/hal/hal_dm_acs.h +++ b/hal/hal_dm_acs.h @@ -80,6 +80,7 @@ struct auto_chan_sel { bool triggered; u8 clm_ratio[MAX_CHANNEL_NUM]; u8 nhm_ratio[MAX_CHANNEL_NUM]; + s8 env_mntr_rpt[MAX_CHANNEL_NUM]; /*unit:dbm*/ #if (RTK_ACS_VERSION == 3) u8 nhm[MAX_CHANNEL_NUM][NHM_RPT_NUM]; #endif @@ -124,8 +125,13 @@ void rtw_acs_adv_reset(_adapter *adapter); u8 rtw_acs_get_clm_ratio_by_ch_num(_adapter *adapter, u8 chan); u8 rtw_acs_get_clm_ratio_by_ch_idx(_adapter *adapter, u8 ch_idx); u8 rtw_acs_get_nhm_ratio_by_ch_num(_adapter *adapter, u8 chan); +u8 rtw_acs_get_nhm_noise_pwr_by_ch_idx(_adapter *adapter, u8 ch_idx); u8 rtw_acs_get_num_ratio_by_ch_idx(_adapter *adapter, u8 ch_idx); +u8 rtw_phydm_clm_ratio(_adapter *adapter); +u8 rtw_phydm_nhm_ratio(_adapter *adapter); +u8 rtw_phydm_nhm_noise_pwr(_adapter *adapter); + void rtw_acs_reset(_adapter *adapter); void rtw_acs_trigger(_adapter *adapter, u16 scan_time_ms, u8 scan_chan, enum NHM_PID pid); void rtw_acs_get_rst(_adapter *adapter); @@ -137,7 +143,7 @@ void rtw_acs_current_info_dump(void *sel, _adapter *adapter); void rtw_acs_start(_adapter *adapter); void rtw_acs_stop(_adapter *adapter); - +u8 rtw_acs_get_rsni(_adapter *adapter, s8 rcpi, u8 ch); #endif /*CONFIG_RTW_ACS*/ #ifdef CONFIG_BACKGROUND_NOISE_MONITOR diff --git a/hal/hal_halmac.c b/hal/hal_halmac.c index 43ffcc9..aa1bbf9 100644 --- a/hal/hal_halmac.c +++ b/hal/hal_halmac.c @@ -29,6 +29,7 @@ #define MSG_PREFIX "[HALMAC]" #define RTW_HALMAC_DLFW_MEM_NO_STOP_TX +#define RTW_HALMAC_FILTER_DRV_C2H /* Block C2H owner=driver */ /* * Driver API for HALMAC operations @@ -569,6 +570,7 @@ const char *const RTW_HALMAC_FEATURE_NAME[] = { "HALMAC_FEATURE_POWER_TRACKING", "HALMAC_FEATURE_PSD", "HALMAC_FEATURE_FW_SNDING", + "HALMAC_FEATURE_DPK", "HALMAC_FEATURE_ALL" }; @@ -622,6 +624,15 @@ static inline u8 is_valid_id_status(enum halmac_feature_id id, enum halmac_cmd_p case HALMAC_FEATURE_FW_SNDING: RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]); break; + case HALMAC_FEATURE_DPK: + if (status == HALMAC_CMD_PROCESS_RCVD) + return _FALSE; + if ((status != HALMAC_CMD_PROCESS_DONE) + || (status != HALMAC_CMD_PROCESS_ERROR)) + RTW_WARN("%s: %s unexpected status(0x%x)!\n", + __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id], + status); + break; case HALMAC_FEATURE_ALL: RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]); break; @@ -682,6 +693,7 @@ static int wait_halmac_event(struct dvobj_priv *d, enum halmac_feature_id id) struct halmac_adapter *mac; struct halmac_api *api; struct submit_ctx *sctx; + int status; int ret; @@ -690,13 +702,16 @@ static int wait_halmac_event(struct dvobj_priv *d, enum halmac_feature_id id) return -1; ret = rtw_sctx_wait(sctx, RTW_HALMAC_FEATURE_NAME[id]); + status = sctx->status; free_halmac_event(d, id); if (_SUCCESS == ret) return 0; - /* timeout! We have to reset halmac state */ - RTW_ERR("%s: Wait id(%d, %s) TIMEOUT! Reset HALMAC state!\n", - __FUNCTION__, id, RTW_HALMAC_FEATURE_NAME[id]); + /* If no one change sctx->status, it is timeout case */ + if (status == 0) + status = RTW_SCTX_DONE_TIMEOUT; + RTW_ERR("%s: id(%d, %s) status=0x%x ! Reset HALMAC state!\n", + __FUNCTION__, id, RTW_HALMAC_FEATURE_NAME[id], status); mac = dvobj_to_halmac(d); api = HALMAC_GET_API(mac); api->halmac_reset_feature(mac, id); @@ -708,7 +723,9 @@ static int wait_halmac_event(struct dvobj_priv *d, enum halmac_feature_id id) * Return: * Always return RTW_HALMAC_SUCCESS, HALMAC don't care the return value. */ -static u8 _halmac_event_indication(void *p, enum halmac_feature_id feature_id, enum halmac_cmd_process_status process_status, u8 *buf, u32 size) +static u8 _halmac_event_indication(void *p, enum halmac_feature_id feature_id, + enum halmac_cmd_process_status process_status, + u8 *buf, u32 size) { struct dvobj_priv *d; PADAPTER adapter; @@ -733,20 +750,27 @@ static u8 _halmac_event_indication(void *p, enum halmac_feature_id feature_id, e indicator->status = process_status; indicator->ret_size = size; if (!indicator->sctx) { - RTW_WARN("%s: No feature id(%d, %s) waiting!!\n", __FUNCTION__, feature_id, RTW_HALMAC_FEATURE_NAME[feature_id]); + RTW_WARN("%s: id(%d, %s) is not waiting!!\n", __FUNCTION__, + feature_id, RTW_HALMAC_FEATURE_NAME[feature_id]); goto exit; } sctx = indicator->sctx; if (HALMAC_CMD_PROCESS_ERROR == process_status) { - RTW_ERR("%s: Something wrong id(%d, %s)!!\n", __FUNCTION__, feature_id, RTW_HALMAC_FEATURE_NAME[feature_id]); + RTW_ERR("%s: id(%d, %s) Something wrong!!\n", __FUNCTION__, + feature_id, RTW_HALMAC_FEATURE_NAME[feature_id]); + if ((size == 1) && buf) + RTW_ERR("%s: error code=0x%x\n", __FUNCTION__, *buf); rtw_sctx_done_err(&sctx, RTW_SCTX_DONE_UNKNOWN); goto exit; } if (size > indicator->buf_size) { - RTW_WARN("%s: id(%d, %s) buffer is not enough(%d<%d), data will be truncated!\n", - __FUNCTION__, feature_id, RTW_HALMAC_FEATURE_NAME[feature_id], indicator->buf_size, size); + RTW_WARN("%s: id(%d, %s) buffer is not enough(%d<%d), " + "and data will be truncated!\n", + __FUNCTION__, + feature_id, RTW_HALMAC_FEATURE_NAME[feature_id], + indicator->buf_size, size); cpsz = indicator->buf_size; } else { cpsz = size; @@ -1194,6 +1218,7 @@ int rtw_halmac_init_adapter(struct dvobj_priv *d, struct halmac_platform_api *pf struct halmac_adapter *halmac; struct halmac_api *api; enum halmac_interface intf; + enum halmac_intf_phy_platform pltfm = HALMAC_INTF_PHY_PLATFORM_ALL; enum halmac_ret_status status; int err = 0; #ifdef CONFIG_SDIO_HCI @@ -1239,9 +1264,13 @@ int rtw_halmac_init_adapter(struct dvobj_priv *d, struct halmac_platform_api *pf goto deinit; } - status = api->halmac_phy_cfg(halmac, HALMAC_INTF_PHY_PLATFORM_ALL); +#ifdef CONFIG_PLATFORM_RTK1319 + pltfm = HALMAC_INTF_PHY_PLATFORM_DHC; +#endif /* CONFIG_PLATFORM_RTK1319 */ + status = api->halmac_phy_cfg(halmac, pltfm); if (status != HALMAC_RET_SUCCESS) { - RTW_ERR("%s: halmac_phy_cfg fail!(status=%d)\n", __FUNCTION__, status); + RTW_ERR("%s: halmac_phy_cfg fail! (platform=%d, status=%d)\n", + __FUNCTION__, pltfm, status); err = -1; goto deinit; } @@ -1254,9 +1283,13 @@ int rtw_halmac_init_adapter(struct dvobj_priv *d, struct halmac_platform_api *pf /* Convert clock speed unit to MHz from Hz */ info.clock_speed = RTW_DIV_ROUND_UP(rtw_sdio_get_clock(d), 1000000); info.block_size = rtw_sdio_get_block_size(d); - RTW_DBG("%s: SDIO ver=%u clock=%uMHz blk_size=%u bytes\n", + if (d->hmpriv.sdio_io_indir == 2) + info.io_indir_flag = 0; + else + info.io_indir_flag = 1; /* Default enable indirect I/O */ + RTW_DBG("%s: SDIO ver=%u clock=%uMHz blk_size=%u bytes, io_indir=%u\n", __FUNCTION__, info.spec_ver+2, info.clock_speed, - info.block_size); + info.block_size, info.io_indir_flag); status = api->halmac_sdio_hw_info(halmac, &info); if (status != HALMAC_RET_SUCCESS) { RTW_ERR("%s: halmac_sdio_hw_info fail!(status=%d)\n", @@ -3473,6 +3506,16 @@ static int init_mac_flow(struct dvobj_priv *d) /* Sync driver RCR cache with register setting */ rtw_hal_get_hwreg(dvobj_get_primary_adapter(d), HW_VAR_RCR, NULL); +#ifdef CONFIG_RTS_FULL_BW + err = rtw_halmac_set_rts_full_bw(d, _TRUE); + if (err) + RTW_WARN("%s: Fail to set RTS FULL BW mode\n", __FUNCTION__); +#else + err = rtw_halmac_set_rts_full_bw(d, _FALSE); + if (err) + RTW_WARN("%s: Fail to disable RTS FULL BW mode\n", __FUNCTION__); +#endif /* CONFIG_RTS_FULL_BW */ + _init_trx_cfg_drv(d); /* Driver inser flow end */ @@ -4137,11 +4180,56 @@ int rtw_halmac_c2h_handle(struct dvobj_priv *d, u8 *c2h, u32 size) struct halmac_adapter *mac; struct halmac_api *api; enum halmac_ret_status status; +#ifdef RTW_HALMAC_FILTER_DRV_C2H + u32 desc_size = 0; + u8 *c2h_data; + u8 sub; +#endif /* RTW_HALMAC_FILTER_DRV_C2H */ mac = dvobj_to_halmac(d); api = HALMAC_GET_API(mac); +#ifdef RTW_HALMAC_FILTER_DRV_C2H + status = api->halmac_get_hw_value(mac, HALMAC_HW_RX_DESC_SIZE, + &desc_size); + if (status != HALMAC_RET_SUCCESS) { + RTW_ERR("%s: fail to get rx desc size!\n", __FUNCTION__); + goto skip_filter; + } + + c2h_data = c2h + desc_size; + sub = C2H_HDR_GET_C2H_SUB_CMD_ID(c2h_data); + switch (sub) { + case C2H_SUB_CMD_ID_C2H_PKT_FTM_DBG: + case C2H_SUB_CMD_ID_C2H_PKT_FTM_2_DBG: + case C2H_SUB_CMD_ID_C2H_PKT_FTM_3_DBG: + case C2H_SUB_CMD_ID_C2H_PKT_FTM_4_DBG: + case C2H_SUB_CMD_ID_FTMACKRPT_HDL_DBG: + case C2H_SUB_CMD_ID_FTMC2H_RPT: + case C2H_SUB_CMD_ID_DRVFTMC2H_RPT: + case C2H_SUB_CMD_ID_C2H_PKT_FTM_5_DBG: + case C2H_SUB_CMD_ID_CCX_RPT: + case C2H_SUB_CMD_ID_C2H_PKT_NAN_RPT: + case C2H_SUB_CMD_ID_C2H_PKT_ATM_RPT: + case C2H_SUB_CMD_ID_C2H_PKT_SCC_CSA_RPT: + case C2H_SUB_CMD_ID_C2H_PKT_FW_STATUS_NOTIFY: + case C2H_SUB_CMD_ID_C2H_PKT_FTMSESSION_END: + case C2H_SUB_CMD_ID_C2H_PKT_DETECT_THERMAL: + case C2H_SUB_CMD_ID_FW_FWCTRL_RPT: + case C2H_SUB_CMD_ID_SCAN_CH_NOTIFY: + case C2H_SUB_CMD_ID_FW_TBTT_RPT: + case C2H_SUB_CMD_ID_BCN_OFFLOAD: + case C2H_SUB_CMD_ID_FW_DBG_MSG: + RTW_PRINT("%s: unhandled C2H, id=0xFF subid=0x%x len=%u\n", + __FUNCTION__, sub, C2H_HDR_GET_LEN(c2h_data)); + RTW_PRINT_DUMP("C2H: ", c2h_data, size - desc_size); + return 0; + } + +skip_filter: +#endif /* RTW_HALMAC_FILTER_DRV_C2H */ + status = api->halmac_get_c2h_info(mac, c2h, size); if (HALMAC_RET_SUCCESS != status) return -1; @@ -4761,6 +4849,48 @@ int rtw_halmac_iqk(struct dvobj_priv *d, u8 clear, u8 segment) return 0; } +/** + * rtw_halmac_dpk() - Run DP Calibration + * @d: struct dvobj_priv* + * @buf: buffer for store return value + * @bufsz: size of buffer + * + * Process DP Calibration(DPK). + * + * Return 0 for OK, otherwise fail. + */ +int rtw_halmac_dpk(struct dvobj_priv *d, u8 *buf, u32 bufsz) +{ + struct halmac_adapter *mac; + struct halmac_api *api; + enum halmac_ret_status status; + enum halmac_feature_id id; + int ret; + + + mac = dvobj_to_halmac(d); + api = HALMAC_GET_API(mac); + id = HALMAC_FEATURE_DPK; + + ret = init_halmac_event(d, id, buf, bufsz); + if (ret) + return -1; + + status = api->halmac_start_dpk(mac); + if (status != HALMAC_RET_SUCCESS) { + free_halmac_event(d, id); + RTW_ERR("%s: Fail to start DPK (0x%x)!\n", + __FUNCTION__, status); + return -1; + } + + ret = wait_halmac_event(d, id); + if (ret) + return -1; + + return 0; +} + static inline u32 _phy_parameter_val_drv2halmac(u32 val, u8 msk_en, u32 msk) { if (!msk_en) @@ -5034,6 +5164,35 @@ void rtw_halmac_led_switch(struct dvobj_priv *d, u8 on) api->halmac_pinmux_wl_led_sw_ctrl(halmac, on); } +static int _gpio_cfg(struct dvobj_priv *d, enum halmac_gpio_func gpio, u8 enable) +{ + struct halmac_adapter *halmac; + struct halmac_api *api; + enum halmac_ret_status status; + + + halmac = dvobj_to_halmac(d); + api = HALMAC_GET_API(halmac); + + if (enable) { + status = api->halmac_pinmux_set_func(halmac, gpio); + if (status != HALMAC_RET_SUCCESS) { + RTW_ERR("%s: pinmux set GPIO(%d) fail!(0x%x)\n", + __FUNCTION__, gpio, status); + return -1; + } + } else { + status = api->halmac_pinmux_free_func(halmac, gpio); + if (status != HALMAC_RET_SUCCESS) { + RTW_ERR("%s: pinmux free GPIO(%d) fail!(0x%x)\n", + __FUNCTION__, gpio, status); + return -1; + } + } + + return 0; +} + /** * rtw_halmac_bt_wake_cfg() - Configure BT wake host function * @d: struct dvobj_priv* @@ -5047,33 +5206,58 @@ void rtw_halmac_led_switch(struct dvobj_priv *d, u8 on) */ int rtw_halmac_bt_wake_cfg(struct dvobj_priv *d, u8 enable) { - struct halmac_adapter *halmac; - struct halmac_api *api; - enum halmac_ret_status status; + return _gpio_cfg(d, HALMAC_GPIO_FUNC_BT_HOST_WAKE1, enable); +} + +static enum halmac_gpio_func _gpio_to_func_for_rfe_ctrl(u8 gpio) +{ + enum halmac_gpio_func f = HALMAC_GPIO_FUNC_UNDEFINE; - halmac = dvobj_to_halmac(d); - api = HALMAC_GET_API(halmac); - - if (enable) { - status = api->halmac_pinmux_set_func(halmac, - HALMAC_GPIO_FUNC_BT_HOST_WAKE1); - if (status != HALMAC_RET_SUCCESS) { - RTW_ERR("%s: pinmux set BT_HOST_WAKE1 fail!(0x%x)\n", - __FUNCTION__, status); - return -1; - } - } else { - status = api->halmac_pinmux_free_func(halmac, - HALMAC_GPIO_FUNC_BT_HOST_WAKE1); - if (status != HALMAC_RET_SUCCESS) { - RTW_ERR("%s: pinmux free BT_HOST_WAKE1 fail!(0x%x)\n", - __FUNCTION__, status); - return -1; - } +#ifdef CONFIG_RTL8822C + switch (gpio) { + case 1: + f = HALMAC_GPIO_FUNC_ANTSWB; + break; + case 2: + f = HALMAC_GPIO_FUNC_S1_TRSW; + break; + case 3: + f = HALMAC_GPIO_FUNC_S0_TRSW; + break; + case 6: + f = HALMAC_GPIO_FUNC_S0_PAPE; + break; + case 7: + f = HALMAC_GPIO_FUNC_S0_TRSWB; + break; + case 13: + f = HALMAC_GPIO_FUNC_ANTSW; + break; } +#endif /* CONFIG_RTL8822C */ - return 0; + return f; +} + +/** + * rtw_halmac_rfe_ctrl_cfg() - Configure RFE control GPIO + * @d: struct dvobj_priv* + * @gpio: gpio number + * + * Configure pinmux to enable RFE control GPIO. + * + * Return 0 for OK, otherwise fail. + */ +int rtw_halmac_rfe_ctrl_cfg(struct dvobj_priv *d, u8 gpio) +{ + enum halmac_gpio_func f; + + + f = _gpio_to_func_for_rfe_ctrl(gpio); + if (f == HALMAC_GPIO_FUNC_UNDEFINE) + return -1; + return _gpio_cfg(d, f, 1); } #ifdef CONFIG_PNO_SUPPORT @@ -5277,6 +5461,37 @@ int rtw_halmac_pno_scanoffload(struct dvobj_priv *d, u32 enable) #ifdef CONFIG_SDIO_HCI +/** + * rtw_halmac_preinit_sdio_io_indirect() - Enable indirect I/O or not + * @d: struct dvobj_priv* + * @enable: true: enable, false: disable + * + * Enable register access using direct I/O or indirect. This function should be + * called before rtw_halmac_init_adapter(), and the life cycle is the same as + * driver until removing driver. + * + * Return 0 for OK, otherwise fail. + */ +int rtw_halmac_preinit_sdio_io_indirect(struct dvobj_priv *d, bool enable) +{ + struct halmac_adapter *halmac; + struct halmacpriv *priv; + + + halmac = dvobj_to_halmac(d); + if (halmac) { + RTW_WARN("%s: illegal operation! " + "preinit function only could be called before init!\n", + __FUNCTION__); + return -1; + } + + priv = &d->hmpriv; + priv->sdio_io_indir = (enable ? 1 : 2); + + return 0; +} + /* * Description: * Update queue allocated page number to driver diff --git a/hal/hal_halmac.h b/hal/hal_halmac.h index 3a46727..7388226 100644 --- a/hal/hal_halmac.h +++ b/hal/hal_halmac.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2015 - 2018 Realtek Corporation. + * Copyright(c) 2015 - 2019 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -116,6 +116,9 @@ int rtw_halmac_write32(struct intf_hdl *, u32 addr, u32 value); /* Software Information */ void rtw_halmac_get_version(char *str, u32 len); +/* Software setting before Initialization */ +int rtw_halmac_preinit_sdio_io_indirect(struct dvobj_priv *d, bool enable); + /* Software Initialization */ int rtw_halmac_init_adapter(struct dvobj_priv *d, struct halmac_platform_api *pf_api); int rtw_halmac_deinit_adapter(struct dvobj_priv *); @@ -195,10 +198,12 @@ int rtw_halmac_download_rsvd_page(struct dvobj_priv *dvobj, u8 pg_offset, u8 *pb int rtw_halmac_fill_hal_spec(struct dvobj_priv *, struct hal_spec_t *); int rtw_halmac_p2pps(struct dvobj_priv *dvobj, PHAL_P2P_PS_PARA pp2p_ps_para); int rtw_halmac_iqk(struct dvobj_priv *d, u8 clear, u8 segment); +int rtw_halmac_dpk(struct dvobj_priv *d, u8 *buf, u32 bufsz); int rtw_halmac_cfg_phy_para(struct dvobj_priv *d, struct rtw_phy_parameter *para); int rtw_halmac_led_cfg(struct dvobj_priv *d, u8 enable, u8 mode); void rtw_halmac_led_switch(struct dvobj_priv *d, u8 on); int rtw_halmac_bt_wake_cfg(struct dvobj_priv *d, u8 enable); +int rtw_halmac_rfe_ctrl_cfg(struct dvobj_priv *d, u8 gpio); #ifdef CONFIG_PNO_SUPPORT int rtw_halmac_pno_scanoffload(struct dvobj_priv *d, u32 enable); #endif diff --git a/hal/hal_hci/hal_usb.c b/hal/hal_hci/hal_usb.c index 20dc07b..609616b 100644 --- a/hal/hal_hci/hal_usb.c +++ b/hal/hal_hci/hal_usb.c @@ -19,6 +19,7 @@ int usb_init_recv_priv(_adapter *padapter, u16 ini_in_buf_sz) { + struct registry_priv *regsty = adapter_to_regsty(padapter); struct recv_priv *precvpriv = &padapter->recvpriv; int i, res = _SUCCESS; struct recv_buf *precvbuf; @@ -60,9 +61,9 @@ int usb_init_recv_priv(_adapter *padapter, u16 ini_in_buf_sz) skb_queue_head_init(&precvpriv->free_recv_skb_queue); #endif - RTW_INFO("NR_RECVBUFF: %d\n", NR_RECVBUFF); + RTW_INFO("NR_RECVBUFF: %d, recvbuf_nr: %d\n", NR_RECVBUFF, regsty->recvbuf_nr); RTW_INFO("MAX_RECVBUF_SZ: %d\n", MAX_RECVBUF_SZ); - precvpriv->pallocated_recv_buf = rtw_zmalloc(NR_RECVBUFF * sizeof(struct recv_buf) + 4); + precvpriv->pallocated_recv_buf = rtw_zmalloc(regsty->recvbuf_nr * sizeof(struct recv_buf) + 4); if (precvpriv->pallocated_recv_buf == NULL) { res = _FAIL; goto exit; @@ -72,14 +73,16 @@ int usb_init_recv_priv(_adapter *padapter, u16 ini_in_buf_sz) precvbuf = (struct recv_buf *)precvpriv->precv_buf; - for (i = 0; i < NR_RECVBUFF ; i++) { + for (i = 0; i < regsty->recvbuf_nr ; i++) { _rtw_init_listhead(&precvbuf->list); +#ifdef PLATFORM_WINDOWS _rtw_spinlock_init(&precvbuf->recvbuf_lock); +#endif precvbuf->alloc_sz = MAX_RECVBUF_SZ; - res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf); + res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf, precvbuf->alloc_sz); if (res == _FAIL) break; @@ -91,7 +94,7 @@ int usb_init_recv_priv(_adapter *padapter, u16 ini_in_buf_sz) precvbuf++; } - precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF; + precvpriv->free_recv_buf_queue_cnt = regsty->recvbuf_nr; #if defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD) @@ -149,18 +152,19 @@ exit: void usb_free_recv_priv(_adapter *padapter, u16 ini_in_buf_sz) { int i; + struct registry_priv *regsty = &padapter->registrypriv; struct recv_buf *precvbuf; struct recv_priv *precvpriv = &padapter->recvpriv; precvbuf = (struct recv_buf *)precvpriv->precv_buf; - for (i = 0; i < NR_RECVBUFF ; i++) { + for (i = 0; i < regsty->recvbuf_nr ; i++) { rtw_os_recvbuf_resource_free(padapter, precvbuf); precvbuf++; } if (precvpriv->pallocated_recv_buf) - rtw_mfree(precvpriv->pallocated_recv_buf, NR_RECVBUFF * sizeof(struct recv_buf) + 4); + rtw_mfree(precvpriv->pallocated_recv_buf, regsty->recvbuf_nr * sizeof(struct recv_buf) + 4); #ifdef CONFIG_USB_INTERRUPT_IN_PIPE #ifdef PLATFORM_LINUX diff --git a/hal/hal_intf.c b/hal/hal_intf.c index 5bc116e..a6eb51e 100644 --- a/hal/hal_intf.c +++ b/hal/hal_intf.c @@ -36,6 +36,7 @@ const u32 _chip_type_to_odm_ic_type[] = { ODM_RTL8192F, ODM_RTL8822C, ODM_RTL8814B, + ODM_RTL8723F, 0, }; @@ -86,13 +87,12 @@ static void rtw_init_wireless_mode(_adapter *padapter) struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); if(hal_spec->proto_cap & PROTO_CAP_11B) proto_wireless_mode |= WIRELESS_11B; - + if(hal_spec->proto_cap & PROTO_CAP_11G) proto_wireless_mode |= WIRELESS_11G; -#ifdef CONFIG_80211AC_VHT + if(hal_spec->band_cap & BAND_CAP_5G) proto_wireless_mode |= WIRELESS_11A; -#endif #ifdef CONFIG_80211N_HT if(hal_spec->proto_cap & PROTO_CAP_11N) { @@ -252,6 +252,7 @@ void dump_hal_trx_mode(void *sel, _adapter *adapter) { struct registry_priv *regpriv = &adapter->registrypriv; PHAL_DATA_TYPE hal_data = GET_HAL_DATA(adapter); + int i; RTW_PRINT_SEL(sel, "trx_path_bmp:0x%02x(%s), NumTotalRFPath:%u, max_tx_cnt:%u\n" , hal_data->trx_path_bmp @@ -261,6 +262,9 @@ void dump_hal_trx_mode(void *sel, _adapter *adapter) ); RTW_PRINT_SEL(sel, "tx_nss:%u, rx_nss:%u\n" , hal_data->tx_nss, hal_data->rx_nss); + for (i = 0; i < hal_data->tx_nss; i++) + RTW_PRINT_SEL(sel, "txpath_cap_num_%uss:%u\n" + , i + 1, hal_data->txpath_cap_num_nss[i]); RTW_PRINT_SEL(sel, "\n"); dump_hal_runtime_trx_mode(sel, adapter); @@ -268,25 +272,22 @@ void dump_hal_trx_mode(void *sel, _adapter *adapter) void _dump_rf_path(void *sel, _adapter *adapter) { - struct registry_priv *regpriv = &adapter->registrypriv; PHAL_DATA_TYPE hal_data = GET_HAL_DATA(adapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); + struct registry_priv *regsty = adapter_to_regsty(adapter); - RTW_PRINT_SEL(sel, "[RF_PATH] ver_id.RF_TYPE:%s, rf_reg_path_num:%u, max_tx_cnt:%u\n" - , rf_type_to_rfpath_str(rtw_chip_rftype_to_hal_rftype(adapter, 0)) - , GET_HAL_SPEC(adapter)->rf_reg_path_num - , GET_HAL_SPEC(adapter)->max_tx_cnt); + RTW_PRINT_SEL(sel, "[RF_PATH] ver_id.RF_TYPE:%s\n" + , rf_type_to_rfpath_str(rtw_chip_rftype_to_hal_rftype(adapter, 0))); + RTW_PRINT_SEL(sel, "[RF_PATH] HALSPEC's rf_reg_trx_path_bmp:0x%02x, rf_reg_path_avail_num:%u, max_tx_cnt:%u\n" + , hal_spec->rf_reg_trx_path_bmp, hal_spec->rf_reg_path_avail_num, hal_spec->max_tx_cnt); RTW_PRINT_SEL(sel, "[RF_PATH] PG's trx_path_bmp:0x%02x, max_tx_cnt:%u\n" , hal_data->eeprom_trx_path_bmp, hal_data->eeprom_max_tx_cnt); - - RTW_PRINT_SEL(sel, "[RF_PATH] Registry's RF PATH:%s\n" - , rf_type_to_rfpath_str(regpriv->rf_path)); - + RTW_PRINT_SEL(sel, "[RF_PATH] Registry's trx_path_bmp:0x%02x, tx_path_lmt:%u, rx_path_lmt:%u\n" + , regsty->trx_path_bmp, regsty->tx_path_lmt, regsty->rx_path_lmt); RTW_PRINT_SEL(sel, "[RF_PATH] HALDATA's trx_path_bmp:0x%02x, max_tx_cnt:%u\n" , hal_data->trx_path_bmp, hal_data->max_tx_cnt); - RTW_PRINT_SEL(sel, "[RF_PATH] HALDATA's rf_type:%s\n" - , rf_type_to_rfpath_str(hal_data->rf_type)); - RTW_PRINT_SEL(sel, "[RF_PATH] NumTotalRFPath:%d\n" - , hal_data->NumTotalRFPath); + RTW_PRINT_SEL(sel, "[RF_PATH] HALDATA's rf_type:%s, NumTotalRFPath:%d\n" + , rf_type_to_rfpath_str(hal_data->rf_type), hal_data->NumTotalRFPath); } #ifdef CONFIG_RTL8814A @@ -310,56 +311,43 @@ if (IS_HARDWARE_TYPE_8814A(adapter)) { } else #endif { - struct registry_priv *regpriv = &adapter->registrypriv; - enum rf_type ic_cap; - enum rf_type type; + struct registry_priv *regsty = adapter_to_regsty(adapter); + u8 trx_path_bmp; u8 tx_path_num; u8 rx_path_num; int i; - ic_cap = rtw_chip_rftype_to_hal_rftype(adapter, hal_spec->rf_reg_path_num); - if (!RF_TYPE_VALID(ic_cap)) { - RTW_ERR("%s rtw_chip_rftype_to_hal_rftype failed\n", __func__); - return _FAIL; - } - type = ic_cap; - - if (RF_TYPE_VALID(regpriv->rf_path)) { - if (rf_type_is_a_in_b(regpriv->rf_path, ic_cap)) - type = regpriv->rf_path; - else - RTW_WARN("%s invalid regpriv:%s > ic_cap:%s\n", __func__ - , rf_type_to_rfpath_str(regpriv->rf_path) - , rf_type_to_rfpath_str(ic_cap)); - } - - if (hal_data->eeprom_trx_path_bmp != 0x00) { - /* specific trx path is defined, restrict it with rftype(TX and RX num) */ - u8 trx_path_bmp = rtw_restrict_trx_path_bmp_by_rftype( - hal_data->eeprom_trx_path_bmp, type, &tx_path_num, &rx_path_num); + trx_path_bmp = hal_spec->rf_reg_trx_path_bmp; + + if (regsty->trx_path_bmp != 0x00) { + /* restrict trx_path_bmp with regsty.trx_path_bmp */ + trx_path_bmp &= regsty->trx_path_bmp; if (!trx_path_bmp) { - RTW_ERR("%s rtw_restrict_trx_path_bmp_by_rftype(0x%x, %s) failed\n" - , __func__, hal_data->eeprom_trx_path_bmp - , rf_type_to_rfpath_str(type)); + RTW_ERR("%s hal_spec.rf_reg_trx_path_bmp:0x%02x, regsty->trx_path_bmp:0x%02x no intersection\n" + , __func__, hal_spec->rf_reg_trx_path_bmp, regsty->trx_path_bmp); + return _FAIL; + } + } else if (hal_data->eeprom_trx_path_bmp != 0x00) { + /* restrict trx_path_bmp with eeprom_trx_path_bmp */ + trx_path_bmp &= hal_data->eeprom_trx_path_bmp; + if (!trx_path_bmp) { + RTW_ERR("%s hal_spec.rf_reg_trx_path_bmp:0x%02x, hal_data->eeprom_trx_path_bmp:0x%02x no intersection\n" + , __func__, hal_spec->rf_reg_trx_path_bmp, hal_data->eeprom_trx_path_bmp); return _FAIL; } - hal_data->trx_path_bmp = trx_path_bmp; - hal_data->rf_type = trx_bmp_to_rf_type((trx_path_bmp & 0xF0) >> 4 - , trx_path_bmp & 0x0F); - } else { - /* no specific trx path is defined, use default trx_bmp */ - enum bb_path tx_bmp, rx_bmp; - - rf_type_to_default_trx_bmp(type, &tx_bmp, &rx_bmp); - hal_data->trx_path_bmp = (tx_bmp << 4) | rx_bmp; - hal_data->rf_type = type; - tx_path_num = rf_type_to_rf_tx_cnt(hal_data->rf_type); - rx_path_num = rf_type_to_rf_rx_cnt(hal_data->rf_type); } - hal_data->NumTotalRFPath = tx_path_num; - if (hal_data->NumTotalRFPath < rx_path_num) - hal_data->NumTotalRFPath = rx_path_num; + /* restrict trx_path_bmp with TX and RX num limit */ + trx_path_bmp = rtw_restrict_trx_path_bmp_by_trx_num_lmt(trx_path_bmp + , regsty->tx_path_lmt, regsty->rx_path_lmt, &tx_path_num, &rx_path_num); + if (!trx_path_bmp) { + RTW_ERR("%s rtw_restrict_trx_path_bmp_by_trx_num_lmt(0x%02x, %u, %u) failed\n" + , __func__, trx_path_bmp, regsty->tx_path_lmt, regsty->rx_path_lmt); + return _FAIL; + } + hal_data->trx_path_bmp = trx_path_bmp; + hal_data->rf_type = trx_bmp_to_rf_type((trx_path_bmp & 0xF0) >> 4, trx_path_bmp & 0x0F); + hal_data->NumTotalRFPath = rtw_max(tx_path_num, rx_path_num); hal_data->max_tx_cnt = hal_spec->max_tx_cnt; hal_data->max_tx_cnt = rtw_min(hal_data->max_tx_cnt, tx_path_num); @@ -385,9 +373,9 @@ void _dump_trx_nss(void *sel, _adapter *adapter) struct registry_priv *regpriv = &adapter->registrypriv; struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); - RTW_PRINT_SEL(sel, "[TRX_Nss] HALSPEC - tx_nss :%d, rx_nss:%d\n", hal_spec->tx_nss_num, hal_spec->rx_nss_num); - RTW_PRINT_SEL(sel, "[TRX_Nss] Registry - tx_nss :%d, rx_nss:%d\n", regpriv->tx_nss, regpriv->rx_nss); - RTW_PRINT_SEL(sel, "[TRX_Nss] HALDATA - tx_nss :%d, rx_nss:%d\n", GET_HAL_TX_NSS(adapter), GET_HAL_RX_NSS(adapter)); + RTW_PRINT_SEL(sel, "[TRX_Nss] HALSPEC - tx_nss:%d, rx_nss:%d\n", hal_spec->tx_nss_num, hal_spec->rx_nss_num); + RTW_PRINT_SEL(sel, "[TRX_Nss] Registry - tx_nss:%d, rx_nss:%d\n", regpriv->tx_nss, regpriv->rx_nss); + RTW_PRINT_SEL(sel, "[TRX_Nss] HALDATA - tx_nss:%d, rx_nss:%d\n", GET_HAL_TX_NSS(adapter), GET_HAL_RX_NSS(adapter)); } #define NSS_VALID(nss) (nss > 0) @@ -398,6 +386,7 @@ u8 rtw_hal_trxnss_init(_adapter *adapter) struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); PHAL_DATA_TYPE hal_data = GET_HAL_DATA(adapter); enum rf_type rf_path = GET_HAL_RFPATH(adapter); + int i; hal_data->tx_nss = hal_spec->tx_nss_num; hal_data->rx_nss = hal_spec->rx_nss_num; @@ -409,6 +398,23 @@ u8 rtw_hal_trxnss_init(_adapter *adapter) hal_data->rx_nss = rtw_min(hal_data->rx_nss, regpriv->rx_nss); hal_data->rx_nss = rtw_min(hal_data->rx_nss, rf_type_to_rf_rx_cnt(rf_path)); + for (i = 0; i < 4; i++) { + if (hal_data->tx_nss < i + 1) + break; + + if (IS_HARDWARE_TYPE_8814B(adapter) /* 8814B is always full-TX */ + #ifdef CONFIG_RTW_TX_NPATH_EN + /* these IC is capable of full-TX when macro defined */ + || IS_HARDWARE_TYPE_8192E(adapter) || IS_HARDWARE_TYPE_8192F(adapter) + || IS_HARDWARE_TYPE_8812(adapter) || IS_HARDWARE_TYPE_8822B(adapter) + || IS_HARDWARE_TYPE_8822C(adapter) + #endif + ) + hal_data->txpath_cap_num_nss[i] = hal_data->max_tx_cnt; + else + hal_data->txpath_cap_num_nss[i] = i + 1; + } + if (1) _dump_trx_nss(RTW_DBGDUMP, adapter); @@ -527,11 +533,20 @@ uint rtw_hal_iface_init(_adapter *adapter) uint rtw_hal_init(_adapter *padapter) { uint status = _SUCCESS; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); halrf_set_rfsupportability(adapter_to_phydm(padapter)); status = padapter->hal_func.hal_init(padapter); + if(pHalData ->phydm_init_result) { + + status = _FAIL; + RTW_ERR("%s phydm init fail reason=%u \n", + __func__, + pHalData ->phydm_init_result); + } + if (status == _SUCCESS) { rtw_set_hw_init_completed(padapter, _TRUE); if (padapter->registrypriv.notch_filter == 1) @@ -556,6 +571,12 @@ uint rtw_hal_init(_adapter *padapter) #ifdef CONFIG_TDMADIG rtw_phydm_tdmadig(padapter, TDMADIG_INIT); #endif/*CONFIG_TDMADIG*/ + rtw_phydm_dyn_rrsr_en(padapter,padapter->registrypriv.en_dyn_rrsr); + #ifdef RTW_HALMAC + RTW_INFO("%s: padapter->registrypriv.set_rrsr_value=0x%x\n", __func__,padapter->registrypriv.set_rrsr_value); + if(padapter->registrypriv.set_rrsr_value != 0xFFFFFFFF) + rtw_phydm_set_rrsr(padapter, padapter->registrypriv.set_rrsr_value, TRUE); + #endif } else { rtw_set_hw_init_completed(padapter, _FALSE); RTW_ERR("%s: hal_init fail\n", __func__); @@ -567,12 +588,21 @@ uint rtw_hal_init(_adapter *padapter) { uint status = _SUCCESS; struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); int i; halrf_set_rfsupportability(adapter_to_phydm(padapter)); status = padapter->hal_func.hal_init(padapter); + if(pHalData ->phydm_init_result) { + + status = _FAIL; + RTW_ERR("%s phydm init fail reason=%u \n", + __func__, + pHalData->phydm_init_result); + } + if (status == _SUCCESS) { rtw_set_hw_init_completed(padapter, _TRUE); rtw_mi_set_mac_addr(padapter);/*set mac addr of all ifaces*/ @@ -608,6 +638,13 @@ uint rtw_hal_init(_adapter *padapter) rtw_phydm_tdmadig(padapter, TDMADIG_INIT); #endif/*CONFIG_TDMADIG*/ + rtw_phydm_dyn_rrsr_en(padapter,padapter->registrypriv.en_dyn_rrsr); + #ifdef RTW_HALMAC + RTW_INFO("%s: padapter->registrypriv.set_rrsr_value=0x%x\n", __func__,padapter->registrypriv.set_rrsr_value); + if(padapter->registrypriv.set_rrsr_value != 0xFFFFFFFF) + rtw_phydm_set_rrsr(padapter, padapter->registrypriv.set_rrsr_value, TRUE); + #endif + } else { rtw_set_hw_init_completed(padapter, _FALSE); RTW_ERR("%s: fail\n", __func__); @@ -816,6 +853,13 @@ u8 rtw_hal_intf_ps_func(_adapter *padapter, HAL_INTF_PS_FUNC efunc_id, u8 *val) return _FAIL; } +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtw_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + return padapter->hal_func.hal_mgmt_xmitframe_enqueue(padapter, pxmitframe); +} +#endif + s32 rtw_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe) { return padapter->hal_func.hal_xmitframe_enqueue(padapter, pxmitframe); @@ -831,9 +875,16 @@ s32 rtw_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe) */ s32 rtw_hal_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe) { +#ifdef CONFIG_RTW_MGMT_QUEUE + _irqL irqL; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); +#endif s32 ret = _FAIL; update_mgntframe_attrib_addr(padapter, pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + update_mgntframe_subtype(padapter, pmgntframe); +#endif #if defined(CONFIG_IEEE80211W) || defined(CONFIG_RTW_MESH) if ((!MLME_IS_MESH(padapter) && SEC_IS_BIP_KEY_INSTALLED(&padapter->securitypriv) == _TRUE) @@ -844,6 +895,23 @@ s32 rtw_hal_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe) rtw_mgmt_xmitframe_coalesce(padapter, pmgntframe->pkt, pmgntframe); #endif +#ifdef CONFIG_RTW_MGMT_QUEUE + if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) { + _enter_critical_bh(&pxmitpriv->lock, &irqL); + ret = mgmt_xmitframe_enqueue_for_sleeping_sta(padapter, pmgntframe); + _exit_critical_bh(&pxmitpriv->lock, &irqL); + + #ifdef DBG_MGMT_QUEUE + if (ret == _TRUE) + RTW_INFO("%s doesn't be queued, dattrib->ra:"MAC_FMT" seq_num = %u, subtype = 0x%x\n", + __func__, MAC_ARG(pmgntframe->attrib.ra), pmgntframe->attrib.seqnum, pmgntframe->attrib.subtype); + #endif + + if (ret == RTW_QUEUE_MGMT) + return ret; + } +#endif + ret = padapter->hal_func.mgnt_xmit(padapter, pmgntframe); return ret; } @@ -1246,13 +1314,16 @@ s32 c2h_handler(_adapter *adapter, u8 id, u8 seq, u8 plen, u8 *payload) #if defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW) case C2H_FW_CHNL_SWITCH_COMPLETE: +#ifndef CONFIG_TDLS_CH_SW_V2 rtw_tdls_chsw_oper_done(adapter); - break; - case C2H_BCN_EARLY_RPT: - rtw_tdls_ch_sw_back_to_base_chnl(adapter); +#endif break; #endif + case C2H_BCN_EARLY_RPT: + rtw_hal_bcn_early_rpt_c2h_handler(adapter); + break; + #ifdef CONFIG_MCC_MODE case C2H_MCC: rtw_hal_mcc_c2h_handler(adapter, plen, payload); @@ -1290,10 +1361,16 @@ s32 c2h_handler(_adapter *adapter, u8 id, u8 seq, u8 plen, u8 *payload) c2h_lps_status_rpt(adapter, payload, plen); break; #endif +#ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX + case C2H_SET_TXPWR_FINISH: + c2h_txpwr_idx_offload_done(adapter, payload, plen); + break; +#endif case C2H_EXTEND: sub_id = payload[0]; /* no handle, goto default */ /* fall through */ + default: if (phydm_c2H_content_parsing(adapter_to_phydm(adapter), id, plen, payload) != TRUE) ret = _FAIL; @@ -1333,6 +1410,7 @@ s32 rtw_hal_c2h_id_handle_directly(_adapter *adapter, u8 id, u8 seq, u8 plen, u8 case C2H_BCN_EARLY_RPT: case C2H_AP_REQ_TXRPT: case C2H_SPC_STAT: + case C2H_SET_TXPWR_FINISH: return _TRUE; default: return _FALSE; @@ -1658,7 +1736,7 @@ static s32 _rtw_hal_macid_drop(_adapter *adapter, u8 macid, u8 drop) , ADPT_ARG(adapter), drop ? "drop" : "undrop" , macid); goto exit; } - + if(_rtw_macid_ctl_chk_cap(adapter, MACID_DROP)) { if (macid < 32) { #ifndef CONFIG_PROTSEL_MACSLEEP @@ -1738,12 +1816,13 @@ static s32 _rtw_hal_macid_drop(_adapter *adapter, u8 macid, u8 drop) , ADPT_ARG(adapter), drop ? "drop" : "undrop" , macid, reg_drop_info, val32); #endif /* CONFIG_PROTSEL_MACSLEEP */ - + + } else if(_rtw_macid_ctl_chk_cap(adapter, MACID_DROP_INDIRECT)) { u16 start_addr = macid_ctl->macid_txrpt/8; u32 txrpt_h4b = 0; u8 i; - + /* each address means 1 byte */ start_addr += macid*(macid_ctl->macid_txrpt_pgsz/8); /* select tx report buffer */ @@ -1798,7 +1877,6 @@ inline s32 rtw_hal_macid_undrop(_adapter *adapter, u8 macid) return _rtw_hal_macid_drop(adapter, macid, 0); } - s32 rtw_hal_fill_h2c_cmd(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer) { _adapter *pri_adapter = GET_PRIMARY_ADAPTER(padapter); @@ -1868,11 +1946,17 @@ void rtw_hal_fw_correct_bcn(_adapter *padapter) void rtw_hal_set_tx_power_level(_adapter *adapter, u8 channel) { + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + if (phy_chk_ch_setting_consistency(adapter, channel) != _SUCCESS) return; + hal_data->set_entire_txpwr = 1; + adapter->hal_func.set_tx_power_level_handler(adapter, channel); rtw_hal_set_txpwr_done(adapter); + + hal_data->set_entire_txpwr = 0; } void rtw_hal_update_txpwr_level(_adapter *adapter) @@ -1880,6 +1964,7 @@ void rtw_hal_update_txpwr_level(_adapter *adapter) HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); rtw_hal_set_tx_power_level(adapter, hal_data->current_channel); + rtw_rfctl_update_op_mode(adapter_to_rfctl(adapter), 0, 0); } void rtw_hal_set_txpwr_done(_adapter *adapter) diff --git a/hal/hal_mcc.c b/hal/hal_mcc.c index 19b01ce..9043218 100644 --- a/hal/hal_mcc.c +++ b/hal/hal_mcc.c @@ -42,8 +42,9 @@ const int mcc_max_policy_num = sizeof(mcc_switch_channel_policy_table) /sizeof(u static void dump_iqk_val_table(PADAPTER padapter) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); struct hal_iqk_reg_backup *iqk_reg_backup = pHalData->iqk_reg_backup; - u8 total_rf_path = pHalData->NumTotalRFPath; + u8 total_rf_path = hal_spec->rf_reg_path_num; u8 rf_path_idx = 0; u8 backup_chan_idx = 0; u8 backup_reg_idx = 0; @@ -385,7 +386,7 @@ static void mcc_cfg_phdym_rf_ch (_adapter *adapter) set_channel_bwmode(adapter, mlmeext->cur_channel, mlmeext->cur_ch_offset, mlmeext->cur_bwmode); order = mccadapriv->order; - mcc_dm->mcc_rf_ch[order] = phy_query_rf_reg(adapter, RF_PATH_A, 0x18, 0xffffffff); + mcc_dm->mcc_rf_ch[order] = phy_query_rf_reg(adapter, RF_PATH_A, 0x18, 0x03ff); } static void mcc_cfg_phdym_update_macid (_adapter *adapter, u8 add, u8 mac_id) @@ -1270,7 +1271,14 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, struct mlme_ext_info *pmlmeinfo = NULL; struct mlme_ext_priv *pmlmeext = NULL; struct hal_com_data *hal = GET_HAL_DATA(adapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); struct mcc_adapter_priv *mccadapriv = NULL; +#if defined(CONFIG_RTL8822C) + struct dm_struct *phydm = adapter_to_phydm(adapter); + struct txagc_table_8822c tab; + u8 agc_buff[2][NUM_RATE_AC_2SS]; /* tatol 0x40 rate index for PATH A/B */ +#endif + u8 ret = _SUCCESS, i = 0, j =0, order = 0, CurtPktPageNum = 0; u8 *start = NULL; u8 path = RF_PATH_A; @@ -1347,7 +1355,8 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, } for (i = 0; i < MAX_MCC_NUM; i++) { - u8 center_ch = 0, band, ch = 0, bw = 0, bw_offset = 0; + u8 center_ch = 0, ch = 0, bw = 0, bw_offset = 0; + BAND_TYPE band = BAND_MAX; u8 power_index = 0; u8 rate_array_sz = 0; u8 *rates = NULL; @@ -1374,8 +1383,8 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, i, pmccobjpriv->mcc_pwr_idx_rsvd_page[i]); total_rate_offset = start; - - for (path = RF_PATH_A; path < hal->NumTotalRFPath; ++path) { +#if !defined(CONFIG_RTL8822C) + for (path = RF_PATH_A; path < hal_spec->rf_reg_path_num; ++path) { total_rate = 0; /* PATH A for 0~63 byte, PATH B for 64~127 byte*/ if (path == RF_PATH_A) @@ -1393,7 +1402,7 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, rates = rates_by_sections[CCK].rates; for (j = 0; j < rate_array_sz; ++j) { power_index = phy_get_tx_power_index_ex(iface, path, CCK, rates[j], bw, band, center_ch, ch); - rate = PHY_GetRateIndexOfTxPowerByRate(rates[j]); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); shift = rate % 4; if (shift == 0) { @@ -1435,7 +1444,7 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, rates = rates_by_sections[OFDM].rates; for (j = 0; j < rate_array_sz; ++j) { power_index = phy_get_tx_power_index_ex(iface, path, OFDM, rates[j], bw, band, center_ch, ch); - rate = PHY_GetRateIndexOfTxPowerByRate(rates[j]); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); shift = rate % 4; if (shift == 0) { @@ -1475,7 +1484,7 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, rates = rates_by_sections[HT_MCS0_MCS7].rates; for (j = 0; j < rate_array_sz; ++j) { power_index = phy_get_tx_power_index_ex(iface, path, HT_1SS, rates[j], bw, band, center_ch, ch); - rate = PHY_GetRateIndexOfTxPowerByRate(rates[j]); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); shift = rate % 4; if (shift == 0) { @@ -1515,7 +1524,7 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, rates = rates_by_sections[HT_MCS8_MCS15].rates; for (j = 0; j < rate_array_sz; ++j) { power_index = phy_get_tx_power_index_ex(iface, path, HT_2SS, rates[j], bw, band, center_ch, ch); - rate = PHY_GetRateIndexOfTxPowerByRate(rates[j]); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); shift = rate % 4; if (shift == 0) { @@ -1554,7 +1563,7 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, rates = rates_by_sections[VHT_1SSMCS0_1SSMCS9].rates; for (j = 0; j < rate_array_sz; ++j) { power_index = phy_get_tx_power_index_ex(iface, path, VHT_1SS, rates[j], bw, band, center_ch, ch); - rate = PHY_GetRateIndexOfTxPowerByRate(rates[j]); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); shift = rate % 4; if (shift == 0) { @@ -1590,7 +1599,7 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, rates = rates_by_sections[VHT_2SSMCS0_2SSMCS9].rates; for (j = 0; j < rate_array_sz; ++j) { power_index = phy_get_tx_power_index_ex(iface, path, VHT_2SS, rates[j], bw, band, center_ch, ch); - rate = PHY_GetRateIndexOfTxPowerByRate(rates[j]); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); shift = rate % 4; if (shift == 0) { @@ -1636,6 +1645,91 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, *total_page_num += CurtPktPageNum; *index += (CurtPktPageNum * page_size); RSVD_PAGE_CFG("mcc_pwr_idx_rsvd_page", CurtPktPageNum, *total_page_num, *index); +#else /* 8822C */ + for (path = RF_PATH_A; path < hal_spec->rf_reg_path_num; ++path) { + /* CCK */ + if (ch <= 14) { + rate_array_sz = rates_by_sections[CCK].rate_num; + rates = rates_by_sections[CCK].rates; + for (j = 0; j < rate_array_sz; ++j) { + power_index = phy_get_tx_power_index_ex(iface, path, CCK, rates[j], bw, band, center_ch, ch); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); + agc_buff[path][rate] = power_index; + } + } + + /* OFDM */ + rate_array_sz = rates_by_sections[OFDM].rate_num; + rates = rates_by_sections[OFDM].rates; + for (j = 0; j < rate_array_sz; ++j) { + power_index = phy_get_tx_power_index_ex(iface, path, OFDM, rates[j], bw, band, center_ch, ch); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); + agc_buff[path][rate] = power_index; + } + /* HT */ + rate_array_sz = rates_by_sections[HT_MCS0_MCS7].rate_num; + rates = rates_by_sections[HT_MCS0_MCS7].rates; + for (j = 0; j < rate_array_sz; ++j) { + power_index = phy_get_tx_power_index_ex(iface, path, HT_1SS, rates[j], bw, band, center_ch, ch); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); + agc_buff[path][rate] = power_index; + } + + rate_array_sz = rates_by_sections[HT_MCS8_MCS15].rate_num; + rates = rates_by_sections[HT_MCS8_MCS15].rates; + for (j = 0; j < rate_array_sz; ++j) { + power_index = phy_get_tx_power_index_ex(iface, path, HT_2SS, rates[j], bw, band, center_ch, ch); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); + agc_buff[path][rate] = power_index; + } + /* VHT */ + rate_array_sz = rates_by_sections[VHT_1SSMCS0_1SSMCS9].rate_num; + rates = rates_by_sections[VHT_1SSMCS0_1SSMCS9].rates; + for (j = 0; j < rate_array_sz; ++j) { + power_index = phy_get_tx_power_index_ex(iface, path, VHT_1SS, rates[j], bw, band, center_ch, ch); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); + agc_buff[path][rate] = power_index; + } + + rate_array_sz = rates_by_sections[VHT_2SSMCS0_2SSMCS9].rate_num; + rates = rates_by_sections[VHT_2SSMCS0_2SSMCS9].rates; + for (j = 0; j < rate_array_sz; ++j) { + power_index = phy_get_tx_power_index_ex(iface, path, VHT_2SS, rates[j], bw, band, center_ch, ch); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); + agc_buff[path][rate] = power_index; + } + } + phydm_get_txagc_ref_and_diff_8822c(phydm, agc_buff, NUM_RATE_AC_2SS, &tab); + *start = tab.ref_pow_cck[0]; + start++; + *start = tab.ref_pow_cck[1]; + start++; + *start = tab.ref_pow_ofdm[0]; + start++; + *start = tab.ref_pow_ofdm[1]; + start++; + _rtw_memcpy(start, tab.diff_t, sizeof(tab.diff_t)); + CurtPktPageNum = 1; + *total_page_num += CurtPktPageNum; + *index += (CurtPktPageNum * page_size); + RSVD_PAGE_CFG("mcc_pwr_idx_rsvd_page", CurtPktPageNum, *total_page_num, *index); + #ifdef DBG_PWR_IDX_RSVD_PAGE + if (1) { + u8 path_idx; + for (path_idx = 0; path_idx < 2; path_idx++) { + for (j = 0; j < NUM_RATE_AC_2SS; j++) + RTW_INFO("agc_buff[%d][%d]=%x\n", i, j, agc_buff[i][j]); + } + RTW_INFO("tab->ref_pow_cck[0]=%x\n", tab.ref_pow_cck[0]); + RTW_INFO("tab->ref_pow_cck[1]=%x\n", tab.ref_pow_cck[1]); + RTW_INFO("tab->ref_pow_ofdm[0]=%x\n", tab.ref_pow_ofdm[0]); + RTW_INFO("tab->ref_pow_ofdm[1]=%x\n", tab.ref_pow_ofdm[1]); + RTW_INFO_DUMP("diff_t ", tab.diff_t, NUM_RATE_AC_2SS); + RTW_INFO_DUMP("tab ", (u8 *)&tab, sizeof(tab)); + } + #endif + +#endif } exit: @@ -1660,6 +1754,7 @@ static void rtw_hal_set_fw_mcc_rsvd_page(PADAPTER padapter) rtw_hal_set_hwreg(port0_iface, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus)); +#ifdef CONFIG_AP_MODE /* Re-Download beacon */ for (i = 0; i < MAX_MCC_NUM; i++) { iface = pmccobjpriv->iface[i]; @@ -1673,18 +1768,19 @@ static void rtw_hal_set_fw_mcc_rsvd_page(PADAPTER padapter) tx_beacon_hdl(iface, NULL); } } +#endif } static void rtw_hal_set_mcc_rsvdpage_cmd(_adapter *padapter) { u8 cmd[H2C_MCC_LOCATION_LEN] = {0}, i = 0, order = 0; _adapter *iface = NULL; - PHAL_DATA_TYPE hal = GET_HAL_DATA(padapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); struct mcc_obj_priv *pmccobjpriv = &(dvobj->mcc_objpriv); SET_H2CCMD_MCC_PWRIDX_OFFLOAD_EN(cmd, _TRUE); - SET_H2CCMD_MCC_PWRIDX_OFFLOAD_RFNUM(cmd, hal->NumTotalRFPath); + SET_H2CCMD_MCC_PWRIDX_OFFLOAD_RFNUM(cmd, hal_spec->rf_reg_path_num); for (order = 0; order < MAX_MCC_NUM; order++) { iface = pmccobjpriv->iface[i]; @@ -1787,7 +1883,7 @@ static void rtw_hal_set_mcc_IQK_offload_cmd(PADAPTER padapter) _adapter *iface = NULL; u8 cmd[H2C_MCC_IQK_PARAM_LEN] = {0}, bready = 0, i = 0, order = 0; u16 TX_X = 0, TX_Y = 0, RX_X = 0, RX_Y = 0; - u8 total_rf_path = GET_HAL_DATA(padapter)->NumTotalRFPath; + u8 total_rf_path = GET_HAL_SPEC(padapter)->rf_reg_path_num; u8 rf_path_idx = 0, last_order = MAX_MCC_NUM - 1, last_rf_path_index = total_rf_path - 1; /* by order, last order & last_rf_path_index must set ready bit = 1 */ @@ -2214,6 +2310,15 @@ static void rtw_hal_mcc_start_prehdl(PADAPTER padapter) mccadapriv = &iface->mcc_adapterpriv; mccadapriv->role = MCC_ROLE_MAX; } + +#ifdef CONFIG_RTL8822C + if (IS_HARDWARE_TYPE_8822C(padapter)) { + HAL_DATA_TYPE *hal = GET_HAL_DATA(padapter); + struct dm_struct *dm = &hal->odmpriv; + + odm_cmn_info_update(dm, ODM_CMNINFO_IS_DOWNLOAD_FW, hal->bFWReady); + } +#endif } static u8 rtw_hal_set_mcc_start_setting(PADAPTER padapter, u8 status) @@ -2379,6 +2484,15 @@ static void rtw_hal_mcc_stop_posthdl(PADAPTER padapter) #ifdef CONFIG_MCC_PHYDM_OFFLOAD rtw_hal_mcc_cfg_phydm(padapter, MCC_CFG_PHYDM_STOP, NULL); #endif + +#ifdef CONFIG_RTL8822C + if (IS_HARDWARE_TYPE_8822C(padapter)) { + HAL_DATA_TYPE *hal = GET_HAL_DATA(padapter); + struct dm_struct *dm = &hal->odmpriv; + + odm_cmn_info_update(dm, ODM_CMNINFO_IS_DOWNLOAD_FW, _FALSE); + } +#endif } static void rtw_hal_mcc_start_posthdl(PADAPTER padapter) @@ -2430,7 +2544,7 @@ static u8 rtw_hal_set_mcc_setting(PADAPTER padapter, u8 status) u8 ret = _FAIL; struct mcc_obj_priv *pmccobjpriv = &(adapter_to_dvobj(padapter)->mcc_objpriv); u8 stop = (status < MCC_SETCMD_STATUS_START_CONNECT) ? _TRUE : _FALSE; - u32 start_time = rtw_get_current_time(); + systime start_time = rtw_get_current_time(); RTW_INFO("===> "FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); @@ -2644,14 +2758,17 @@ static void rtw_hal_mcc_update_noa_start_time_hdl(PADAPTER padapter, u8 buflen, static u8 mcc_get_reg_hdl(PADAPTER adapter, const u8 *val) { + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct mcc_obj_priv *mccobjpriv = &(dvobj->mcc_objpriv); - struct hal_com_data *hal = GET_HAL_DATA(adapter); _adapter *cur_iface = NULL; u8 ret = _SUCCESS; u8 cur_order = 0; - + #ifdef CONFIG_RTL8822C + u16 dbg_reg[DBG_MCC_REG_NUM] = {0x4d4,0x522,0x1d70}; + #else u16 dbg_reg[DBG_MCC_REG_NUM] = {0x4d4,0x522,0xc50,0xe50}; + #endif u16 dbg_rf_reg[DBG_MCC_RF_REG_NUM] = {0x18}; u8 i; u32 reg_val; @@ -2673,7 +2790,7 @@ static u8 mcc_get_reg_hdl(PADAPTER adapter, const u8 *val) goto exit; } - path_nums = hal->NumTotalRFPath; + path_nums = hal_spec->rf_reg_path_num; if (cur_order == 0xff) cur_iface = adapter; else @@ -2749,7 +2866,7 @@ static u8 mcc_get_reg_cmd(_adapter *adapter, u8 cur_order) _rtw_memcpy(mcc_cur_order, &cur_order, 1); - init_h2fwcmd_w_parm_no_rsp(cmdobj, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, cmdobj); exit: @@ -3284,14 +3401,34 @@ u8 rtw_hal_set_mcc_setting_start_bss_network(PADAPTER padapter, u8 chbw_allow) if (MCC_EN(padapter)) { /* channel bw offset can not be allowed, start MCC */ if (chbw_allow == _FALSE) { - struct mcc_obj_priv *pmccobjpriv = &(adapter_to_dvobj(padapter)->mcc_objpriv); + struct mcc_obj_priv *pmccobjpriv = &(adapter_to_dvobj(padapter)->mcc_objpriv); - rtw_hal_mcc_restore_iqk_val(padapter); - _enter_critical_mutex(&pmccobjpriv->mcc_mutex, NULL); - ret = rtw_hal_set_mcc_setting(padapter, MCC_SETCMD_STATUS_START_CONNECT); - _exit_critical_mutex(&pmccobjpriv->mcc_mutex, NULL); + //rtw_hal_mcc_restore_iqk_val(padapter); + _enter_critical_mutex(&pmccobjpriv->mcc_mutex, NULL); + ret = rtw_hal_set_mcc_setting(padapter, MCC_SETCMD_STATUS_START_CONNECT); + _exit_critical_mutex(&pmccobjpriv->mcc_mutex, NULL); + + if (ret == _FAIL) { /* MCC Start fail, AP/GO switch to buddy's channel */ + u8 ch_to_set = 0, bw_to_set, offset_to_set; + + rtw_hal_set_mcc_status(padapter, MCC_STATUS_NEED_MCC | MCC_STATUS_DOING_MCC); + rtw_hal_set_mcc_setting_disconnect(padapter); + if (rtw_mi_get_ch_setting_union_no_self( + padapter, &ch_to_set, &bw_to_set, + &offset_to_set) != 0) { + PHAL_DATA_TYPE hal = GET_HAL_DATA(padapter); + u8 doiqk = _TRUE; + + rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk); + hal->current_channel = 0; + hal->current_channel_bw = CHANNEL_WIDTH_MAX; + set_channel_bwmode(padapter, ch_to_set, offset_to_set, bw_to_set); + doiqk = _FALSE; + rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk); + } } } + } return ret; } @@ -3361,9 +3498,17 @@ u8 rtw_hal_set_mcc_setting_join_done_chk_ch(PADAPTER padapter) _enter_critical_mutex(&pmccobjpriv->mcc_mutex, NULL); ret = rtw_hal_set_mcc_setting(padapter, MCC_SETCMD_STATUS_START_CONNECT); _exit_critical_mutex(&pmccobjpriv->mcc_mutex, NULL); + + if (ret == _FAIL) { /* MCC Start Fail, then disconenct client join */ + rtw_hal_set_mcc_status(padapter, MCC_STATUS_NEED_MCC | MCC_STATUS_DOING_MCC); + rtw_disassoc_cmd(padapter, 0, RTW_CMDF_DIRECTLY); + rtw_indicate_disconnect(padapter, 0, _FALSE); + rtw_free_assoc_resources(padapter, _TRUE); + rtw_free_network_queue(padapter, _TRUE); + } + } } } - } return ret; } @@ -3423,7 +3568,7 @@ static void rtw_hal_mcc_dump_noa_content(void *sel, PADAPTER padapter) static void mcc_dump_dbg_reg(void *sel, _adapter *adapter) { struct mcc_obj_priv *mccobjpriv = adapter_to_mccobjpriv(adapter); - HAL_DATA_TYPE *hal = GET_HAL_DATA(adapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); u8 i,j; _irqL irqL; @@ -3436,7 +3581,7 @@ static void mcc_dump_dbg_reg(void *sel, _adapter *adapter) RTW_PRINT_SEL(sel, "REG_0x%X:0x%08x\n", mccobjpriv->dbg_reg[i], mccobjpriv->dbg_reg_val[i]); for (i = 0; i < ARRAY_SIZE(mccobjpriv->dbg_rf_reg); i++) { - for (j = 0; j < hal->NumTotalRFPath; j++) + for (j = 0; j < hal_spec->rf_reg_path_num; j++) RTW_PRINT_SEL(sel, "RF_PATH_%d_REG_0x%X:0x%08x\n", j, mccobjpriv->dbg_rf_reg[i], mccobjpriv->dbg_rf_reg_val[i][j]); } @@ -3826,7 +3971,7 @@ u8 rtw_set_mcc_duration_cmd(_adapter *adapter, u8 type, u8 val) _rtw_memcpy(buf, &type, 1); _rtw_memcpy(buf + 1, &val, 1); - init_h2fwcmd_w_parm_no_rsp(cmdobj, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, cmdobj); exit: @@ -3892,7 +4037,7 @@ u8 rtw_set_mcc_phydm_offload_enable_cmd(_adapter *adapter, u8 enable, u8 enqueue pdrvextra_cmd_parm->pbuf = mcc_phydm_offload_enable; _rtw_memcpy(mcc_phydm_offload_enable, &enable, 1); - init_h2fwcmd_w_parm_no_rsp(cmdobj, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + init_h2fwcmd_w_parm_no_rsp(cmdobj, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); res = rtw_enqueue_cmd(pcmdpriv, cmdobj); } else { mcc_phydm_offload_enable_hdl(adapter, &enable); diff --git a/hal/hal_mp.c b/hal/hal_mp.c index 6ee5e75..9817e53 100644 --- a/hal/hal_mp.c +++ b/hal/hal_mp.c @@ -180,7 +180,7 @@ void hal_mpt_CCKTxPowerAdjust(PADAPTER Adapter, BOOLEAN bInCH14) } else if (IS_HARDWARE_TYPE_8723D(Adapter)) { /* 2.4G CCK TX DFIR */ /* 2016.01.20 Suggest from RS BB mingzhi*/ - if (u1Channel == 14) { + if ((u1Channel == 14)) { phy_set_bb_reg(Adapter, rCCK0_TxFilter2, bMaskDWord, 0x0000B81C); phy_set_bb_reg(Adapter, rCCK0_DebugPort, bMaskDWord, 0x00000000); phy_set_bb_reg(Adapter, 0xAAC, bMaskDWord, 0x00003667); @@ -434,12 +434,16 @@ mpt_SetTxPower( u8 path = 0 , i = 0, MaxRate = MGN_6M; u8 StartPath = RF_PATH_A, EndPath = RF_PATH_B; + u8 tx_nss = 2; - if (IS_HARDWARE_TYPE_8814A(pAdapter) || IS_HARDWARE_TYPE_8814B(pAdapter)) + if (IS_HARDWARE_TYPE_8814A(pAdapter) || IS_HARDWARE_TYPE_8814B(pAdapter)) { EndPath = RF_PATH_D; - else if (IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8188GTV(pAdapter) - || IS_HARDWARE_TYPE_8723D(pAdapter) || IS_HARDWARE_TYPE_8821C(pAdapter)) + tx_nss = 4; + } else if (IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8188GTV(pAdapter) + || IS_HARDWARE_TYPE_8723D(pAdapter) || IS_HARDWARE_TYPE_8821C(pAdapter) || IS_HARDWARE_TYPE_8723F(pAdapter)) { EndPath = RF_PATH_A; + tx_nss = 1; + } switch (Rate) { case MPT_CCK: { @@ -471,12 +475,15 @@ mpt_SetTxPower( MGN_MCS25, MGN_MCS26, MGN_MCS27, MGN_MCS28, MGN_MCS29, MGN_MCS30, MGN_MCS31, }; - if (pHalData->rf_type == RF_3T3R) + if (tx_nss == 4) + MaxRate = MGN_MCS31; + else if (tx_nss == 3) MaxRate = MGN_MCS23; - else if (pHalData->rf_type == RF_2T2R) + else if (tx_nss == 2) MaxRate = MGN_MCS15; else MaxRate = MGN_MCS7; + for (path = StartPath; path <= EndPath; path++) { for (i = 0; i < sizeof(rate); ++i) { if (rate[i] > MaxRate) @@ -497,9 +504,11 @@ mpt_SetTxPower( MGN_VHT4SS_MCS0, MGN_VHT4SS_MCS1, MGN_VHT4SS_MCS2, MGN_VHT4SS_MCS3, MGN_VHT4SS_MCS4, MGN_VHT4SS_MCS5, MGN_VHT4SS_MCS6, MGN_VHT4SS_MCS7, MGN_VHT4SS_MCS8, MGN_VHT4SS_MCS9, }; - if (pHalData->rf_type == RF_3T3R) + if (tx_nss == 4) + MaxRate = MGN_VHT4SS_MCS9; + else if (tx_nss == 3) MaxRate = MGN_VHT3SS_MCS9; - else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R) + else if (tx_nss == 2) MaxRate = MGN_VHT2SS_MCS9; else MaxRate = MGN_VHT1SS_MCS9; @@ -856,7 +865,8 @@ void mpt_SetRFPath_8814A(PADAPTER pAdapter) } #endif /* CONFIG_RTL8814A */ -#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) +#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) \ + || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) || defined(CONFIG_RTL8723F) void mpt_SetSingleTone_8814A( PADAPTER pAdapter, @@ -952,7 +962,7 @@ mpt_SetSingleTone_8814A( phy_set_bb_reg(pAdapter, rCCAonSec_Jaguar, BIT1, 0x0); /* Enable CCA*/ if (bEnPMacTx == FALSE) { - if(IS_HARDWARE_TYPE_JAGUAR3(pAdapter)) { + if (IS_HARDWARE_TYPE_JAGUAR3(pAdapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter)) { #ifdef PHYDM_MP_SUPPORT phydm_stop_ofdm_cont_tx(pAdapter); pMptCtx->bCckContTx = FALSE; @@ -1506,9 +1516,68 @@ void mpt_set_rfpath_8192f(PADAPTER pAdapter) #endif void hal_mpt_SetAntenna(PADAPTER pAdapter) - { - RTW_INFO("Do %s\n", __func__); + PHAL_DATA_TYPE hal; + ANTENNA_PATH anttx; + enum bb_path bb_tx = 0; + + + hal = GET_HAL_DATA(pAdapter); + anttx = hal->antenna_tx_path; + + switch (anttx) { + case ANTENNA_A: + bb_tx = BB_PATH_A; + break; + case ANTENNA_B: + bb_tx = BB_PATH_B; + break; + case ANTENNA_C: + bb_tx = BB_PATH_C; + break; + case ANTENNA_D: + bb_tx = BB_PATH_D; + break; + case ANTENNA_AB: + bb_tx = BB_PATH_AB; + break; + case ANTENNA_AC: + bb_tx = BB_PATH_AC; + break; + case ANTENNA_AD: + bb_tx = BB_PATH_AD; + break; + case ANTENNA_BC: + bb_tx = BB_PATH_BC; + break; + case ANTENNA_BD: + bb_tx = BB_PATH_BD; + break; + case ANTENNA_CD: + bb_tx = BB_PATH_CD; + break; + case ANTENNA_ABC: + bb_tx = BB_PATH_ABC; + break; + case ANTENNA_BCD: + bb_tx = BB_PATH_BCD; + break; + case ANTENNA_ABD: + bb_tx = BB_PATH_ABD; + break; + case ANTENNA_ACD: + bb_tx = BB_PATH_ACD; + break; + case ANTENNA_ABCD: + bb_tx = BB_PATH_ABCD; + break; + default: + bb_tx = BB_PATH_A; + break; + } + tx_path_nss_set_full_tx(hal->txpath_nss, hal->txpath_num_nss, bb_tx); + RTW_INFO("%s ,ant idx %d, tx path_num_nss = %d\n", __func__, anttx, hal->txpath_num_nss[0]); + #ifdef CONFIG_RTL8822C if (IS_HARDWARE_TYPE_8822C(pAdapter)) { rtl8822c_mp_config_rfpath(pAdapter); @@ -1607,7 +1676,7 @@ s32 hal_mpt_SetThermalMeter(PADAPTER pAdapter, u8 target_ther) void hal_mpt_TriggerRFThermalMeter(PADAPTER pAdapter) { - if (IS_HARDWARE_TYPE_JAGUAR3(pAdapter)) { + if (IS_HARDWARE_TYPE_JAGUAR3(pAdapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter)) { phy_set_rf_reg(pAdapter, RF_PATH_A, 0x42, BIT19, 0x1); phy_set_rf_reg(pAdapter, RF_PATH_A, 0x42, BIT19, 0x0); phy_set_rf_reg(pAdapter, RF_PATH_A, 0x42, BIT19, 0x1); @@ -1684,8 +1753,9 @@ void hal_mpt_SetSingleCarrierTx(PADAPTER pAdapter, u8 bStart) phy_set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, 1); /*/ 4. Turn On Continue Tx and turn off the other test modes.*/ -#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) - if (IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter)) +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A)\ + || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8723F) + if (IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter)) phy_set_bb_reg(pAdapter, rSingleTone_ContTx_Jaguar, BIT18 | BIT17 | BIT16, OFDM_SingleCarrier); else #endif /* CONFIG_RTL8812A || CONFIG_RTL8821A || CONFIG_RTL8814A || CONFIG_RTL8822B || CONFIG_RTL8821C */ @@ -1695,8 +1765,9 @@ void hal_mpt_SetSingleCarrierTx(PADAPTER pAdapter, u8 bStart) /*/ Stop Single Carrier.*/ /*/ Stop Single Carrier.*/ /*/ Turn off all test modes.*/ -#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) - if (IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter)) +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)\ + || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8723F) + if (IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter)|| IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter)) phy_set_bb_reg(pAdapter, rSingleTone_ContTx_Jaguar, BIT18 | BIT17 | BIT16, OFDM_ALL_OFF); else #endif /* CONFIG_RTL8812A || CONFIG_RTL8821A || CONFIG_RTL8814A || CONFIG_RTL8822B || CONFIG_RTL8821C */ @@ -1719,7 +1790,7 @@ void hal_mpt_SetSingleToneTx(PADAPTER pAdapter, u8 bStart) static u32 regRF = 0, regBB0 = 0, regBB1 = 0, regBB2 = 0, regBB3 = 0; u8 rfPath; - if (IS_HARDWARE_TYPE_JAGUAR3(pAdapter)) { + if (IS_HARDWARE_TYPE_JAGUAR3(pAdapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter)) { #ifdef PHYDM_MP_SUPPORT #ifdef CONFIG_RTL8814B if(pHalData->current_channel_bw == CHANNEL_WIDTH_80_80) @@ -1989,7 +2060,7 @@ void hal_mpt_SetCarrierSuppressionTx(PADAPTER pAdapter, u8 bStart) pAdapter->mppriv.mpt_ctx.is_carrier_suppression = bStart; - if (IS_HARDWARE_TYPE_JAGUAR3(pAdapter)) { + if (IS_HARDWARE_TYPE_JAGUAR3(pAdapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter)) { #ifdef PHYDM_MP_SUPPORT phydm_mp_set_carrier_supp(pdm_odm, bStart, pAdapter->mppriv.rateidx); #endif @@ -2004,7 +2075,7 @@ void hal_mpt_SetCarrierSuppressionTx(PADAPTER pAdapter, u8 bStart) write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable);/*set CCK block on*/ /*/Turn Off All Test Mode*/ - if (IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter)) + if (IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter)) phy_set_bb_reg(pAdapter, 0x914, BIT18 | BIT17 | BIT16, OFDM_ALL_OFF); /* rSingleTone_ContTx_Jaguar*/ else phy_set_bb_reg(pAdapter, rOFDM1_LSTF, BIT30 | BIT29 | BIT28, OFDM_ALL_OFF); @@ -2048,7 +2119,7 @@ u32 hal_mpt_query_phytxok(PADAPTER pAdapter) struct dm_struct *dm = (struct dm_struct *)&pHalData->odmpriv; struct phydm_mp *mp = &dm->dm_mp_table; - if (IS_HARDWARE_TYPE_JAGUAR3(pAdapter)) { + if (IS_HARDWARE_TYPE_JAGUAR3(pAdapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter)) { phydm_mp_get_tx_ok(&pHalData->odmpriv, pAdapter->mppriv.rateidx); count = mp->tx_phy_ok_cnt; @@ -2086,7 +2157,7 @@ static void mpt_StopCckContTx( phy_set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); /*normal mode*/ phy_set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, 0x1); /*turn on scramble setting*/ - if (!IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter)) { + if (!IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter) && !IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter)) { phy_set_bb_reg(pAdapter, 0xa14, 0x300, 0x0); /* 0xa15[1:0] = 2b00*/ phy_set_bb_reg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x0); /* 0xc08[16] = 0*/ @@ -2099,9 +2170,11 @@ static void mpt_StopCckContTx( phy_set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); phy_set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); - if (!IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter)) { - phy_set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); - phy_set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); + if (!IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter) && !IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter) + && !IS_HARDWARE_TYPE_8723D(pAdapter) && !IS_HARDWARE_TYPE_8192F(pAdapter) + && !IS_HARDWARE_TYPE_8188F(pAdapter)) { + phy_set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); + phy_set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); } if (IS_HARDWARE_TYPE_8188E(pAdapter) || IS_HARDWARE_TYPE_8723B(pAdapter) || @@ -2126,14 +2199,14 @@ static void mpt_StopOfdmContTx( pMptCtx->bCckContTx = FALSE; pMptCtx->bOfdmContTx = FALSE; - if (IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter)) + if (IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter)) phy_set_bb_reg(pAdapter, 0x914, BIT18 | BIT17 | BIT16, OFDM_ALL_OFF); else phy_set_bb_reg(pAdapter, rOFDM1_LSTF, BIT30 | BIT29 | BIT28, OFDM_ALL_OFF); rtw_mdelay_os(10); - if (!IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter)){ + if (!IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter) && !IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter)){ phy_set_bb_reg(pAdapter, 0xa14, 0x300, 0x0); /* 0xa15[1:0] = 0*/ phy_set_bb_reg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x0); /* 0xc08[16] = 0*/ } @@ -2142,9 +2215,11 @@ static void mpt_StopOfdmContTx( phy_set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); phy_set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); - if (!IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter)) { - phy_set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); - phy_set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); + if (!IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter) && !IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter) + && !IS_HARDWARE_TYPE_8723D(pAdapter) && !IS_HARDWARE_TYPE_8192F(pAdapter) + && !IS_HARDWARE_TYPE_8188F(pAdapter)) { + phy_set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); + phy_set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); } } /* mpt_StopOfdmContTx */ @@ -2162,7 +2237,7 @@ static void mpt_StartCckContTx( phy_set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, 1);/*set CCK block on*/ /*Turn Off All Test Mode*/ - if (IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter)) + if (IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter)) phy_set_bb_reg(pAdapter, 0x914, BIT18 | BIT17 | BIT16, OFDM_ALL_OFF); else phy_set_bb_reg(pAdapter, rOFDM1_LSTF, BIT30 | BIT29 | BIT28, OFDM_ALL_OFF); @@ -2174,7 +2249,7 @@ static void mpt_StartCckContTx( phy_set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); /*transmit mode*/ phy_set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, 0x1); /*turn on scramble setting*/ - if (!IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter)) { + if (!IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter) && !IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter)) { phy_set_bb_reg(pAdapter, 0xa14, 0x300, 0x3); /* 0xa15[1:0] = 11 force cck rxiq = 0*/ phy_set_bb_reg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x1); /* 0xc08[16] = 1 force ofdm rxiq = ofdm txiq*/ phy_set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, BIT14, 1); @@ -2182,7 +2257,9 @@ static void mpt_StartCckContTx( phy_set_bb_reg(pAdapter, 0x0B34, BIT14, 1); } - if (!IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter)) { + if (!IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter) && !IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter) + && !IS_HARDWARE_TYPE_8723D(pAdapter) && !IS_HARDWARE_TYPE_8192F(pAdapter) + && !IS_HARDWARE_TYPE_8188F(pAdapter)) { phy_set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); phy_set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); } @@ -2220,18 +2297,20 @@ static void mpt_StartOfdmContTx( /* 3. turn on scramble setting*/ phy_set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, 1); - if (!IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter)) { + if (!IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter) && !IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter)) { phy_set_bb_reg(pAdapter, 0xa14, 0x300, 0x3); /* 0xa15[1:0] = 2b'11*/ phy_set_bb_reg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x1); /* 0xc08[16] = 1*/ } /* 4. Turn On Continue Tx and turn off the other test modes.*/ - if (IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter)) + if (IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter)) phy_set_bb_reg(pAdapter, 0x914, BIT18 | BIT17 | BIT16, OFDM_ContinuousTx); else phy_set_bb_reg(pAdapter, rOFDM1_LSTF, BIT30 | BIT29 | BIT28, OFDM_ContinuousTx); - if (!IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter)) { + if (!IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter) && !IS_HARDWARE_TYPE_JAGUAR3_11N(pAdapter) + && !IS_HARDWARE_TYPE_8723D(pAdapter) && !IS_HARDWARE_TYPE_8192F(pAdapter) + && !IS_HARDWARE_TYPE_8188F(pAdapter)) { phy_set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); phy_set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); } @@ -2240,45 +2319,49 @@ static void mpt_StartOfdmContTx( pMptCtx->bOfdmContTx = TRUE; } /* mpt_StartOfdmContTx */ -#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8821B) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) +#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8821B) || defined(CONFIG_RTL8822B) \ + || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) \ + || defined(CONFIG_RTL8723F) #ifdef PHYDM_PMAC_TX_SETTING_SUPPORT static void mpt_convert_phydm_txinfo_for_jaguar3( - RT_PMAC_TX_INFO pMacTxInfo, struct phydm_pmac_info *phydmtxinfo) + RT_PMAC_TX_INFO *pMacTxInfo, struct phydm_pmac_info *phydmtxinfo) { - phydmtxinfo->en_pmac_tx = pMacTxInfo.bEnPMacTx; - phydmtxinfo->mode = pMacTxInfo.Mode; - phydmtxinfo->tx_rate = MRateToHwRate(mpt_to_mgnt_rate(pMacTxInfo.TX_RATE)); - phydmtxinfo->tx_sc = pMacTxInfo.TX_SC; - phydmtxinfo->is_short_preamble = pMacTxInfo.bSPreamble; - phydmtxinfo->ndp_sound = pMacTxInfo.NDP_sound; - phydmtxinfo->bw = pMacTxInfo.BandWidth; - phydmtxinfo->m_stbc = pMacTxInfo.m_STBC; - phydmtxinfo->packet_period = pMacTxInfo.PacketPeriod; - phydmtxinfo->packet_count = pMacTxInfo.PacketCount; - phydmtxinfo->packet_pattern = pMacTxInfo.PacketPattern; - phydmtxinfo->sfd = pMacTxInfo.SFD; - phydmtxinfo->signal_field = pMacTxInfo.SignalField; - phydmtxinfo->service_field = pMacTxInfo.ServiceField; - phydmtxinfo->length = pMacTxInfo.LENGTH; - _rtw_memcpy(&phydmtxinfo->crc16,pMacTxInfo.CRC16, 2); - _rtw_memcpy(&phydmtxinfo->lsig , pMacTxInfo.LSIG,3); - _rtw_memcpy(&phydmtxinfo->ht_sig , pMacTxInfo.HT_SIG,6); - _rtw_memcpy(&phydmtxinfo->vht_sig_a , pMacTxInfo.VHT_SIG_A,6); - _rtw_memcpy(&phydmtxinfo->vht_sig_b , pMacTxInfo.VHT_SIG_B,4); - phydmtxinfo->vht_sig_b_crc = pMacTxInfo.VHT_SIG_B_CRC; - _rtw_memcpy(&phydmtxinfo->vht_delimiter,pMacTxInfo.VHT_Delimiter,4); + phydmtxinfo->en_pmac_tx = pMacTxInfo->bEnPMacTx; + phydmtxinfo->mode = pMacTxInfo->Mode; + phydmtxinfo->tx_rate = MRateToHwRate(mpt_to_mgnt_rate(pMacTxInfo->TX_RATE)); + phydmtxinfo->tx_sc = pMacTxInfo->TX_SC; + phydmtxinfo->is_short_preamble = pMacTxInfo->bSPreamble; + phydmtxinfo->ndp_sound = pMacTxInfo->NDP_sound; + phydmtxinfo->bw = pMacTxInfo->BandWidth; + phydmtxinfo->m_stbc = pMacTxInfo->m_STBC; + phydmtxinfo->packet_period = pMacTxInfo->PacketPeriod; + phydmtxinfo->packet_count = pMacTxInfo->PacketCount; + phydmtxinfo->packet_pattern = pMacTxInfo->PacketPattern; + phydmtxinfo->sfd = pMacTxInfo->SFD; + phydmtxinfo->signal_field = pMacTxInfo->SignalField; + phydmtxinfo->service_field = pMacTxInfo->ServiceField; + phydmtxinfo->length = pMacTxInfo->LENGTH; + _rtw_memcpy(&phydmtxinfo->crc16,pMacTxInfo->CRC16, 2); + _rtw_memcpy(&phydmtxinfo->lsig , pMacTxInfo->LSIG,3); + _rtw_memcpy(&phydmtxinfo->ht_sig , pMacTxInfo->HT_SIG,6); + _rtw_memcpy(&phydmtxinfo->vht_sig_a , pMacTxInfo->VHT_SIG_A,6); + _rtw_memcpy(&phydmtxinfo->vht_sig_b , pMacTxInfo->VHT_SIG_B,4); + phydmtxinfo->vht_sig_b_crc = pMacTxInfo->VHT_SIG_B_CRC; + _rtw_memcpy(&phydmtxinfo->vht_delimiter,pMacTxInfo->VHT_Delimiter,4); } #endif /* for HW TX mode */ -void mpt_ProSetPMacTx(PADAPTER Adapter) +u8 mpt_ProSetPMacTx(PADAPTER Adapter) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); PMPT_CONTEXT pMptCtx = &(Adapter->mppriv.mpt_ctx); struct mp_priv *pmppriv = &Adapter->mppriv; + struct hal_spec_t *hal_spec = GET_HAL_SPEC(Adapter); RT_PMAC_TX_INFO PMacTxInfo = pMptCtx->PMacTxInfo; - u32 u4bTmp; struct dm_struct *p_dm_odm; + u32 u4bTmp; + u8 status = _TRUE; p_dm_odm = &pHalData->odmpriv; @@ -2303,14 +2386,42 @@ void mpt_ProSetPMacTx(PADAPTER Adapter) RTW_INFO("TXSC %d BandWidth %d PacketPeriod %d PacketCount %d PacketLength %d PacketPattern %d\n", PMacTxInfo.TX_SC, PMacTxInfo.BandWidth, PMacTxInfo.PacketPeriod, PMacTxInfo.PacketCount, PMacTxInfo.PacketLength, PMacTxInfo.PacketPattern); - if (IS_HARDWARE_TYPE_JAGUAR3(Adapter)) { + if (hal_spec->tx_nss_num < 2 && MPT_IS_2SS_RATE(PMacTxInfo.TX_RATE)) + return _FALSE; + if (hal_spec->tx_nss_num < 3 && MPT_IS_3SS_RATE(PMacTxInfo.TX_RATE)) + return _FALSE; + if (hal_spec->tx_nss_num < 4 && MPT_IS_4SS_RATE(PMacTxInfo.TX_RATE)) + return _FALSE; + if (!is_supported_vht(Adapter->registrypriv.wireless_mode) && MPT_IS_VHT_RATE(PMacTxInfo.TX_RATE)) + return _FALSE; + if (!is_supported_ht(Adapter->registrypriv.wireless_mode) && MPT_IS_HT_RATE(PMacTxInfo.TX_RATE)) + return _FALSE; + + if (PMacTxInfo.BandWidth == 1 && hal_chk_bw_cap(Adapter, BW_CAP_40M)) + PMacTxInfo.BandWidth = CHANNEL_WIDTH_40; + else if (PMacTxInfo.BandWidth == 2 && hal_chk_bw_cap(Adapter, BW_CAP_80M)) + PMacTxInfo.BandWidth = CHANNEL_WIDTH_80; + else + PMacTxInfo.BandWidth = CHANNEL_WIDTH_20; + + if (IS_HARDWARE_TYPE_JAGUAR3(Adapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(Adapter)) { #ifdef PHYDM_PMAC_TX_SETTING_SUPPORT struct phydm_pmac_info phydm_mactxinfo; - mpt_convert_phydm_txinfo_for_jaguar3(PMacTxInfo, &phydm_mactxinfo); + if (PMacTxInfo.bEnPMacTx == TRUE) { + pMptCtx->HWTxmode = PMacTxInfo.Mode; + pMptCtx->mpt_rate_index = PMacTxInfo.TX_RATE; + if (PMacTxInfo.Mode == CONTINUOUS_TX) + hal_mpt_SetTxPower(Adapter); + } else { + PMacTxInfo.Mode = pMptCtx->HWTxmode; + PMacTxInfo.TX_RATE = pMptCtx->mpt_rate_index; + pMptCtx->HWTxmode = TEST_NONE; + } + mpt_convert_phydm_txinfo_for_jaguar3(&PMacTxInfo, &phydm_mactxinfo); phydm_set_pmac_tx(p_dm_odm, &phydm_mactxinfo, pMptCtx->mpt_rf_path); #endif - return; + return status; } if (PMacTxInfo.bEnPMacTx == FALSE) { @@ -2337,7 +2448,7 @@ void mpt_ProSetPMacTx(PADAPTER Adapter) mpt_SetSingleTone_8814A(Adapter, FALSE, TRUE); } pMptCtx->HWTxmode = TEST_NONE; - return; + return status; } pMptCtx->mpt_rate_index = PMacTxInfo.TX_RATE; @@ -2501,6 +2612,7 @@ void mpt_ProSetPMacTx(PADAPTER Adapter) if (PMacTxInfo.Mode == OFDM_Single_Tone_TX) mpt_SetSingleTone_8814A(Adapter, TRUE, TRUE); + return status; } #endif @@ -2527,4 +2639,14 @@ void hal_mpt_SetContinuousTx(PADAPTER pAdapter, u8 bStart) } } +void mpt_trigger_tssi_tracking(PADAPTER pAdapter, u8 rf_path) +{ +#ifdef CONFIG_RTL8814B + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_struct *pDM_Odm = &pHalData->odmpriv; + + halrf_do_tssi_8814b(pDM_Odm, rf_path); +#endif +} + #endif /* CONFIG_MP_INCLUDE*/ diff --git a/hal/halmac/halmac_88xx/halmac_8822b/halmac_init_8822b.c b/hal/halmac/halmac_88xx/halmac_8822b/halmac_init_8822b.c index 96caa0e..3216ab9 100644 --- a/hal/halmac/halmac_88xx/halmac_8822b/halmac_init_8822b.c +++ b/hal/halmac/halmac_88xx/halmac_8822b/halmac_init_8822b.c @@ -751,6 +751,7 @@ enum halmac_ret_status init_protocol_cfg_8822b(struct halmac_adapter *adapter) { u32 value32; + u8 value8; struct halmac_api *api = (struct halmac_api *)adapter->halmac_api; PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__); @@ -773,6 +774,9 @@ init_protocol_cfg_8822b(struct halmac_adapter *adapter) HALMAC_REG_W8(REG_FAST_EDCA_BEBK_SETTING, WLAN_FAST_EDCA_BE_TH); HALMAC_REG_W8(REG_FAST_EDCA_BEBK_SETTING + 2, WLAN_FAST_EDCA_BK_TH); + value8 = HALMAC_REG_R8(REG_INIRTS_RATE_SEL); + HALMAC_REG_W8(REG_INIRTS_RATE_SEL, value8 | BIT(5)); + PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__); return HALMAC_RET_SUCCESS; diff --git a/hal/halmac/halmac_88xx/halmac_8822b/halmac_phy_8822b.c b/hal/halmac/halmac_88xx/halmac_8822b/halmac_phy_8822b.c index 9630db9..e4f4a81 100644 --- a/hal/halmac/halmac_88xx/halmac_8822b/halmac_phy_8822b.c +++ b/hal/halmac/halmac_88xx/halmac_8822b/halmac_phy_8822b.c @@ -83,6 +83,10 @@ struct halmac_intf_phy_para pcie_gen1_phy_param_8822b[] = { HALMAC_IP_INTF_PHY, HALMAC_INTF_PHY_CUT_ALL, HALMAC_INTF_PHY_PLATFORM_ASUS}, + {0x001B, 0xF029, + HALMAC_IP_INTF_PHY, + HALMAC_INTF_PHY_CUT_ALL, + HALMAC_INTF_PHY_PLATFORM_LENOVO_V540}, {0x0020, 0x94FF, HALMAC_IP_INTF_PHY, HALMAC_INTF_PHY_CUT_C, diff --git a/hal/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.c b/hal/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.c index 4b46dfe..2ba940d 100644 --- a/hal/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.c +++ b/hal/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.c @@ -211,7 +211,7 @@ static struct halmac_wlan_pwr_cfg TRANS_ACT_TO_CARDEMU_8822B[] = { HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_ADDR_MAC, - HALMAC_PWR_CMD_WRITE, BIT(3), 0}, + HALMAC_PWR_CMD_WRITE, 0xFF, 0xC4}, {0x001F, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_INTF_ALL_MSK, diff --git a/hal/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.h b/hal/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.h index 3b7fd3c..59a97c8 100644 --- a/hal/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.h +++ b/hal/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.h @@ -21,7 +21,7 @@ #if HALMAC_8822B_SUPPORT -#define HALMAC_8822B_PWR_SEQ_VER "V31" +#define HALMAC_8822B_PWR_SEQ_VER "V35" extern struct halmac_wlan_pwr_cfg *card_en_flow_8822b[]; extern struct halmac_wlan_pwr_cfg *card_dis_flow_8822b[]; diff --git a/hal/halmac/halmac_88xx/halmac_bb_rf_88xx.c b/hal/halmac/halmac_88xx/halmac_bb_rf_88xx.c index 8227bd7..245f424 100644 --- a/hal/halmac/halmac_88xx/halmac_bb_rf_88xx.c +++ b/hal/halmac/halmac_88xx/halmac_bb_rf_88xx.c @@ -19,6 +19,58 @@ #include "halmac_init_88xx.h" #if HALMAC_88XX_SUPPORT +/** + * start_dpk_88xx() -trigger FW DPK + * @adapter : the adapter of halmac + * Author : Yong-Ching Lin/KaiYuan Chang/Ivan Lin + * Return : enum halmac_ret_status + * More details of status code can be found in prototype document + */ +enum halmac_ret_status +start_dpk_88xx(struct halmac_adapter *adapter) +{ + u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 }; + u16 seq_num = 0; + enum halmac_ret_status status = HALMAC_RET_SUCCESS; + struct halmac_h2c_header_info hdr_info; + enum halmac_cmd_process_status *proc_status; + + proc_status = &adapter->halmac_state.dpk_state.proc_status; + + if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS) + return HALMAC_RET_NO_DLFW; + + if (adapter->fw_ver.h2c_version < 15) + return HALMAC_RET_FW_NO_SUPPORT; + + PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__); + + if (*proc_status == HALMAC_CMD_PROCESS_SENDING) { + PLTFM_MSG_TRACE("[TRACE]Wait event(dpk)\n"); + return HALMAC_RET_BUSY_STATE; + } + + *proc_status = HALMAC_CMD_PROCESS_SENDING; + + hdr_info.sub_cmd_id = SUB_CMD_ID_DPK; + hdr_info.content_size = 1; + hdr_info.ack = 1; + set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num); + + adapter->halmac_state.dpk_state.seq_num = seq_num; + + status = send_h2c_pkt_88xx(adapter, h2c_buf); + + if (status != HALMAC_RET_SUCCESS) { + PLTFM_MSG_ERR("[ERR]send h2c pkt fail!!\n"); + reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_DPK); + return status; + } + + PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__); + + return HALMAC_RET_SUCCESS; +} /** * start_iqk_88xx() -trigger FW IQK @@ -163,6 +215,34 @@ get_iqk_status_88xx(struct halmac_adapter *adapter, return HALMAC_RET_SUCCESS; } +enum halmac_ret_status +get_dpk_status_88xx(struct halmac_adapter *adapter, + enum halmac_cmd_process_status *proc_status, u8 *data, + u32 *size) +{ + struct halmac_dpk_state *state = &adapter->halmac_state.dpk_state; + + *proc_status = adapter->halmac_state.dpk_state.proc_status; + + if (!data) + return HALMAC_RET_NULL_POINTER; + + if (!size) + return HALMAC_RET_NULL_POINTER; + + if (*proc_status == HALMAC_CMD_PROCESS_DONE) { + if (*size < state->data_size) { + *size = state->data_size; + return HALMAC_RET_BUFFER_TOO_SMALL; + } + + *size = state->data_size; + PLTFM_MEMCPY(data, state->data, *size); + } + + return HALMAC_RET_SUCCESS; +} + enum halmac_ret_status get_pwr_trk_status_88xx(struct halmac_adapter *adapter, enum halmac_cmd_process_status *proc_status) @@ -300,6 +380,102 @@ get_h2c_ack_iqk_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size) return HALMAC_RET_SUCCESS; } +enum halmac_ret_status +get_h2c_ack_dpk_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size) +{ + u8 seq_num; + u8 fw_rc; + struct halmac_dpk_state *state = &adapter->halmac_state.dpk_state; + enum halmac_cmd_process_status proc_status; + + seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf); + PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n", + state->seq_num, seq_num); + if (seq_num != state->seq_num) { + PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n", + state->seq_num, seq_num); + return HALMAC_RET_SUCCESS; + } + + if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) { + PLTFM_MSG_ERR("[ERR]not cmd sending\n"); + return HALMAC_RET_SUCCESS; + } + + fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf); + state->fw_rc = fw_rc; + + if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS) { + proc_status = HALMAC_CMD_PROCESS_RCVD; + state->proc_status = proc_status; + PLTFM_EVENT_SIG(HALMAC_FEATURE_DPK, proc_status, NULL, 0); + } else { + proc_status = HALMAC_CMD_PROCESS_ERROR; + state->proc_status = proc_status; + PLTFM_EVENT_SIG(HALMAC_FEATURE_DPK, proc_status, &fw_rc, 1); + } + + return HALMAC_RET_SUCCESS; +} + +enum halmac_ret_status +get_dpk_data_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size) +{ + u8 seq_num; + u8 seg_id; + u8 seg_size; + u16 total_size; + enum halmac_cmd_process_status proc_status; + struct halmac_dpk_state *state = &adapter->halmac_state.dpk_state; + + seq_num = (u8)DPK_DATA_GET_H2C_SEQ(buf); + PLTFM_MSG_TRACE("[TRACE]seq num : h2c->%d c2h->%d\n", + state->seq_num, seq_num); + if (seq_num != state->seq_num) { + PLTFM_MSG_ERR("[ERR]seq num mismatch : h2c->%d c2h->%d\n", + state->seq_num, seq_num); + return HALMAC_RET_SUCCESS; + } + + if (state->proc_status != HALMAC_CMD_PROCESS_RCVD) { + PLTFM_MSG_ERR("[ERR]not receive dpk ack\n"); + if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) { + PLTFM_MSG_ERR("[ERR]not cmd sending\n"); + return HALMAC_RET_SUCCESS; + } + } + + total_size = (u16)DPK_DATA_GET_TOTAL_SIZE(buf); + seg_id = (u8)DPK_DATA_GET_SEGMENT_ID(buf); + seg_size = (u8)DPK_DATA_GET_SEGMENT_SIZE(buf); + state->data_size = total_size; + + if (!state->data) { + state->data = (u8 *)PLTFM_MALLOC(state->data_size); + if (!state->data) { + PLTFM_MSG_ERR("[ERR]malloc fail!!\n"); + return HALMAC_RET_NULL_POINTER; + } + } + + if (seg_id == 0) + state->seg_size = seg_size; + + PLTFM_MEMCPY(state->data + seg_id * state->seg_size, + buf + C2H_DATA_OFFSET_88XX, seg_size); + + if (DPK_DATA_GET_END_SEGMENT(buf) == 0) + return HALMAC_RET_SUCCESS; + + proc_status = HALMAC_CMD_PROCESS_DONE; + state->proc_status = proc_status; + + PLTFM_EVENT_SIG(HALMAC_FEATURE_DPK, state->proc_status, state->data, + state->data_size); + + return HALMAC_RET_SUCCESS; +} + enum halmac_ret_status get_h2c_ack_pwr_trk_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size) { diff --git a/hal/halmac/halmac_88xx/halmac_bb_rf_88xx.h b/hal/halmac/halmac_88xx/halmac_bb_rf_88xx.h index 4e1549f..1aa2386 100644 --- a/hal/halmac/halmac_88xx/halmac_bb_rf_88xx.h +++ b/hal/halmac/halmac_88xx/halmac_bb_rf_88xx.h @@ -52,6 +52,20 @@ get_h2c_ack_pwr_trk_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size); enum halmac_ret_status get_psd_data_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size); +enum halmac_ret_status +start_dpk_88xx(struct halmac_adapter *adapter); + +enum halmac_ret_status +get_h2c_ack_dpk_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size); + +enum halmac_ret_status +get_dpk_data_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size); + +enum halmac_ret_status +get_dpk_status_88xx(struct halmac_adapter *adapter, + enum halmac_cmd_process_status *proc_status, u8 *data, + u32 *size); + #endif /* HALMAC_88XX_SUPPORT */ #endif/* _HALMAC_BB_RF_88XX_H_ */ diff --git a/hal/halmac/halmac_88xx/halmac_common_88xx.c b/hal/halmac/halmac_88xx/halmac_common_88xx.c index cdec785..885be21 100644 --- a/hal/halmac/halmac_88xx/halmac_common_88xx.c +++ b/hal/halmac/halmac_88xx/halmac_common_88xx.c @@ -500,7 +500,9 @@ set_hw_value_88xx(struct halmac_adapter *adapter, enum halmac_hw_id hw_id, void *value) { enum halmac_ret_status status = HALMAC_RET_SUCCESS; - struct halmac_tx_page_threshold_info *th_info = NULL; +#if HALMAC_SDIO_SUPPORT + struct halmac_tx_page_threshold_info *th_info; +#endif struct halmac_api *api = (struct halmac_api *)adapter->halmac_api; PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__); @@ -761,6 +763,9 @@ parse_c2h_pkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size) case C2H_SUB_CMD_ID_SCAN_CH_NOTIFY: status = get_scan_ch_notify_88xx(adapter, c2h_pkt, c2h_size); break; + case C2H_SUB_CMD_ID_DPK_DATA: + status = get_dpk_data_88xx(adapter, c2h_pkt, c2h_size); + break; default: PLTFM_MSG_WARN("[WARN]Sub cmd id!!\n"); status = HALMAC_RET_C2H_NOT_HANDLED; @@ -893,6 +898,9 @@ get_h2c_ack_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size) case H2C_SUB_CMD_ID_FW_SNDING_ACK: status = get_h2c_ack_fw_snding_88xx(adapter, buf, size); break; + case H2C_SUB_CMD_ID_DPK_ACK: + status = get_h2c_ack_dpk_88xx(adapter, buf, size); + break; default: status = HALMAC_RET_C2H_NOT_HANDLED; break; @@ -2853,6 +2861,9 @@ query_status_88xx(struct halmac_adapter *adapter, case HALMAC_FEATURE_FW_SNDING: status = get_fw_snding_status_88xx(adapter, proc_status); break; + case HALMAC_FEATURE_DPK: + status = get_dpk_status_88xx(adapter, proc_status, data, size); + break; default: return HALMAC_RET_INVALID_FEATURE_ID; } @@ -2998,7 +3009,7 @@ pwr_seq_parser_88xx(struct halmac_adapter *adapter, cut = HALMAC_PWR_CUT_TESTCHIP_MSK; break; default: - PLTFM_MSG_ERR("[ERR]cut version!!\n"); + PLTFM_MSG_ERR("[ERR]chip info!!\n"); return HALMAC_RET_SWITCH_CASE_ERROR; } @@ -3165,7 +3176,7 @@ parse_intf_phy_88xx(struct halmac_adapter *adapter, u16 ip_sel; struct halmac_intf_phy_para *cur_param; struct halmac_api *api = (struct halmac_api *)adapter->halmac_api; - u8 result = HALMAC_RET_SUCCESS; + enum halmac_ret_status result = HALMAC_RET_SUCCESS; switch (adapter->chip_ver) { case HALMAC_CHIP_VER_A_CUT: @@ -3210,6 +3221,15 @@ parse_intf_phy_88xx(struct halmac_adapter *adapter, } else if (intf_phy == HAL_INTF_PHY_USB2 || intf_phy == HAL_INTF_PHY_USB3) { #if HALMAC_USB_SUPPORT + if (offset > 0x100) + usb_page_switch_88xx(adapter, + intf_phy, + 1); + else + usb_page_switch_88xx(adapter, + intf_phy, + 0); + offset = offset & 0xFF; result = usbphy_write_88xx(adapter, (u8)offset, value, intf_phy); if (result != HALMAC_RET_SUCCESS) @@ -3236,7 +3256,7 @@ parse_intf_phy_88xx(struct halmac_adapter *adapter, cur_param++; } while (1); - return HALMAC_RET_SUCCESS; + return result; } /** diff --git a/hal/halmac/halmac_88xx/halmac_efuse_88xx.c b/hal/halmac/halmac_88xx/halmac_efuse_88xx.c index 9d860c5..184c2df 100644 --- a/hal/halmac/halmac_88xx/halmac_efuse_88xx.c +++ b/hal/halmac/halmac_88xx/halmac_efuse_88xx.c @@ -26,6 +26,15 @@ #define FEATURE_DUMP_LOG_EFUSE HALMAC_FEATURE_DUMP_LOGICAL_EFUSE #define FEATURE_DUMP_LOG_EFUSE_MASK HALMAC_FEATURE_DUMP_LOGICAL_EFUSE_MASK +#define SUPER_USB_ZONE0_START 0x150 +#define SUPER_USB_ZONE0_END 0x199 +#define SUPER_USB_ZONE1_START 0x200 +#define SUPER_USB_ZONE1_END 0x217 +#define SUPER_USB_RE_PG_CK_ZONE0_START 0x15D +#define SUPER_USB_RE_PG_CK_ZONE0_END 0x164 + +static u8 bt_switch = 0; + static enum halmac_cmd_construct_state efuse_cmd_cnstr_state_88xx(struct halmac_adapter *adapter); @@ -54,6 +63,10 @@ dump_efuse_drv_88xx(struct halmac_adapter *adapter); static enum halmac_ret_status proc_write_log_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value); +static enum halmac_ret_status +proc_write_log_efuse_word_88xx(struct halmac_adapter *adapter, u32 offset, + u16 value); + static enum halmac_ret_status update_eeprom_mask_88xx(struct halmac_adapter *adapter, struct halmac_pg_efuse_info *info, u8 *updated_mask); @@ -72,6 +85,11 @@ proc_pg_efuse_88xx(struct halmac_adapter *adapter, struct halmac_pg_efuse_info *info, u8 word_en, u8 pre_word_en, u32 eeprom_offset); +static enum halmac_ret_status +pg_super_usb_efuse_88xx(struct halmac_adapter *adapter, + struct halmac_pg_efuse_info *info, u8 word_en, + u8 pre_word_en, u32 eeprom_offset); + static enum halmac_ret_status program_efuse_88xx(struct halmac_adapter *adapter, struct halmac_pg_efuse_info *info, u8 *updated_mask); @@ -80,6 +98,28 @@ static void mask_eeprom_88xx(struct halmac_adapter *adapter, struct halmac_pg_efuse_info *info); +static enum halmac_ret_status +proc_gen_super_usb_map_88xx(struct halmac_adapter *adapter, u8 *drv_map, + u8 *updated_map, u8 *updated_mask); + +static enum halmac_ret_status +super_usb_efuse_parser_88xx(struct halmac_adapter *adapter, u8 *phy_map, + u8 *log_map, u8 *log_mask); + +static enum halmac_ret_status +super_usb_chk_88xx(struct halmac_adapter *adapter, u8 *super_usb); + +static enum halmac_ret_status +log_efuse_re_pg_chk_88xx(struct halmac_adapter *adapter, u8 *efuse_mask, + u32 addr, u8 *re_pg); + +static enum halmac_ret_status +super_usb_fmt_chk_88xx(struct halmac_adapter *adapter, u8 *re_pg); + +static enum halmac_ret_status +super_usb_re_pg_chk_88xx(struct halmac_adapter *adapter, u8 *phy_map, + u8 *re_pg); + /** * dump_efuse_map_88xx() - dump "physical" efuse map * @adapter : the adapter of halmac @@ -220,13 +260,23 @@ dump_efuse_map_bt_88xx(struct halmac_adapter *adapter, PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n"); return status; } + bt_switch = 1; status = read_hw_efuse_88xx(adapter, 0, size, map); if (status != HALMAC_RET_SUCCESS) { + bt_switch = 0; PLTFM_MSG_ERR("[ERR]read hw efuse\n"); return status; } + status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI); + if (status != HALMAC_RET_SUCCESS) { + bt_switch = 0; + PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n"); + return status; + } + bt_switch = 0; + if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) != HALMAC_RET_SUCCESS) return HALMAC_RET_ERROR_STATE; @@ -282,13 +332,23 @@ write_efuse_bt_88xx(struct halmac_adapter *adapter, u32 offset, u8 value, PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n"); return status; } + bt_switch = 1; status = write_hw_efuse_88xx(adapter, offset, value); if (status != HALMAC_RET_SUCCESS) { + bt_switch = 0; PLTFM_MSG_ERR("[ERR]write efuse\n"); return status; } + status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI); + if (status != HALMAC_RET_SUCCESS) { + bt_switch = 0; + PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n"); + return status; + } + bt_switch = 0; + if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) != HALMAC_RET_SUCCESS) return HALMAC_RET_ERROR_STATE; @@ -344,13 +404,23 @@ read_efuse_bt_88xx(struct halmac_adapter *adapter, u32 offset, u8 *value, PLTFM_MSG_ERR("[ERR]switch efuse bank\n"); return status; } + bt_switch = 1; status = read_efuse_88xx(adapter, offset, 1, value); if (status != HALMAC_RET_SUCCESS) { + bt_switch = 0; PLTFM_MSG_ERR("[ERR]read efuse\n"); return status; } + status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI); + if (status != HALMAC_RET_SUCCESS) { + bt_switch = 0; + PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n"); + return status; + } + bt_switch = 0; + if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) != HALMAC_RET_SUCCESS) return HALMAC_RET_ERROR_STATE; @@ -737,6 +807,61 @@ write_log_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value) return HALMAC_RET_SUCCESS; } +/** + * write_log_efuse_word_88xx() - write "logical" efuse offset word + * @adapter : the adapter of halmac + * @offset : offset + * @value : value + * Author : Soar + * Return : enum halmac_ret_status + * More details of status code can be found in prototype document + */ +enum halmac_ret_status +write_log_efuse_word_88xx(struct halmac_adapter *adapter, u32 offset, u16 value) +{ + enum halmac_ret_status status = HALMAC_RET_SUCCESS; + enum halmac_cmd_process_status *proc_status; + + proc_status = &adapter->halmac_state.efuse_state.proc_status; + + PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__); + + if (offset >= adapter->hw_cfg_info.eeprom_size) { + PLTFM_MSG_ERR("[ERR]Offset is too large\n"); + return HALMAC_RET_EFUSE_SIZE_INCORRECT; + } + + if (*proc_status == HALMAC_CMD_PROCESS_SENDING) { + PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n"); + return HALMAC_RET_BUSY_STATE; + } + + if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) { + PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n"); + return HALMAC_RET_ERROR_STATE; + } + + status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_MSG_ERR("[ERR]switch efuse bank\n"); + return status; + } + + status = proc_write_log_efuse_word_88xx(adapter, offset, value); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_MSG_ERR("[ERR]write logical efuse\n"); + return status; + } + + if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) != + HALMAC_RET_SUCCESS) + return HALMAC_RET_ERROR_STATE; + + PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__); + + return HALMAC_RET_SUCCESS; +} + /** * pg_efuse_by_map_88xx() - pg logical efuse by map * @adapter : the adapter of halmac @@ -873,9 +998,11 @@ switch_efuse_bank_88xx(struct halmac_adapter *adapter, u8 reg_value; struct halmac_api *api = (struct halmac_api *)adapter->halmac_api; - if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_BUSY) != - HALMAC_RET_SUCCESS) - return HALMAC_RET_ERROR_STATE; + if (!bt_switch) { + if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_BUSY) != + HALMAC_RET_SUCCESS) + return HALMAC_RET_ERROR_STATE; + } reg_value = HALMAC_REG_R8(REG_LDO_EFUSE_CTRL + 1); @@ -1293,9 +1420,19 @@ proc_pg_efuse_by_map_88xx(struct halmac_adapter *adapter, enum halmac_efuse_read_cfg cfg) { u8 *updated_mask = NULL; + u8 *updated_map = NULL; + u32 map_size = adapter->hw_cfg_info.eeprom_size; u32 mask_size = adapter->hw_cfg_info.eeprom_size >> 4; + u8 super_usb; + struct halmac_pg_efuse_info local_info; enum halmac_ret_status status = HALMAC_RET_SUCCESS; + status = super_usb_chk_88xx(adapter, &super_usb); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_MSG_ERR("[ERR]super_usb_chk\n"); + return status; + } + updated_mask = (u8 *)PLTFM_MALLOC(mask_size); if (!updated_mask) { PLTFM_MSG_ERR("[ERR]malloc updated mask\n"); @@ -1310,21 +1447,58 @@ proc_pg_efuse_by_map_88xx(struct halmac_adapter *adapter, return status; } + if (super_usb) { + updated_map = (u8 *)PLTFM_MALLOC(map_size); + if (!updated_map) { + PLTFM_MSG_ERR("[ERR]malloc updated map\n"); + PLTFM_FREE(updated_mask, mask_size); + return HALMAC_RET_MALLOC_FAIL; + } + PLTFM_MEMSET(updated_map, 0xFF, map_size); + + status = proc_gen_super_usb_map_88xx(adapter, info->efuse_map, + updated_map, updated_mask); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_MSG_ERR("[ERR]gen eeprom mask/map\n"); + PLTFM_FREE(updated_mask, mask_size); + PLTFM_FREE(updated_map, map_size); + return status; + } + + local_info.efuse_map = updated_map; + local_info.efuse_mask = updated_mask; + local_info.efuse_map_size = map_size; + local_info.efuse_mask_size = mask_size; + } + + if (super_usb) + status = check_efuse_enough_88xx(adapter, &local_info, + updated_mask); + else status = check_efuse_enough_88xx(adapter, info, updated_mask); if (status != HALMAC_RET_SUCCESS) { PLTFM_MSG_ERR("[ERR]chk efuse enough\n"); PLTFM_FREE(updated_mask, mask_size); + if (super_usb) + PLTFM_FREE(updated_map, map_size); return status; } + if (super_usb) + status = program_efuse_88xx(adapter, &local_info, updated_mask); + else status = program_efuse_88xx(adapter, info, updated_mask); if (status != HALMAC_RET_SUCCESS) { PLTFM_MSG_ERR("[ERR]pg efuse\n"); PLTFM_FREE(updated_mask, mask_size); + if (super_usb) + PLTFM_FREE(updated_map, map_size); return status; } PLTFM_FREE(updated_mask, mask_size); + if (super_usb) + PLTFM_FREE(updated_map, map_size); return HALMAC_RET_SUCCESS; } @@ -1520,6 +1694,117 @@ proc_write_log_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value) return HALMAC_RET_SUCCESS; } +static enum halmac_ret_status +proc_write_log_efuse_word_88xx(struct halmac_adapter *adapter, u32 offset, + u16 value) +{ + u8 byte1; + u8 byte2; + u8 blk; + u8 blk_idx; + u8 hdr; + u8 hdr2; + u8 *map = NULL; + u32 eeprom_size = adapter->hw_cfg_info.eeprom_size; + u32 prtct_efuse_size = adapter->hw_cfg_info.prtct_efuse_size; + u32 end; + enum halmac_ret_status status = HALMAC_RET_SUCCESS; + + map = (u8 *)PLTFM_MALLOC(eeprom_size); + if (!map) { + PLTFM_MSG_ERR("[ERR]malloc map\n"); + return HALMAC_RET_MALLOC_FAIL; + } + PLTFM_MEMSET(map, 0xFF, eeprom_size); + + status = read_log_efuse_map_88xx(adapter, map); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_MSG_ERR("[ERR]read logical efuse\n"); + PLTFM_FREE(map, eeprom_size); + return status; + } + + end = adapter->efuse_end; + blk = (u8)(offset >> 3); + blk_idx = (u8)((offset & (8 - 1)) >> 1); + + if (offset > 0x7f) { + hdr = (((blk & 0x07) << 5) & 0xE0) | 0x0F; + hdr2 = (u8)(((blk & 0x78) << 1) + + ((0x1 << blk_idx) ^ 0x0F)); + } else { + hdr = (u8)((blk << 4) + ((0x01 << blk_idx) ^ 0x0F)); + } + + if ((offset & 1) == 0) { + byte1 = (u8)(value & 0xFF); + byte2 = (u8)((value >> 8) & 0xFF); + } else { + PLTFM_FREE(map, eeprom_size); + return HALMAC_RET_ADR_NOT_ALIGN; + } + + if (offset > 0x7f) { + if (adapter->hw_cfg_info.efuse_size <= + 4 + prtct_efuse_size + end) { + PLTFM_FREE(map, eeprom_size); + return HALMAC_RET_EFUSE_NOT_ENOUGH; + } + + status = write_hw_efuse_88xx(adapter, end, hdr); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_FREE(map, eeprom_size); + return status; + } + + status = write_hw_efuse_88xx(adapter, end + 1, hdr2); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_FREE(map, eeprom_size); + return status; + } + + status = write_hw_efuse_88xx(adapter, end + 2, byte1); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_FREE(map, eeprom_size); + return status; + } + + status = write_hw_efuse_88xx(adapter, end + 3, byte2); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_FREE(map, eeprom_size); + return status; + } + } else { + if (adapter->hw_cfg_info.efuse_size <= + 3 + prtct_efuse_size + end) { + PLTFM_FREE(map, eeprom_size); + return HALMAC_RET_EFUSE_NOT_ENOUGH; + } + + status = write_hw_efuse_88xx(adapter, end, hdr); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_FREE(map, eeprom_size); + return status; + } + + status = write_hw_efuse_88xx(adapter, end + 1, byte1); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_FREE(map, eeprom_size); + return status; + } + + status = write_hw_efuse_88xx(adapter, end + 2, byte2); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_FREE(map, eeprom_size); + return status; + } + } + + PLTFM_FREE(map, eeprom_size); + + return HALMAC_RET_SUCCESS; +} + enum halmac_ret_status read_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u32 size, u8 *map) { @@ -1629,6 +1914,14 @@ check_efuse_enough_88xx(struct halmac_adapter *adapter, u16 j; u32 eeprom_offset; u32 pg_num = 0; + u8 super_usb; + enum halmac_ret_status status = HALMAC_RET_SUCCESS; + + status = super_usb_chk_88xx(adapter, &super_usb); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_MSG_ERR("[ERR]super_usb_chk\n"); + return status; + } for (i = 0; i < info->efuse_map_size; i = i + 8) { eeprom_offset = i; @@ -1639,14 +1932,21 @@ check_efuse_enough_88xx(struct halmac_adapter *adapter, pre_word_en = (*(updated_mask + (i >> 4)) >> 4); if (pre_word_en > 0) { - if (eeprom_offset > 0x7f) { - pg_num += 2; + if (super_usb && + ((eeprom_offset >= SUPER_USB_ZONE0_START && + eeprom_offset <= SUPER_USB_ZONE0_END) || + (eeprom_offset >= SUPER_USB_ZONE1_START && + eeprom_offset <= SUPER_USB_ZONE1_END))) { for (j = 0; j < 4; j++) { if (((pre_word_en >> j) & 0x1) > 0) - pg_num += 2; + pg_num += 4; } } else { - pg_num++; + if (eeprom_offset > 0x7f) + pg_num += 2; + else + pg_num++; + for (j = 0; j < 4; j++) { if (((pre_word_en >> j) & 0x1) > 0) pg_num += 2; @@ -1767,6 +2067,68 @@ proc_pg_efuse_88xx(struct halmac_adapter *adapter, return status; } +static enum halmac_ret_status +pg_super_usb_efuse_88xx(struct halmac_adapter *adapter, + struct halmac_pg_efuse_info *info, u8 word_en, + u8 pre_word_en, u32 eeprom_offset) +{ + u8 blk; + u8 hdr; + u8 hdr2; + u16 i; + u32 efuse_end; + enum halmac_ret_status status = HALMAC_RET_SUCCESS; + + efuse_end = adapter->efuse_end; + + blk = (u8)(eeprom_offset >> 3); + hdr = (((blk & 0x07) << 5) & 0xE0) | 0x0F; + + for (i = 0; i < 4; i++) { + hdr = (((blk & 0x07) << 5) & 0xE0) | 0x0F; + if (((pre_word_en >> i) & 0x1) > 0) { + hdr2 = (u8)(((blk & 0x78) << 1) + + ((pre_word_en & BIT(i)) ^ 0x0F)); + + status = write_hw_efuse_88xx(adapter, efuse_end, hdr); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_MSG_ERR("[ERR]write efuse\n"); + return status; + } + + status = write_hw_efuse_88xx(adapter, efuse_end + 1, + hdr2); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_MSG_ERR("[ERR]write efuse(+1)\n"); + return status; + } + + efuse_end = efuse_end + 2; + + status = write_hw_efuse_88xx(adapter, efuse_end, + *(info->efuse_map + + eeprom_offset + + (i << 1))); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_MSG_ERR("[ERR]write efuse(<<1)\n"); + return status; + } + + status = write_hw_efuse_88xx(adapter, efuse_end + 1, + *(info->efuse_map + + eeprom_offset + (i << 1) + + 1)); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_MSG_ERR("[ERR]write efuse(<<1)+1\n"); + return status; + } + efuse_end = efuse_end + 2; + } + } + adapter->efuse_end = efuse_end; + return status; +} + static enum halmac_ret_status program_efuse_88xx(struct halmac_adapter *adapter, struct halmac_pg_efuse_info *info, u8 *updated_mask) @@ -1775,8 +2137,15 @@ program_efuse_88xx(struct halmac_adapter *adapter, u8 word_en; u16 i; u32 eeprom_offset; + u8 super_usb; enum halmac_ret_status status = HALMAC_RET_SUCCESS; + status = super_usb_chk_88xx(adapter, &super_usb); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_MSG_ERR("[ERR]super_usb_chk\n"); + return status; + } + for (i = 0; i < info->efuse_map_size; i = i + 8) { eeprom_offset = i; @@ -1789,7 +2158,20 @@ program_efuse_88xx(struct halmac_adapter *adapter, } if (pre_word_en > 0) { - if (eeprom_offset > 0x7f) { + if (super_usb && + ((eeprom_offset >= SUPER_USB_ZONE0_START && + eeprom_offset <= SUPER_USB_ZONE0_END) || + (eeprom_offset >= SUPER_USB_ZONE1_START && + eeprom_offset <= SUPER_USB_ZONE1_END))) { + status = pg_super_usb_efuse_88xx(adapter, info, + word_en, + pre_word_en, + eeprom_offset); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_MSG_ERR("[ERR]super usb efuse\n"); + return status; + } + } else if (eeprom_offset > 0x7f) { status = pg_extend_efuse_88xx(adapter, info, word_en, pre_word_en, @@ -2255,4 +2637,437 @@ read_wifi_phy_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u32 size, return HALMAC_RET_SUCCESS; } +static enum halmac_ret_status +proc_gen_super_usb_map_88xx(struct halmac_adapter *adapter, u8 *drv_map, + u8 *updated_map, u8 *updated_mask) +{ + u8 *local_map = NULL; + u8 *super_usb_map = NULL; + u8 *super_usb_mask = NULL; + u8 mask_val_0; + u8 mask_val_1; + u32 efuse_size; + u32 i; + u32 j; + u32 val32; + u32 map_size = adapter->hw_cfg_info.eeprom_size; + u32 mask_size = adapter->hw_cfg_info.eeprom_size >> 4; + enum halmac_ret_status status = HALMAC_RET_SUCCESS; + + if (adapter->efuse_map_valid == 0) { + efuse_size = adapter->hw_cfg_info.efuse_size; + + local_map = (u8 *)PLTFM_MALLOC(efuse_size); + if (!local_map) { + PLTFM_MSG_ERR("[ERR]local map\n"); + return HALMAC_RET_MALLOC_FAIL; + } + + status = read_efuse_88xx(adapter, 0, efuse_size, local_map); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_MSG_ERR("[ERR]read efuse\n"); + PLTFM_FREE(local_map, efuse_size); + return status; + } + + if (!adapter->efuse_map) { + adapter->efuse_map = (u8 *)PLTFM_MALLOC(efuse_size); + if (!adapter->efuse_map) { + PLTFM_MSG_ERR("[ERR]malloc adapter map\n"); + PLTFM_FREE(local_map, efuse_size); + return HALMAC_RET_MALLOC_FAIL; + } + } + + PLTFM_MUTEX_LOCK(&adapter->efuse_mutex); + PLTFM_MEMCPY(adapter->efuse_map, local_map, efuse_size); + adapter->efuse_map_valid = 1; + PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex); + + PLTFM_FREE(local_map, efuse_size); + } + + super_usb_mask = (u8 *)PLTFM_MALLOC(mask_size); + if (!super_usb_mask) { + PLTFM_MSG_ERR("[ERR]malloc updated mask\n"); + return HALMAC_RET_MALLOC_FAIL; + } + PLTFM_MEMSET(super_usb_mask, 0x00, mask_size); + + super_usb_map = (u8 *)PLTFM_MALLOC(map_size); + if (!super_usb_map) { + PLTFM_MSG_ERR("[ERR]malloc updated map\n"); + PLTFM_FREE(super_usb_mask, mask_size); + return HALMAC_RET_MALLOC_FAIL; + } + PLTFM_MEMSET(super_usb_map, 0xFF, map_size); + + status = super_usb_efuse_parser_88xx(adapter, adapter->efuse_map, + super_usb_map, super_usb_mask); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_FREE(super_usb_mask, mask_size); + PLTFM_FREE(super_usb_map, map_size); + return HALMAC_RET_EEPROM_PARSING_FAIL; + } + + for (i = 0; i < map_size; i = i + 16) { + mask_val_0 = *(updated_mask + (i >> 4)); + mask_val_1 = *(super_usb_mask + (i >> 4)); + if (mask_val_0 || mask_val_1) { + for (j = 0; j < 4; j++) { + val32 = i + (j << 1); + if (mask_val_0 & BIT(j + 4)) { + *(updated_map + val32) = + *(drv_map + val32); + *(updated_map + val32 + 1) = + *(drv_map + val32 + 1); + } else if (mask_val_1 & BIT(j + 4)) { + *(updated_map + val32) = + *(super_usb_map + val32); + *(updated_map + val32 + 1) = + *(super_usb_map + val32 + 1); + } + } + for (j = 0; j < 4; j++) { + val32 = i + (j << 1); + if (mask_val_0 & BIT(j)) { + *(updated_map + val32 + 8) = + *(drv_map + val32 + 8); + *(updated_map + val32 + 9) = + *(drv_map + val32 + 9); + } else if (mask_val_1 & BIT(j)) { + *(updated_map + val32 + 8) = + *(super_usb_map + val32 + 8); + *(updated_map + val32 + 9) = + *(super_usb_map + val32 + 9); + } + } + *(updated_mask + (i >> 4)) |= mask_val_1; + } + } + + PLTFM_FREE(super_usb_mask, mask_size); + PLTFM_FREE(super_usb_map, map_size); + + return status; +} + +static enum halmac_ret_status +super_usb_efuse_parser_88xx(struct halmac_adapter *adapter, u8 *phy_map, + u8 *log_map, u8 *log_mask) +{ + u8 i; + u8 value8; + u8 blk_idx; + u8 word_en; + u8 valid; + u8 hdr; + u8 hdr2 = 0; + u8 usb_addr; + u32 eeprom_idx; + u32 efuse_idx = 0; + u32 start_offset; + u32 prtct_efuse_size = adapter->hw_cfg_info.prtct_efuse_size; + struct halmac_hw_cfg_info *hw_info = &adapter->hw_cfg_info; + + do { + value8 = *(phy_map + efuse_idx); + hdr = value8; + + if ((hdr & 0x1f) == 0x0f) { + efuse_idx++; + value8 = *(phy_map + efuse_idx); + hdr2 = value8; + if (hdr2 == 0xff) + break; + blk_idx = ((hdr2 & 0xF0) >> 1) | ((hdr >> 5) & 0x07); + word_en = hdr2 & 0x0F; + } else { + blk_idx = (hdr & 0xF0) >> 4; + word_en = hdr & 0x0F; + } + + if (hdr == 0xff) + break; + + efuse_idx++; + + if (efuse_idx >= hw_info->efuse_size - prtct_efuse_size - 1) + return HALMAC_RET_EEPROM_PARSING_FAIL; + + for (i = 0; i < 4; i++) { + valid = (u8)((~(word_en >> i)) & BIT(0)); + if (valid == 1) { + eeprom_idx = (blk_idx << 3) + (i << 1); + + if ((eeprom_idx + 1) > hw_info->eeprom_size) { + PLTFM_MSG_ERR("[ERR]efuse idx:0x%X\n", + efuse_idx - 1); + + PLTFM_MSG_ERR("[ERR]read hdr:0x%X\n", + hdr); + + PLTFM_MSG_ERR("[ERR]rad hdr2:0x%X\n", + hdr2); + + return HALMAC_RET_EEPROM_PARSING_FAIL; + } + + value8 = *(phy_map + efuse_idx); + *(log_map + eeprom_idx) = value8; + + eeprom_idx++; + efuse_idx++; + + if (efuse_idx > hw_info->efuse_size - + prtct_efuse_size - 1) + return HALMAC_RET_EEPROM_PARSING_FAIL; + + value8 = *(phy_map + efuse_idx); + *(log_map + eeprom_idx) = value8; + + efuse_idx++; + + if (efuse_idx > hw_info->efuse_size - + prtct_efuse_size) + return HALMAC_RET_EEPROM_PARSING_FAIL; + } + } + + start_offset = blk_idx << 3; + if ((start_offset >= SUPER_USB_ZONE0_START && + start_offset <= SUPER_USB_ZONE0_END) || + (start_offset >= SUPER_USB_ZONE1_START && + start_offset <= SUPER_USB_ZONE1_END)) + usb_addr = 1; + else + usb_addr = 0; + if (usb_addr) { + if (word_en != 0xE && word_en != 0xD && + word_en != 0xB && word_en != 0x7) { + if (blk_idx & 1) + *(log_mask + (blk_idx >> 1)) |= + ~word_en & 0x0F; + else + *(log_mask + (blk_idx >> 1)) |= + ~(word_en << 4) & 0xF0; + } else { + if (blk_idx & 1) + *(log_mask + (blk_idx >> 1)) &= + word_en | 0xF0; + else + *(log_mask + (blk_idx >> 1)) &= + (word_en << 4) | 0x0F; + } + } + } while (1); + + adapter->efuse_end = efuse_idx; + + return HALMAC_RET_SUCCESS; +} + +static enum halmac_ret_status +super_usb_chk_88xx(struct halmac_adapter *adapter, u8 *super_usb) +{ + u8 *local_map = NULL; + u32 efuse_size; + u8 re_pg; + enum halmac_ret_status status = HALMAC_RET_SUCCESS; + + if (adapter->chip_id == HALMAC_CHIP_ID_8822C && + (adapter->intf == HALMAC_INTERFACE_PCIE || + adapter->intf == HALMAC_INTERFACE_USB)) { + *super_usb = 1; + } else { + *super_usb = 0; + return HALMAC_RET_SUCCESS; + } + + if (adapter->efuse_map_valid == 0) { + efuse_size = adapter->hw_cfg_info.efuse_size; + + local_map = (u8 *)PLTFM_MALLOC(efuse_size); + if (!local_map) { + PLTFM_MSG_ERR("[ERR]local map\n"); + return HALMAC_RET_MALLOC_FAIL; + } + + status = read_efuse_88xx(adapter, 0, efuse_size, local_map); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_MSG_ERR("[ERR]read efuse\n"); + PLTFM_FREE(local_map, efuse_size); + return status; + } + + if (!adapter->efuse_map) { + adapter->efuse_map = (u8 *)PLTFM_MALLOC(efuse_size); + if (!adapter->efuse_map) { + PLTFM_MSG_ERR("[ERR]malloc adapter map\n"); + PLTFM_FREE(local_map, efuse_size); + return HALMAC_RET_MALLOC_FAIL; + } + } + + PLTFM_MUTEX_LOCK(&adapter->efuse_mutex); + PLTFM_MEMCPY(adapter->efuse_map, local_map, efuse_size); + adapter->efuse_map_valid = 1; + PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex); + + PLTFM_FREE(local_map, efuse_size); + } + + status = super_usb_re_pg_chk_88xx(adapter, adapter->efuse_map, &re_pg); + if (status != HALMAC_RET_SUCCESS) + return status; + if (re_pg) { + status = super_usb_fmt_chk_88xx(adapter, &re_pg); + if (status != HALMAC_RET_SUCCESS) + return status; + if (re_pg == 1) { + *super_usb = 0; + return HALMAC_RET_SUCCESS; + } + } + + return status; +} + +static enum halmac_ret_status +log_efuse_re_pg_chk_88xx(struct halmac_adapter *adapter, u8 *efuse_mask, + u32 addr, u8 *re_pg) +{ + u32 size = adapter->hw_cfg_info.eeprom_size; + u8 mask_val; + u8 mask_offset; + enum halmac_ret_status status = HALMAC_RET_SUCCESS; + + if (addr >= size) { + PLTFM_MSG_ERR("[ERR]Offset is too large\n"); + return HALMAC_RET_EFUSE_SIZE_INCORRECT; + } + + mask_val = *(efuse_mask + (addr >> 4)); + if (addr & 0x8) + mask_offset = BIT((addr & 0x7) >> 1); + else + mask_offset = BIT((addr & 0x7) >> 1) << 4; + + if (mask_val & mask_offset) + *re_pg = 1; + else + *re_pg = 0; + + return status; +} + +static enum halmac_ret_status +super_usb_fmt_chk_88xx(struct halmac_adapter *adapter, u8 *re_pg) +{ + u32 map_size = adapter->hw_cfg_info.eeprom_size; + u32 mask_size = adapter->hw_cfg_info.eeprom_size >> 4; + u32 addr; + u8 *super_usb_map = NULL; + u8 *super_usb_mask = NULL; + enum halmac_ret_status status = HALMAC_RET_SUCCESS; + + super_usb_mask = (u8 *)PLTFM_MALLOC(mask_size); + if (!super_usb_mask) { + PLTFM_MSG_ERR("[ERR]malloc updated mask\n"); + return HALMAC_RET_MALLOC_FAIL; + } + PLTFM_MEMSET(super_usb_mask, 0x00, mask_size); + + super_usb_map = (u8 *)PLTFM_MALLOC(map_size); + if (!super_usb_map) { + PLTFM_MSG_ERR("[ERR]malloc updated map\n"); + PLTFM_FREE(super_usb_mask, mask_size); + return HALMAC_RET_MALLOC_FAIL; + } + PLTFM_MEMSET(super_usb_map, 0xFF, map_size); + + status = super_usb_efuse_parser_88xx(adapter, adapter->efuse_map, + super_usb_map, super_usb_mask); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_FREE(super_usb_mask, mask_size); + PLTFM_FREE(super_usb_map, map_size); + return HALMAC_RET_EEPROM_PARSING_FAIL; + } + + for (addr = SUPER_USB_ZONE0_START; + addr <= SUPER_USB_ZONE0_END; addr++) { + status = log_efuse_re_pg_chk_88xx(adapter, super_usb_mask, addr, + re_pg); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_FREE(super_usb_mask, mask_size); + PLTFM_FREE(super_usb_map, map_size); + return status; + } + if (*re_pg == 1) { + PLTFM_FREE(super_usb_mask, mask_size); + PLTFM_FREE(super_usb_map, map_size); + return status; + } + } + + for (addr = SUPER_USB_ZONE1_START; + addr <= SUPER_USB_ZONE1_END; addr++) { + status = log_efuse_re_pg_chk_88xx(adapter, super_usb_mask, addr, + re_pg); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_FREE(super_usb_mask, mask_size); + PLTFM_FREE(super_usb_map, map_size); + return status; + } + if (*re_pg == 1) { + PLTFM_FREE(super_usb_mask, mask_size); + PLTFM_FREE(super_usb_map, map_size); + return status; + } + } + + *re_pg = 0; + + PLTFM_FREE(super_usb_mask, mask_size); + PLTFM_FREE(super_usb_map, map_size); + + return status; +} + +static enum halmac_ret_status +super_usb_re_pg_chk_88xx(struct halmac_adapter *adapter, u8 *phy_map, u8 *re_pg) +{ + u32 size = adapter->hw_cfg_info.eeprom_size; + u32 addr; + u8 *map = NULL; + enum halmac_ret_status status = HALMAC_RET_SUCCESS; + + map = (u8 *)PLTFM_MALLOC(size); + if (!map) { + PLTFM_MSG_ERR("[ERR]malloc map\n"); + return HALMAC_RET_MALLOC_FAIL; + } + PLTFM_MEMSET(map, 0xFF, size); + + status = eeprom_mask_parser_88xx(adapter, phy_map, map); + if (status != HALMAC_RET_SUCCESS) { + PLTFM_FREE(map, size); + return status; + } + + for (addr = SUPER_USB_RE_PG_CK_ZONE0_START; + addr <= SUPER_USB_RE_PG_CK_ZONE0_END; addr++) { + if (*(map + addr) != 0xFF) { + PLTFM_FREE(map, size); + *re_pg = 1; + return status; + } + } + + *re_pg = 0; + + PLTFM_FREE(map, size); + + return status; +} #endif /* HALMAC_88XX_SUPPORT */ diff --git a/hal/halmac/halmac_88xx/halmac_efuse_88xx.h b/hal/halmac/halmac_88xx/halmac_efuse_88xx.h index 7263e33..0e20f2b 100644 --- a/hal/halmac/halmac_88xx/halmac_efuse_88xx.h +++ b/hal/halmac/halmac_88xx/halmac_efuse_88xx.h @@ -68,6 +68,10 @@ read_logical_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 *value); enum halmac_ret_status write_log_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value); +enum halmac_ret_status +write_log_efuse_word_88xx(struct halmac_adapter *adapter, u32 offset, + u16 value); + enum halmac_ret_status pg_efuse_by_map_88xx(struct halmac_adapter *adapter, struct halmac_pg_efuse_info *info, diff --git a/hal/halmac/halmac_88xx/halmac_gpio_88xx.c b/hal/halmac/halmac_88xx/halmac_gpio_88xx.c index 3d69885..7edc16f 100644 --- a/hal/halmac/halmac_88xx/halmac_gpio_88xx.c +++ b/hal/halmac/halmac_88xx/halmac_gpio_88xx.c @@ -241,6 +241,23 @@ pinmux_parser_88xx(struct halmac_adapter *adapter, cur_list++; } + switch (*cur_func) { + case HALMAC_BT_DPDT_SEL: + *cur_func = (HALMAC_REG_R8(REG_LED_CFG + 3) & BIT(0)) ? + HALMAC_WL_DPDT_SEL : HALMAC_BT_DPDT_SEL; + break; + case HALMAC_BT_PAPE_SEL: + *cur_func = (HALMAC_REG_R8(REG_PAD_CTRL1 + 3) & BIT(5)) ? + HALMAC_WL_PAPE_SEL : HALMAC_BT_PAPE_SEL; + break; + case HALMAC_BT_LNAON_SEL: + *cur_func = (HALMAC_REG_R8(REG_PAD_CTRL1 + 3) & BIT(4)) ? + HALMAC_WL_LNAON_SEL : HALMAC_BT_LNAON_SEL; + break; + default: + break; + } + *state = HALMAC_GPIO_CFG_STATE_IDLE; if (i == size) diff --git a/hal/halmac/halmac_88xx/halmac_init_88xx.c b/hal/halmac/halmac_88xx/halmac_init_88xx.c index 3cd82ae..1cdd0e1 100644 --- a/hal/halmac/halmac_88xx/halmac_init_88xx.c +++ b/hal/halmac/halmac_88xx/halmac_init_88xx.c @@ -231,6 +231,7 @@ mount_api_88xx(struct halmac_adapter *adapter) api->halmac_get_logical_efuse_size = get_log_efuse_size_88xx; api->halmac_write_logical_efuse = write_log_efuse_88xx; + api->halmac_write_logical_efuse_word = write_log_efuse_word_88xx; api->halmac_read_logical_efuse = read_logical_efuse_88xx; api->halmac_write_wifi_phy_efuse = write_wifi_phy_efuse_88xx; @@ -269,6 +270,7 @@ mount_api_88xx(struct halmac_adapter *adapter) api->halmac_drop_scan_packet = drop_scan_packet_88xx; api->halmac_start_iqk = start_iqk_88xx; + api->halmac_start_dpk = start_dpk_88xx; api->halmac_ctrl_pwr_tracking = ctrl_pwr_tracking_88xx; api->halmac_psd = psd_88xx; api->halmac_cfg_la_mode = cfg_la_mode_88xx; @@ -588,6 +590,9 @@ reset_ofld_feature_88xx(struct halmac_adapter *adapter, state->fw_snding_state.proc_status = HALMAC_CMD_PROCESS_IDLE; state->fw_snding_state.cmd_cnstr_state = HALMAC_CMD_CNSTR_IDLE; break; + case HALMAC_FEATURE_DPK: + state->dpk_state.proc_status = HALMAC_CMD_PROCESS_IDLE; + break; case HALMAC_FEATURE_ALL: state->cfg_param_state.proc_status = HALMAC_CMD_PROCESS_IDLE; state->cfg_param_state.cmd_cnstr_state = HALMAC_CMD_CNSTR_IDLE; @@ -673,14 +678,13 @@ verify_io_88xx(struct halmac_adapter *adapter) enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS; if (adapter->intf == HALMAC_INTERFACE_SDIO) { +#if HALMAC_SDIO_SUPPORT offset = REG_PAGE5_DUMMY; if (0 == (offset & 0xFFFF0000)) offset |= WLAN_IOREG_OFFSET; -#if HALMAC_SDIO_SUPPORT + ret_status = cnv_to_sdio_bus_offset_88xx(adapter, &offset); -#else - return HALMAC_RET_WRONG_INTF; -#endif + /* Verify CMD52 R/W */ wvalue8 = 0xab; PLTFM_SDIO_CMD52_W(offset, wvalue8); @@ -727,6 +731,9 @@ verify_io_88xx(struct halmac_adapter *adapter) PLTFM_MSG_ERR("[ERR]cmd52 is used\n"); ret_status = HALMAC_RET_PLATFORM_API_INCORRECT; } +#else + return HALMAC_RET_WRONG_INTF; +#endif } else { wvalue32 = 0x77665511; PLTFM_REG_W32(REG_PAGE5_DUMMY, wvalue32); diff --git a/hal/halmac/halmac_88xx/halmac_usb_88xx.c b/hal/halmac/halmac_88xx/halmac_usb_88xx.c index 05c1d6d..f87ad99 100644 --- a/hal/halmac/halmac_88xx/halmac_usb_88xx.c +++ b/hal/halmac/halmac_88xx/halmac_usb_88xx.c @@ -25,6 +25,9 @@ enum usb_burst_size { USB_BURST_SIZE_UNDEFINE = 0x7F, }; +#define USB_PHY_PAGE0 0x9B +#define USB_PHY_PAGE1 0xBB + /** * init_usb_cfg_88xx() - init USB * @adapter : the adapter of halmac @@ -522,4 +525,16 @@ en_ref_autok_usb_88xx(struct halmac_adapter *adapter, u8 en) { return HALMAC_RET_NOT_SUPPORT; } +enum halmac_ret_status +usb_page_switch_88xx(struct halmac_adapter *adapter, u8 speed, u8 page) +{ + if (speed == HAL_INTF_PHY_USB3) + return HALMAC_RET_SUCCESS; + if (page == 0) + usbphy_write_88xx(adapter, USB_REG_PAGE, USB_PHY_PAGE0, speed); + else + usbphy_write_88xx(adapter, USB_REG_PAGE, USB_PHY_PAGE1, speed); + + return HALMAC_RET_SUCCESS; +} #endif /* HALMAC_88XX_SUPPORT */ diff --git a/hal/halmac/halmac_88xx/halmac_usb_88xx.h b/hal/halmac/halmac_88xx/halmac_usb_88xx.h index 29e32fe..8e53793 100644 --- a/hal/halmac/halmac_88xx/halmac_usb_88xx.h +++ b/hal/halmac/halmac_88xx/halmac_usb_88xx.h @@ -85,6 +85,9 @@ usbphy_read_88xx(struct halmac_adapter *adapter, u8 addr, u8 speed); enum halmac_ret_status en_ref_autok_usb_88xx(struct halmac_adapter *adapter, u8 en); +enum halmac_ret_status +usb_page_switch_88xx(struct halmac_adapter *adapter, u8 speed, u8 page); + #endif /* HALMAC_88XX_SUPPORT */ #endif/* _HALMAC_API_88XX_USB_H_ */ diff --git a/hal/halmac/halmac_api.c b/hal/halmac/halmac_api.c index 3dfd920..d6f531d 100644 --- a/hal/halmac/halmac_api.c +++ b/hal/halmac/halmac_api.c @@ -133,7 +133,7 @@ halmac_init_adapter(void *drv_adapter, struct halmac_platform_api *pltfm_api, "HALMAC_MAJOR_VER = %d\n" "HALMAC_PROTOTYPE_VER = %d\n" "HALMAC_MINOR_VER = %d\n" - "HALMAC_PATCH_VER = %s\n", + "HALMAC_PATCH_VER = %d\n", HALMAC_MAJOR_VER, HALMAC_PROTOTYPE_VER, HALMAC_MINOR_VER, HALMAC_PATCH_VER); diff --git a/hal/halmac/halmac_api.h b/hal/halmac/halmac_api.h index 3d8290d..3c1b864 100644 --- a/hal/halmac/halmac_api.h +++ b/hal/halmac/halmac_api.h @@ -16,12 +16,12 @@ #ifndef _HALMAC_API_H_ #define _HALMAC_API_H_ -#define HALMAC_SVN_VER "11692M" +#define HALMAC_SVN_VER "55772M" #define HALMAC_MAJOR_VER 1 #define HALMAC_PROTOTYPE_VER 6 -#define HALMAC_MINOR_VER 5 -#define HALMAC_PATCH_VER "6*" +#define HALMAC_MINOR_VER 6 +#define HALMAC_PATCH_VER 23 #define HALMAC_88XX_SUPPORT (HALMAC_8821C_SUPPORT || \ HALMAC_8822B_SUPPORT || \ diff --git a/hal/halmac/halmac_bit2.h b/hal/halmac/halmac_bit2.h index 97b0d45..29f757b 100644 --- a/hal/halmac/halmac_bit2.h +++ b/hal/halmac/halmac_bit2.h @@ -71499,6 +71499,26 @@ #endif +#if (HALMAC_8822B_SUPPORT) + +/* 2 REG_MACRX_HANG_TIMER_CONTROL (Offset 0x1661) */ + +#define BIT_TIMEOUT_COUNTER_EN BIT(7) +#define BIT_RESET_FIFO_CONTROL BIT(5) + +#define BIT_SHIFT_COUNT_TIMEOUT 0 +#define BIT_MASK_COUNT_TIMEOUT 0x1f +#define BIT_COUNT_TIMEOUT(x) \ + (((x) & BIT_MASK_COUNT_TIMEOUT) << BIT_SHIFT_COUNT_TIMEOUT) +#define BITS_COUNT_TIMEOUT (BIT_MASK_COUNT_TIMEOUT << BIT_SHIFT_COUNT_TIMEOUT) +#define BIT_CLEAR_COUNT_TIMEOUT(x) ((x) & (~BITS_COUNT_TIMEOUT)) +#define BIT_GET_COUNT_TIMEOUT(x) \ + (((x) >> BIT_SHIFT_COUNT_TIMEOUT) & BIT_MASK_COUNT_TIMEOUT) +#define BIT_SET_COUNT_TIMEOUT(x, v) \ + (BIT_CLEAR_COUNT_TIMEOUT(x) | BIT_COUNT_TIMEOUT(v)) + +#endif + #if (HALMAC_8814B_SUPPORT) /* 2 REG_GENERAL_OPTION (Offset 0x1664) */ diff --git a/hal/halmac/halmac_bit_8822b.h b/hal/halmac/halmac_bit_8822b.h index 79afe10..9600e9a 100644 --- a/hal/halmac/halmac_bit_8822b.h +++ b/hal/halmac/halmac_bit_8822b.h @@ -15380,6 +15380,22 @@ #define BIT_CLI0_PWRBIT_OW_EN_8822B BIT(1) #define BIT_CLI0_PWR_ST_8822B BIT(0) +/* 2 REG_MACRX_HANG_TIMER_CONTROL_8822B */ +#define BIT_TIMEOUT_COUNTER_EN_8822B BIT(7) +#define BIT_RESET_FIFO_CONTROL_8822B BIT(5) + +#define BIT_SHIFT_COUNT_TIMEOUT_8822B 0 +#define BIT_MASK_COUNT_TIMEOUT_8822B 0x1f +#define BIT_COUNT_TIMEOUT_8822B(x) \ + (((x) & BIT_MASK_COUNT_TIMEOUT_8822B) << BIT_SHIFT_COUNT_TIMEOUT_8822B) +#define BITS_COUNT_TIMEOUT_8822B \ + (BIT_MASK_COUNT_TIMEOUT_8822B << BIT_SHIFT_COUNT_TIMEOUT_8822B) +#define BIT_CLEAR_COUNT_TIMEOUT_8822B(x) ((x) & (~BITS_COUNT_TIMEOUT_8822B)) +#define BIT_GET_COUNT_TIMEOUT_8822B(x) \ + (((x) >> BIT_SHIFT_COUNT_TIMEOUT_8822B) & BIT_MASK_COUNT_TIMEOUT_8822B) +#define BIT_SET_COUNT_TIMEOUT_8822B(x, v) \ + (BIT_CLEAR_COUNT_TIMEOUT_8822B(x) | BIT_COUNT_TIMEOUT_8822B(v)) + /* 2 REG_WMAC_MU_BF_OPTION_8822B */ #define BIT_WMAC_RESP_NONSTA1_DIS_8822B BIT(7) #define BIT_BIT_WMAC_TXMU_ACKPOLICY_EN_8822B BIT(6) diff --git a/hal/halmac/halmac_fw_offload_c2h_ap.h b/hal/halmac/halmac_fw_offload_c2h_ap.h index 8699864..26d21b4 100644 --- a/hal/halmac/halmac_fw_offload_c2h_ap.h +++ b/hal/halmac/halmac_fw_offload_c2h_ap.h @@ -34,6 +34,7 @@ #define C2H_SUB_CMD_ID_FW_MEM_DUMP_ACK 0X01 #define C2H_SUB_CMD_ID_ACT_SCHEDULE_REQ_ACK 0X1 #define C2H_SUB_CMD_ID_NAN_FUNC_CTRL_ACK 0X1 +#define C2H_SUB_CMD_ID_DPK_ACK 0X1 #define C2H_SUB_CMD_ID_PSD_DATA 0X04 #define C2H_SUB_CMD_ID_EFUSE_DATA 0X05 #define C2H_SUB_CMD_ID_IQK_DATA 0X06 @@ -60,6 +61,7 @@ #define C2H_SUB_CMD_ID_SCAN_CH_NOTIFY 0X22 #define C2H_SUB_CMD_ID_FW_TBTT_RPT 0X23 #define C2H_SUB_CMD_ID_BCN_OFFLOAD 0X24 +#define C2H_SUB_CMD_ID_DPK_DATA 0X25 #define H2C_SUB_CMD_ID_CFG_PARAM_ACK SUB_CMD_ID_CFG_PARAM #define H2C_SUB_CMD_ID_CH_SWITCH_ACK SUB_CMD_ID_CH_SWITCH #define H2C_SUB_CMD_ID_BT_COEX_ACK SUB_CMD_ID_BT_COEX @@ -75,6 +77,7 @@ #define H2C_SUB_CMD_ID_FW_MEM_DUMP_ACK SUB_CMD_ID_FW_MEM_DUMP #define H2C_SUB_CMD_ID_ACT_SCHEDULE_REQ_ACK SUB_CMD_ID_ACT_SCHEDULE_REQ #define H2C_SUB_CMD_ID_NAN_FUNC_CTRL_ACK SUB_CMD_ID_NAN_FUNC_CTRL +#define H2C_SUB_CMD_ID_DPK_ACK SUB_CMD_ID_DPK #define H2C_SUB_CMD_ID_CCX_RPT SUB_CMD_ID_CCX_RPT #define H2C_SUB_CMD_ID_FW_DBG_MSG SUB_CMD_ID_FW_DBG_MSG #define H2C_SUB_CMD_ID_FW_SNDING_ACK SUB_CMD_ID_FW_SNDING @@ -96,6 +99,7 @@ #define H2C_CMD_ID_FW_MEM_DUMP_ACK 0XFF #define H2C_CMD_ID_ACT_SCHEDULE_REQ_ACK 0XFF #define H2C_CMD_ID_NAN_FUNC_CTRL_ACK 0XFF +#define H2C_CMD_ID_DPK_ACK 0XFF #define H2C_CMD_ID_CCX_RPT 0XFF #define H2C_CMD_ID_FW_DBG_MSG 0XFF #define H2C_CMD_ID_FW_SNDING_ACK 0XFF @@ -686,4 +690,83 @@ SET_C2H_FIELD_CLR(c2h_pkt + 0X04, 8, 8, value) #define BCN_OFFLOAD_SET_STATUS_NO_CLR(c2h_pkt, value) \ SET_C2H_FIELD_NO_CLR(c2h_pkt + 0X04, 8, 8, value) +#define DPK_DATA_GET_SEGMENT_ID(c2h_pkt) GET_C2H_FIELD(c2h_pkt + 0X04, 0, 7) +#define DPK_DATA_SET_SEGMENT_ID(c2h_pkt, value) \ + SET_C2H_FIELD_CLR(c2h_pkt + 0X04, 0, 7, value) +#define DPK_DATA_SET_SEGMENT_ID_NO_CLR(c2h_pkt, value) \ + SET_C2H_FIELD_NO_CLR(c2h_pkt + 0X04, 0, 7, value) +#define DPK_DATA_GET_END_SEGMENT(c2h_pkt) GET_C2H_FIELD(c2h_pkt + 0X04, 7, 1) +#define DPK_DATA_SET_END_SEGMENT(c2h_pkt, value) \ + SET_C2H_FIELD_CLR(c2h_pkt + 0X04, 7, 1, value) +#define DPK_DATA_SET_END_SEGMENT_NO_CLR(c2h_pkt, value) \ + SET_C2H_FIELD_NO_CLR(c2h_pkt + 0X04, 7, 1, value) +#define DPK_DATA_GET_SEGMENT_SIZE(c2h_pkt) GET_C2H_FIELD(c2h_pkt + 0X04, 8, 8) +#define DPK_DATA_SET_SEGMENT_SIZE(c2h_pkt, value) \ + SET_C2H_FIELD_CLR(c2h_pkt + 0X04, 8, 8, value) +#define DPK_DATA_SET_SEGMENT_SIZE_NO_CLR(c2h_pkt, value) \ + SET_C2H_FIELD_NO_CLR(c2h_pkt + 0X04, 8, 8, value) +#define DPK_DATA_GET_TOTAL_SIZE(c2h_pkt) GET_C2H_FIELD(c2h_pkt + 0X04, 16, 16) +#define DPK_DATA_SET_TOTAL_SIZE(c2h_pkt, value) \ + SET_C2H_FIELD_CLR(c2h_pkt + 0X04, 16, 16, value) +#define DPK_DATA_SET_TOTAL_SIZE_NO_CLR(c2h_pkt, value) \ + SET_C2H_FIELD_NO_CLR(c2h_pkt + 0X04, 16, 16, value) +#define DPK_DATA_GET_H2C_SEQ(c2h_pkt) GET_C2H_FIELD(c2h_pkt + 0X08, 0, 16) +#define DPK_DATA_SET_H2C_SEQ(c2h_pkt, value) \ + SET_C2H_FIELD_CLR(c2h_pkt + 0X08, 0, 16, value) +#define DPK_DATA_SET_H2C_SEQ_NO_CLR(c2h_pkt, value) \ + SET_C2H_FIELD_NO_CLR(c2h_pkt + 0X08, 0, 16, value) +#define DPK_DATA_GET_PATH0_OK(c2h_pkt) GET_C2H_FIELD(c2h_pkt + 0X08, 16, 8) +#define DPK_DATA_SET_PATH0_OK(c2h_pkt, value) \ + SET_C2H_FIELD_CLR(c2h_pkt + 0X08, 16, 8, value) +#define DPK_DATA_SET_PATH0_OK_NO_CLR(c2h_pkt, value) \ + SET_C2H_FIELD_NO_CLR(c2h_pkt + 0X08, 16, 8, value) +#define DPK_DATA_GET_PATH1_OK(c2h_pkt) GET_C2H_FIELD(c2h_pkt + 0X08, 24, 8) +#define DPK_DATA_SET_PATH1_OK(c2h_pkt, value) \ + SET_C2H_FIELD_CLR(c2h_pkt + 0X08, 24, 8, value) +#define DPK_DATA_SET_PATH1_OK_NO_CLR(c2h_pkt, value) \ + SET_C2H_FIELD_NO_CLR(c2h_pkt + 0X08, 24, 8, value) +#define DPK_DATA_GET_THERM0_S0(c2h_pkt) GET_C2H_FIELD(c2h_pkt + 0X0C, 0, 8) +#define DPK_DATA_SET_THERM0_S0(c2h_pkt, value) \ + SET_C2H_FIELD_CLR(c2h_pkt + 0X0C, 0, 8, value) +#define DPK_DATA_SET_THERM0_S0_NO_CLR(c2h_pkt, value) \ + SET_C2H_FIELD_NO_CLR(c2h_pkt + 0X0C, 0, 8, value) +#define DPK_DATA_GET_THERM0_S1(c2h_pkt) GET_C2H_FIELD(c2h_pkt + 0X0C, 8, 8) +#define DPK_DATA_SET_THERM0_S1(c2h_pkt, value) \ + SET_C2H_FIELD_CLR(c2h_pkt + 0X0C, 8, 8, value) +#define DPK_DATA_SET_THERM0_S1_NO_CLR(c2h_pkt, value) \ + SET_C2H_FIELD_NO_CLR(c2h_pkt + 0X0C, 8, 8, value) +#define DPK_DATA_GET_THERM1_S0(c2h_pkt) GET_C2H_FIELD(c2h_pkt + 0X0C, 16, 8) +#define DPK_DATA_SET_THERM1_S0(c2h_pkt, value) \ + SET_C2H_FIELD_CLR(c2h_pkt + 0X0C, 16, 8, value) +#define DPK_DATA_SET_THERM1_S0_NO_CLR(c2h_pkt, value) \ + SET_C2H_FIELD_NO_CLR(c2h_pkt + 0X0C, 16, 8, value) +#define DPK_DATA_GET_THERM1_S1(c2h_pkt) GET_C2H_FIELD(c2h_pkt + 0X0C, 24, 8) +#define DPK_DATA_SET_THERM1_S1(c2h_pkt, value) \ + SET_C2H_FIELD_CLR(c2h_pkt + 0X0C, 24, 8, value) +#define DPK_DATA_SET_THERM1_S1_NO_CLR(c2h_pkt, value) \ + SET_C2H_FIELD_NO_CLR(c2h_pkt + 0X0C, 24, 8, value) +#define DPK_DATA_GET_THERM_DELTA0_S0(c2h_pkt) \ + GET_C2H_FIELD(c2h_pkt + 0X10, 0, 8) +#define DPK_DATA_SET_THERM_DELTA0_S0(c2h_pkt, value) \ + SET_C2H_FIELD_CLR(c2h_pkt + 0X10, 0, 8, value) +#define DPK_DATA_SET_THERM_DELTA0_S0_NO_CLR(c2h_pkt, value) \ + SET_C2H_FIELD_NO_CLR(c2h_pkt + 0X10, 0, 8, value) +#define DPK_DATA_GET_THERM_DELTA0_S1(c2h_pkt) \ + GET_C2H_FIELD(c2h_pkt + 0X10, 8, 8) +#define DPK_DATA_SET_THERM_DELTA0_S1(c2h_pkt, value) \ + SET_C2H_FIELD_CLR(c2h_pkt + 0X10, 8, 8, value) +#define DPK_DATA_SET_THERM_DELTA0_S1_NO_CLR(c2h_pkt, value) \ + SET_C2H_FIELD_NO_CLR(c2h_pkt + 0X10, 8, 8, value) +#define DPK_DATA_GET_THERM_DELTA1_S0(c2h_pkt) \ + GET_C2H_FIELD(c2h_pkt + 0X10, 16, 8) +#define DPK_DATA_SET_THERM_DELTA1_S0(c2h_pkt, value) \ + SET_C2H_FIELD_CLR(c2h_pkt + 0X10, 16, 8, value) +#define DPK_DATA_SET_THERM_DELTA1_S0_NO_CLR(c2h_pkt, value) \ + SET_C2H_FIELD_NO_CLR(c2h_pkt + 0X10, 16, 8, value) +#define DPK_DATA_GET_THERM_DELTA1_S1(c2h_pkt) \ + GET_C2H_FIELD(c2h_pkt + 0X10, 24, 8) +#define DPK_DATA_SET_THERM_DELTA1_S1(c2h_pkt, value) \ + SET_C2H_FIELD_CLR(c2h_pkt + 0X10, 24, 8, value) +#define DPK_DATA_SET_THERM_DELTA1_S1_NO_CLR(c2h_pkt, value) \ + SET_C2H_FIELD_NO_CLR(c2h_pkt + 0X10, 24, 8, value) #endif diff --git a/hal/halmac/halmac_fw_offload_c2h_nic.h b/hal/halmac/halmac_fw_offload_c2h_nic.h index df88107..0b4aead 100644 --- a/hal/halmac/halmac_fw_offload_c2h_nic.h +++ b/hal/halmac/halmac_fw_offload_c2h_nic.h @@ -34,6 +34,7 @@ #define C2H_SUB_CMD_ID_FW_MEM_DUMP_ACK 0X01 #define C2H_SUB_CMD_ID_ACT_SCHEDULE_REQ_ACK 0X1 #define C2H_SUB_CMD_ID_NAN_FUNC_CTRL_ACK 0X1 +#define C2H_SUB_CMD_ID_DPK_ACK 0X1 #define C2H_SUB_CMD_ID_PSD_DATA 0X04 #define C2H_SUB_CMD_ID_EFUSE_DATA 0X05 #define C2H_SUB_CMD_ID_IQK_DATA 0X06 @@ -60,6 +61,7 @@ #define C2H_SUB_CMD_ID_SCAN_CH_NOTIFY 0X22 #define C2H_SUB_CMD_ID_FW_TBTT_RPT 0X23 #define C2H_SUB_CMD_ID_BCN_OFFLOAD 0X24 +#define C2H_SUB_CMD_ID_DPK_DATA 0X25 #define H2C_SUB_CMD_ID_CFG_PARAM_ACK SUB_CMD_ID_CFG_PARAM #define H2C_SUB_CMD_ID_CH_SWITCH_ACK SUB_CMD_ID_CH_SWITCH #define H2C_SUB_CMD_ID_BT_COEX_ACK SUB_CMD_ID_BT_COEX @@ -75,6 +77,7 @@ #define H2C_SUB_CMD_ID_FW_MEM_DUMP_ACK SUB_CMD_ID_FW_MEM_DUMP #define H2C_SUB_CMD_ID_ACT_SCHEDULE_REQ_ACK SUB_CMD_ID_ACT_SCHEDULE_REQ #define H2C_SUB_CMD_ID_NAN_FUNC_CTRL_ACK SUB_CMD_ID_NAN_FUNC_CTRL +#define H2C_SUB_CMD_ID_DPK_ACK SUB_CMD_ID_DPK #define H2C_SUB_CMD_ID_CCX_RPT SUB_CMD_ID_CCX_RPT #define H2C_SUB_CMD_ID_FW_DBG_MSG SUB_CMD_ID_FW_DBG_MSG #define H2C_SUB_CMD_ID_FW_SNDING_ACK SUB_CMD_ID_FW_SNDING @@ -96,6 +99,7 @@ #define H2C_CMD_ID_FW_MEM_DUMP_ACK 0XFF #define H2C_CMD_ID_ACT_SCHEDULE_REQ_ACK 0XFF #define H2C_CMD_ID_NAN_FUNC_CTRL_ACK 0XFF +#define H2C_CMD_ID_DPK_ACK 0XFF #define H2C_CMD_ID_CCX_RPT 0XFF #define H2C_CMD_ID_FW_DBG_MSG 0XFF #define H2C_CMD_ID_FW_SNDING_ACK 0XFF @@ -501,4 +505,55 @@ #define BCN_OFFLOAD_GET_STATUS(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 8, 8) #define BCN_OFFLOAD_SET_STATUS(c2h_pkt, value) \ SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 8, 8, value) +#define DPK_DATA_GET_SEGMENT_ID(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 7) +#define DPK_DATA_SET_SEGMENT_ID(c2h_pkt, value) \ + SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 7, value) +#define DPK_DATA_GET_END_SEGMENT(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 7, 1) +#define DPK_DATA_SET_END_SEGMENT(c2h_pkt, value) \ + SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 7, 1, value) +#define DPK_DATA_GET_SEGMENT_SIZE(c2h_pkt) \ + LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 8, 8) +#define DPK_DATA_SET_SEGMENT_SIZE(c2h_pkt, value) \ + SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 8, 8, value) +#define DPK_DATA_GET_TOTAL_SIZE(c2h_pkt) \ + LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 16, 16) +#define DPK_DATA_SET_TOTAL_SIZE(c2h_pkt, value) \ + SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 16, 16, value) +#define DPK_DATA_GET_H2C_SEQ(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 0, 16) +#define DPK_DATA_SET_H2C_SEQ(c2h_pkt, value) \ + SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 0, 16, value) +#define DPK_DATA_GET_PATH0_OK(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 16, 8) +#define DPK_DATA_SET_PATH0_OK(c2h_pkt, value) \ + SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 16, 8, value) +#define DPK_DATA_GET_PATH1_OK(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 24, 8) +#define DPK_DATA_SET_PATH1_OK(c2h_pkt, value) \ + SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 24, 8, value) +#define DPK_DATA_GET_THERM0_S0(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 0, 8) +#define DPK_DATA_SET_THERM0_S0(c2h_pkt, value) \ + SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 0, 8, value) +#define DPK_DATA_GET_THERM0_S1(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 8, 8) +#define DPK_DATA_SET_THERM0_S1(c2h_pkt, value) \ + SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 8, 8, value) +#define DPK_DATA_GET_THERM1_S0(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 16, 8) +#define DPK_DATA_SET_THERM1_S0(c2h_pkt, value) \ + SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 16, 8, value) +#define DPK_DATA_GET_THERM1_S1(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 24, 8) +#define DPK_DATA_SET_THERM1_S1(c2h_pkt, value) \ + SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 24, 8, value) +#define DPK_DATA_GET_THERM_DELTA0_S0(c2h_pkt) \ + LE_BITS_TO_4BYTE(c2h_pkt + 0X10, 0, 8) +#define DPK_DATA_SET_THERM_DELTA0_S0(c2h_pkt, value) \ + SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X10, 0, 8, value) +#define DPK_DATA_GET_THERM_DELTA0_S1(c2h_pkt) \ + LE_BITS_TO_4BYTE(c2h_pkt + 0X10, 8, 8) +#define DPK_DATA_SET_THERM_DELTA0_S1(c2h_pkt, value) \ + SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X10, 8, 8, value) +#define DPK_DATA_GET_THERM_DELTA1_S0(c2h_pkt) \ + LE_BITS_TO_4BYTE(c2h_pkt + 0X10, 16, 8) +#define DPK_DATA_SET_THERM_DELTA1_S0(c2h_pkt, value) \ + SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X10, 16, 8, value) +#define DPK_DATA_GET_THERM_DELTA1_S1(c2h_pkt) \ + LE_BITS_TO_4BYTE(c2h_pkt + 0X10, 24, 8) +#define DPK_DATA_SET_THERM_DELTA1_S1(c2h_pkt, value) \ + SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X10, 24, 8, value) #endif diff --git a/hal/halmac/halmac_fw_offload_h2c_ap.h b/hal/halmac/halmac_fw_offload_h2c_ap.h index fbec093..81afe3f 100644 --- a/hal/halmac/halmac_fw_offload_h2c_ap.h +++ b/hal/halmac/halmac_fw_offload_h2c_ap.h @@ -44,6 +44,7 @@ #define CMD_ID_NAN_CHANNEL_PLAN_0 0XFF #define CMD_ID_NAN_CHANNEL_PLAN_1 0XFF #define CMD_ID_NAN_FUNC_CTRL 0XFF +#define CMD_ID_DPK 0XFF #define CATEGORY_H2C_CMD_HEADER 0X00 #define CATEGORY_FW_OFFLOAD_H2C 0X01 #define CATEGORY_FW_ACCESS_TEST 0X01 @@ -74,6 +75,7 @@ #define CATEGORY_NAN_CHANNEL_PLAN_0 0X01 #define CATEGORY_NAN_CHANNEL_PLAN_1 0X01 #define CATEGORY_NAN_FUNC_CTRL 0X01 +#define CATEGORY_DPK 0X01 #define SUB_CMD_ID_FW_ACCESS_TEST 0X00 #define SUB_CMD_ID_CH_SWITCH 0X02 #define SUB_CMD_ID_DUMP_PHYSICAL_EFUSE 0X03 @@ -102,6 +104,7 @@ #define SUB_CMD_ID_NAN_CHANNEL_PLAN_0 0XB4 #define SUB_CMD_ID_NAN_CHANNEL_PLAN_1 0XB5 #define SUB_CMD_ID_NAN_FUNC_CTRL 0XB6 +#define SUB_CMD_ID_DPK 0XB7 #define H2C_CMD_HEADER_GET_CATEGORY(h2c_pkt) GET_H2C_FIELD(h2c_pkt + 0X00, 0, 7) #define H2C_CMD_HEADER_SET_CATEGORY(h2c_pkt, value) \ SET_H2C_FIELD_CLR(h2c_pkt + 0X00, 0, 7, value) diff --git a/hal/halmac/halmac_fw_offload_h2c_nic.h b/hal/halmac/halmac_fw_offload_h2c_nic.h index 5ef1775..4cbc19f 100644 --- a/hal/halmac/halmac_fw_offload_h2c_nic.h +++ b/hal/halmac/halmac_fw_offload_h2c_nic.h @@ -44,6 +44,7 @@ #define CMD_ID_NAN_CHANNEL_PLAN_0 0XFF #define CMD_ID_NAN_CHANNEL_PLAN_1 0XFF #define CMD_ID_NAN_FUNC_CTRL 0XFF +#define CMD_ID_DPK 0XFF #define CATEGORY_H2C_CMD_HEADER 0X00 #define CATEGORY_FW_OFFLOAD_H2C 0X01 #define CATEGORY_FW_ACCESS_TEST 0X01 @@ -74,6 +75,7 @@ #define CATEGORY_NAN_CHANNEL_PLAN_0 0X01 #define CATEGORY_NAN_CHANNEL_PLAN_1 0X01 #define CATEGORY_NAN_FUNC_CTRL 0X01 +#define CATEGORY_DPK 0X01 #define SUB_CMD_ID_FW_ACCESS_TEST 0X00 #define SUB_CMD_ID_CH_SWITCH 0X02 #define SUB_CMD_ID_DUMP_PHYSICAL_EFUSE 0X03 @@ -102,6 +104,7 @@ #define SUB_CMD_ID_NAN_CHANNEL_PLAN_0 0XB4 #define SUB_CMD_ID_NAN_CHANNEL_PLAN_1 0XB5 #define SUB_CMD_ID_NAN_FUNC_CTRL 0XB6 +#define SUB_CMD_ID_DPK 0XB7 #define H2C_CMD_HEADER_GET_CATEGORY(h2c_pkt) \ LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 7) #define H2C_CMD_HEADER_SET_CATEGORY(h2c_pkt, value) \ diff --git a/hal/halmac/halmac_gpio_cmd.h b/hal/halmac/halmac_gpio_cmd.h index 2eb4e19..40efa57 100644 --- a/hal/halmac/halmac_gpio_cmd.h +++ b/hal/halmac/halmac_gpio_cmd.h @@ -83,10 +83,10 @@ #define HALMAC_WL_DPDT_SEL 37 #define HALMAC_BT_PAPE_SEL 38 #define HALMAC_SW_PAPE_SEL 39 -#define HALMAC_WLBT_PAPE_SEL 40 +#define HALMAC_WL_PAPE_SEL 40 #define HALMAC_SW_LNAON_SET 41 #define HALMAC_BT_LNAON_SEL 42 -#define HALMAC_WLBT_LNAON_SEL 43 +#define HALMAC_WL_LNAON_SEL 43 #define HALMAC_SWR_CTRL_EN 44 #define HALMAC_UART_BRIDGE 45 #define HALMAC_BT_I2C 46 diff --git a/hal/halmac/halmac_intf_phy_cmd.h b/hal/halmac/halmac_intf_phy_cmd.h index 4914c7a..be8f626 100644 --- a/hal/halmac/halmac_intf_phy_cmd.h +++ b/hal/halmac/halmac_intf_phy_cmd.h @@ -41,6 +41,8 @@ enum halmac_ip_sel { enum halmac_intf_phy_platform { HALMAC_INTF_PHY_PLATFORM_ALL = BIT(0), HALMAC_INTF_PHY_PLATFORM_ASUS = BIT(1), + HALMAC_INTF_PHY_PLATFORM_LENOVO_V540 = BIT(2), + HALMAC_INTF_PHY_PLATFORM_DHC = BIT(3), HALMAC_INTF_PHY_PLATFORM_FOR_ALL = 0x7FFF, }; diff --git a/hal/halmac/halmac_reg2.h b/hal/halmac/halmac_reg2.h index 7f00c4b..be4b847 100644 --- a/hal/halmac/halmac_reg2.h +++ b/hal/halmac/halmac_reg2.h @@ -8021,6 +8021,12 @@ #endif +#if (HALMAC_8822B_SUPPORT) + +#define REG_MACRX_HANG_TIMER_CONTROL 0x1661 + +#endif + #if (HALMAC_8812F_SUPPORT || HALMAC_8814B_SUPPORT || HALMAC_8822C_SUPPORT) #define REG_GENERAL_OPTION 0x1664 diff --git a/hal/halmac/halmac_reg_8822b.h b/hal/halmac/halmac_reg_8822b.h index 52d27a7..4aea8ff 100644 --- a/hal/halmac/halmac_reg_8822b.h +++ b/hal/halmac/halmac_reg_8822b.h @@ -636,6 +636,7 @@ #define REG_BSSID4_8822B 0x1648 #define REG_NOA_REPORT_8822B 0x1650 #define REG_PWRBIT_SETTING_8822B 0x1660 +#define REG_MACRX_HANG_TIMER_CONTROL_8822B 0x1661 #define REG_WMAC_MU_BF_OPTION_8822B 0x167C #define REG_WMAC_MU_ARB_8822B 0x167E #define REG_WMAC_MU_OPTION_8822B 0x167F diff --git a/hal/halmac/halmac_state_machine.h b/hal/halmac/halmac_state_machine.h index 508c0e2..0cea549 100644 --- a/hal/halmac/halmac_state_machine.h +++ b/hal/halmac/halmac_state_machine.h @@ -128,6 +128,15 @@ struct halmac_iqk_state { u16 seq_num; }; +struct halmac_dpk_state { + enum halmac_cmd_process_status proc_status; + u16 data_size; + u16 seg_size; + u8 *data; + u8 fw_rc; + u16 seq_num; +}; + struct halmac_pwr_tracking_state { enum halmac_cmd_process_status proc_status; u8 fw_rc; @@ -158,6 +167,7 @@ struct halmac_state { struct halmac_scan_pkt_state scan_pkt_state; struct halmac_drop_pkt_state drop_pkt_state; struct halmac_iqk_state iqk_state; + struct halmac_dpk_state dpk_state; struct halmac_pwr_tracking_state pwr_trk_state; struct halmac_psd_state psd_state; struct halmac_fw_snding_state fw_snding_state; diff --git a/hal/halmac/halmac_type.h b/hal/halmac/halmac_type.h index 3a05735..e0950a4 100644 --- a/hal/halmac/halmac_type.h +++ b/hal/halmac/halmac_type.h @@ -546,6 +546,7 @@ enum halmac_ret_status { HALMAC_RET_INIT_XTAL_AAC_FAIL = 0x76, HALMAC_RET_PINMUX_NOT_SUPPORT = 0x77, HALMAC_RET_FWFF_NO_EMPTY = 0x78, + HALMAC_RET_ADR_NOT_ALIGN = 0x79, }; enum halmac_chip_id { @@ -565,6 +566,13 @@ enum halmac_chip_ver { HALMAC_CHIP_VER_D_CUT = 0x03, HALMAC_CHIP_VER_E_CUT = 0x04, HALMAC_CHIP_VER_F_CUT = 0x05, + HALMAC_CHIP_VER_G_CUT = 0x06, + HALMAC_CHIP_VER_H_CUT = 0x07, + HALMAC_CHIP_VER_I_CUT = 0x08, + HALMAC_CHIP_VER_J_CUT = 0x09, + HALMAC_CHIP_VER_K_CUT = 0x0A, + HALMAC_CHIP_VER_L_CUT = 0x0B, + HALMAC_CHIP_VER_M_CUT = 0x0C, HALMAC_CHIP_VER_TEST = 0xFF, HALMAC_CHIP_VER_UNDEFINE = 0x7FFF, }; @@ -1285,6 +1293,7 @@ enum halmac_feature_id { HALMAC_FEATURE_POWER_TRACKING, /* Support */ HALMAC_FEATURE_PSD, /* Support */ HALMAC_FEATURE_FW_SNDING, /* Support */ + HALMAC_FEATURE_DPK, /* Support */ HALMAC_FEATURE_ALL, /* Support, only for reset */ }; @@ -1649,8 +1658,10 @@ enum halmac_api_id { HALMAC_API_CFGSPC_SET_PCIE = 0x9E, HALMAC_API_GET_WATCHER = 0x9F, HALMAC_API_DUMP_LOGICAL_EFUSE_MASK = 0xA0, - HALMAC_API_READ_WIFI_PHY_EFUSE = 0xA1, - HALMAC_API_WRITE_WIFI_PHY_EFUSE = 0xA2, + HALMAC_API_WRITE_LOGICAL_EFUSE_WORD = 0xA1, + HALMAC_API_READ_WIFI_PHY_EFUSE = 0xA2, + HALMAC_API_WRITE_WIFI_PHY_EFUSE = 0xA3, + HALMAC_API_START_DPK = 0xA4, HALMAC_API_MAX }; @@ -1798,6 +1809,8 @@ enum halmac_gpio_func { HALMAC_GPIO_FUNC_S1_TRSW = 23, HALMAC_GPIO_FUNC_S0_TRSWB = 24, HALMAC_GPIO_FUNC_S1_TRSWB = 25, + HALMAC_GPIO_FUNC_ANTSW = 26, + HALMAC_GPIO_FUNC_ANTSWB = 27, HALMAC_GPIO_FUNC_UNDEFINE = 0X7F, }; @@ -2095,6 +2108,8 @@ struct halmac_pinmux_info { u8 s1_pape:1; u8 s0_trswb:1; u8 s1_trswb:1; + u8 antswb:1; + u8 antsw:1; }; struct halmac_ofld_func_info { @@ -2279,6 +2294,9 @@ struct halmac_api { (*halmac_write_logical_efuse)(struct halmac_adapter *adapter, u32 offset, u8 value); enum halmac_ret_status + (*halmac_write_logical_efuse_word)(struct halmac_adapter *adapter, + u32 offset, u16 value); + enum halmac_ret_status (*halmac_read_logical_efuse)(struct halmac_adapter *adapter, u32 offset, u8 *value); enum halmac_ret_status @@ -2423,6 +2441,8 @@ struct halmac_api { (*halmac_start_iqk)(struct halmac_adapter *adapter, struct halmac_iqk_para *param); enum halmac_ret_status + (*halmac_start_dpk)(struct halmac_adapter *adapter); + enum halmac_ret_status (*halmac_ctrl_pwr_tracking)(struct halmac_adapter *adapter, struct halmac_pwr_tracking_option *opt); enum halmac_ret_status diff --git a/hal/halmac/halmac_usb_reg.h b/hal/halmac/halmac_usb_reg.h index f53c243..dd7a016 100644 --- a/hal/halmac/halmac_usb_reg.h +++ b/hal/halmac/halmac_usb_reg.h @@ -16,4 +16,6 @@ #ifndef __HALMAC_USB_REG_H__ #define __HALMAC_USB_REG_H__ +#define USB_REG_PAGE 0xF4 + #endif/* __HALMAC_USB_REG_H__ */ diff --git a/hal/led/hal_led.c b/hal/led/hal_led.c index 2a753f9..95d3daa 100644 --- a/hal/led/hal_led.c +++ b/hal/led/hal_led.c @@ -63,7 +63,7 @@ void rtw_led_set_strategy(_adapter *adapter, u8 strategy) rtw_hal_sw_led_deinit(pri_adapter); #endif - rtw_led_control(pri_adapter, LED_CTL_POWER_OFF); + rtw_led_control(pri_adapter, RTW_LED_OFF); } #ifdef CONFIG_RTW_SW_LED diff --git a/hal/led/hal_usb_led.c b/hal/led/hal_usb_led.c index 915a2d2..1599536 100644 --- a/hal/led/hal_usb_led.c +++ b/hal/led/hal_usb_led.c @@ -48,9 +48,9 @@ SwLedBlink( break; case LED_BLINK_StartToBlink: - if (check_fwstate(pmlmepriv, _FW_LINKED) && check_fwstate(pmlmepriv, WIFI_STATION_STATE)) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) && check_fwstate(pmlmepriv, WIFI_STATION_STATE)) bStopBlinking = _TRUE; - if (check_fwstate(pmlmepriv, _FW_LINKED) && + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) && (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) bStopBlinking = _TRUE; else if (pLed->BlinkTimes == 0) @@ -72,9 +72,9 @@ SwLedBlink( if (bStopBlinking) { if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on) SwLedOff(padapter, pLed); - else if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) && (pLed->bLedOn == _FALSE)) + else if ((check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) && (pLed->bLedOn == _FALSE)) SwLedOn(padapter, pLed); - else if ((check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) && pLed->bLedOn == _TRUE) + else if ((check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE) && pLed->bLedOn == _TRUE) SwLedOff(padapter, pLed); pLed->BlinkTimes = 0; @@ -136,7 +136,7 @@ SwLedBlink1( if (pHalData->CustomerID == RT_CID_DEFAULT) { - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { if (!pLed1->bSWLedCtrl) { SwLedOn(padapter, pLed1); pLed1->bSWLedCtrl = _TRUE; @@ -176,7 +176,7 @@ SwLedBlink1( if (bStopBlinking) { if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on) SwLedOff(padapter, pLed); - else if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { pLed->bLedLinkBlinkInProgress = _TRUE; pLed->CurrLedState = LED_BLINK_NORMAL; if (pLed->bLedOn) @@ -185,7 +185,7 @@ SwLedBlink1( pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); - } else if (check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) { + } else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE) { pLed->bLedNoLinkBlinkInProgress = _TRUE; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) @@ -215,7 +215,7 @@ SwLedBlink1( if (bStopBlinking) { if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on) SwLedOff(padapter, pLed); - else if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { pLed->bLedLinkBlinkInProgress = _TRUE; pLed->CurrLedState = LED_BLINK_NORMAL; if (pLed->bLedOn) @@ -223,7 +223,7 @@ SwLedBlink1( else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); - } else if (check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) { + } else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE) { pLed->bLedNoLinkBlinkInProgress = _TRUE; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) @@ -310,12 +310,12 @@ SwLedBlink2( if (bStopBlinking) { if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on) SwLedOff(padapter, pLed); - else if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { pLed->CurrLedState = RTW_LED_ON; pLed->BlinkingLedState = RTW_LED_ON; SwLedOn(padapter, pLed); - } else if (check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) { + } else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE) { pLed->CurrLedState = RTW_LED_OFF; pLed->BlinkingLedState = RTW_LED_OFF; SwLedOff(padapter, pLed); @@ -341,12 +341,12 @@ SwLedBlink2( if (bStopBlinking) { if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on) SwLedOff(padapter, pLed); - else if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { pLed->CurrLedState = RTW_LED_ON; pLed->BlinkingLedState = RTW_LED_ON; SwLedOn(padapter, pLed); - } else if (check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) { + } else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE) { pLed->CurrLedState = RTW_LED_OFF; pLed->BlinkingLedState = RTW_LED_OFF; SwLedOff(padapter, pLed); @@ -397,13 +397,13 @@ SwLedBlink3( if (bStopBlinking) { if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on) SwLedOff(padapter, pLed); - else if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { pLed->CurrLedState = RTW_LED_ON; pLed->BlinkingLedState = RTW_LED_ON; if (!pLed->bLedOn) SwLedOn(padapter, pLed); - } else if (check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) { + } else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE) { pLed->CurrLedState = RTW_LED_OFF; pLed->BlinkingLedState = RTW_LED_OFF; if (pLed->bLedOn) @@ -431,14 +431,14 @@ SwLedBlink3( if (bStopBlinking) { if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on) SwLedOff(padapter, pLed); - else if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { pLed->CurrLedState = RTW_LED_ON; pLed->BlinkingLedState = RTW_LED_ON; if (!pLed->bLedOn) SwLedOn(padapter, pLed); - } else if (check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) { + } else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE) { pLed->CurrLedState = RTW_LED_OFF; pLed->BlinkingLedState = RTW_LED_OFF; @@ -823,13 +823,13 @@ SwLedBlink7( if (bStopBlinking) { if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on) SwLedOff(Adapter, pLed); - else if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { pLed->CurrLedState = RTW_LED_ON; pLed->BlinkingLedState = RTW_LED_ON; if (!pLed->bLedOn) SwLedOn(Adapter, pLed); - } else if (check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) { + } else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE) { pLed->CurrLedState = RTW_LED_OFF; pLed->BlinkingLedState = RTW_LED_OFF; if (pLed->bLedOn) @@ -957,12 +957,12 @@ SwLedBlink9( if (bStopBlinking) { if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on) SwLedOff(Adapter, pLed); - else if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { pLed->bLedLinkBlinkInProgress = _TRUE; pLed->CurrLedState = LED_BLINK_SLOWLY; _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); - } else if (check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) { + } else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE) { pLed->bLedNoLinkBlinkInProgress = _TRUE; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) @@ -1192,7 +1192,7 @@ SwLedBlink10( if (bStopBlinking) { if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on) SwLedOff(Adapter, pLed); - else if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + else if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { pLed->bLedNoLinkBlinkInProgress = _FALSE; pLed->CurrLedState = RTW_LED_OFF; pLed->BlinkingLedState = RTW_LED_OFF; @@ -1391,7 +1391,7 @@ SwLedBlink11( break; case LED_BLINK_WPS_STOP: /* WPS authentication fail */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else @@ -1684,7 +1684,7 @@ SwLedBlink15( _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_ON_INTERVAL); } else { /* if(pLed->OLDLedState ==LED_NO_LINK_BLINK) */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) { + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE) { pLed->CurrLedState = LED_BLINK_NO_LINK; pLed->BlinkingLedState = RTW_LED_ON; @@ -2029,7 +2029,7 @@ SwLedControlMode1( break; case LED_CTL_SITE_SURVEY: - if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) + if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) ; else if (pLed->bLedScanBlinkInProgress == _FALSE) { if (IS_LED_WPS_BLINKING(pLed)) @@ -2234,7 +2234,7 @@ SwLedControlMode2( case LED_CTL_TX: case LED_CTL_RX: - if ((pLed->bLedBlinkInProgress == _FALSE) && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) { + if ((pLed->bLedBlinkInProgress == _FALSE) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) { if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) return; @@ -2373,7 +2373,7 @@ SwLedControlMode3( case LED_CTL_TX: case LED_CTL_RX: - if ((pLed->bLedBlinkInProgress == _FALSE) && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) { + if ((pLed->bLedBlinkInProgress == _FALSE) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) { if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) return; @@ -2577,7 +2577,7 @@ SwLedControlMode4( break; case LED_CTL_SITE_SURVEY: - if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) + if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) ; else if (pLed->bLedScanBlinkInProgress == _FALSE) { if (IS_LED_WPS_BLINKING(pLed)) @@ -2823,7 +2823,7 @@ SwLedControlMode5( break; case LED_CTL_SITE_SURVEY: - if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) + if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) ; else if (pLed->bLedScanBlinkInProgress == _FALSE) { if (pLed->bLedBlinkInProgress == _TRUE) { @@ -3195,7 +3195,7 @@ SwLedControlMode9( break; case LED_CTL_SITE_SURVEY: - if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) + if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) ; else { /* if(pLed->bLedScanBlinkInProgress ==FALSE) */ if (IS_LED_WPS_BLINKING(pLed)) @@ -3464,7 +3464,7 @@ SwLedControlMode10( break; case LED_CTL_SITE_SURVEY: - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) ; /* don't blink when media connect */ else { /* if(pLed->bLedScanBlinkInProgress ==FALSE) */ if (IS_LED_WPS_BLINKING(pLed) || IS_LED_WPS_BLINKING(pLed1)) @@ -4008,7 +4008,7 @@ SwLedControlMode15( _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->CurrLedState = LED_BLINK_WPS_STOP; - /* if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) */ + /* if(check_fwstate(pmlmepriv, WIFI_ASOC_STATE)== _TRUE) */ { pLed->BlinkingLedState = RTW_LED_ON; @@ -4078,7 +4078,7 @@ SwLedControlMode15( break; case LED_CTL_SITE_SURVEY: - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) return; if (pLed->bLedWPSBlinkInProgress == _TRUE) diff --git a/hal/phydm/ap_makefile.mk b/hal/phydm/ap_makefile.mk index be3ff53..120fc3d 100644 --- a/hal/phydm/ap_makefile.mk +++ b/hal/phydm/ap_makefile.mk @@ -122,7 +122,8 @@ ifeq ($(CONFIG_WLAN_HAL_8812FE),y) _PHYDM_FILES += \ phydm/rtl8812f/halhwimg8812f_bb.o\ phydm/rtl8812f/phydm_regconfig8812f.o\ - phydm/rtl8812f/phydm_hal_api8812f.o + phydm/rtl8812f/phydm_hal_api8812f.o\ + phydm/rtl8812f/phydm_rtl8812f.o endif endif @@ -135,7 +136,8 @@ ifeq ($(CONFIG_WLAN_HAL_8821CE),y) phydm/rtl8821c/halhwimg8821c_bb.o\ phydm/rtl8821c/halhwimg8821c_mac.o\ phydm/rtl8821c/phydm_regconfig8821c.o\ - phydm/rtl8821c/phydm_hal_api8821c.o + phydm/rtl8821c/phydm_hal_api8821c.o\ + phydm/rtl8821c/phydm_rtl8821c.o endif endif @@ -190,6 +192,7 @@ ifeq ($(CONFIG_WLAN_HAL_8814BE),y) _PHYDM_FILES += phydm/halrf/rtl8814b/halrf_8814b.o _PHYDM_FILES += phydm/halrf/rtl8814b/halrf_iqk_8814b.o _PHYDM_FILES += phydm/halrf/rtl8814b/halrf_dpk_8814b.o + _PHYDM_FILES += phydm/halrf/rtl8814b/halrf_txgapk_8814b.o _PHYDM_FILES += phydm/halrf/rtl8814b/halrf_rfk_init_8814b.o _PHYDM_FILES += phydm/halrf/rtl8814b/halhwimg8814b_rf.o ifeq ($(CONFIG_RTL_ODM_WLAN_DRIVER),y) @@ -197,6 +200,7 @@ ifeq ($(CONFIG_WLAN_HAL_8814BE),y) phydm/rtl8814b/phydm_hal_api8814b.o\ phydm/rtl8814b/halhwimg8814b_bb.o\ phydm/rtl8814b/phydm_regconfig8814b.o \ + phydm/rtl8814b/phydm_extraagc8814b.o \ phydm/halrf/rtl8814b/halrf_8814b.o endif endif @@ -214,7 +218,20 @@ ifeq ($(CONFIG_WLAN_HAL_8197G),y) phydm/rtl8197g/halhwimg8197g_bb.o\ phydm/rtl8197g/halhwimg8197g_mac.o\ phydm/rtl8197g/phydm_regconfig8197g.o \ + phydm/rtl8197g/phydm_rtl8197g.o \ phydm/halrf/rtl8197g/halrf_8197g.o endif endif - +ifeq ($(CONFIG_WLAN_HAL_8723FE),y) + _PHYDM_FILES += phydm/halrf/rtl8723f/halrf_8723f.o + _PHYDM_FILES += phydm/halrf/rtl8723f/halrf_iqk_8723f.o + _PHYDM_FILES += phydm/halrf/rtl8723f/halrf_dpk_8723f.o + _PHYDM_FILES += phydm/halrf/rtl8723f/halrf_rfk_init_8723f.o + _PHYDM_FILES += phydm/halrf/rtl8723f/halhwimg8723f_rf.o + ifeq ($(CONFIG_RTL_ODM_WLAN_DRIVER),y) + _PHYDM_FILES += \ + phydm/rtl8723f/halhwimg8723f_bb.o\ + phydm/rtl8723f/phydm_regconfig8723f.o\ + phydm/rtl8723f/phydm_hal_api8723f.o + endif +endif diff --git a/hal/phydm/halrf/halphyrf_ap.c b/hal/phydm/halrf/halphyrf_ap.c index 775b420..857f019 100644 --- a/hal/phydm/halrf/halphyrf_ap.c +++ b/hal/phydm/halrf/halphyrf_ap.c @@ -433,17 +433,25 @@ odm_txpowertracking_callback_thermal_meter_jaguar_series4(void *dm_void) priv->pmib->dot11RFEntry.thermal[i] == 0x0) return; } - if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8812F | ODM_RTL8197G)) { + if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8812F)) { for (i = 0; i < c.rf_path_count; i++) thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0x7e); /* 0x42: RF Reg[6:1] Thermal Trim*/ + } else if (dm->support_ic_type == ODM_RTL8197G) { + for (i = 0; i < c.rf_path_count; i++) + thermal_value[i] = (u8)odm_get_rf_reg(dm, i, RF_0xf6, 0x7E000); } else { for (i = 0; i < c.rf_path_count; i++) { thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */ - thermal_value_temp[i] = (s8)thermal_value[i] + phydm_get_thermal_offset(dm); - - RF_DBG(dm, DBG_RF_TX_PWR_TRACK, - "thermal_value_temp[%d](%d) = thermal_value[%d](%d) + power_time_thermal(%d)\n", i, thermal_value_temp[i], i, thermal_value[i], phydm_get_thermal_offset(dm)); + if (dm->support_ic_type == ODM_RTL8814B) { + thermal_value_temp[i] = (s8)thermal_value[i] + phydm_get_multi_thermal_offset(dm, i); + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "thermal_value_temp[%d](%d) = thermal_value[%d](%d) + multi_thermal_trim(%d)\n", i, thermal_value_temp[i], i, thermal_value[i], phydm_get_multi_thermal_offset(dm, i)); + } else { + thermal_value_temp[i] = (s8)thermal_value[i] + phydm_get_thermal_offset(dm); + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "thermal_value_temp[%d](%d) = thermal_value[%d](%d) + thermal_trim(%d)\n", i, thermal_value_temp[i], i, thermal_value[i], phydm_get_thermal_offset(dm)); + } if (thermal_value_temp[i] > 63) thermal_value[i] = 63; @@ -591,7 +599,7 @@ odm_txpowertracking_callback_thermal_meter_jaguar_series4(void *dm_void) #endif /* Wait sacn to do IQK by RF Jenyu*/ - if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) { + if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden) && (dm->is_linked || *dm->mp_mode)) { /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/ if (delta_IQK >= c.threshold_iqk) { cali_info->thermal_value_iqk = thermal_value[RF_PATH_A]; @@ -838,9 +846,9 @@ odm_txpowertracking_callback_thermal_meter_jaguar_series3( if (GET_CHIP_VER(priv) == VERSION_8197F) { for (p = RF_PATH_A; p < c.rf_path_count; p++) (*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, 0); - //} else if (GET_CHIP_VER(priv) == VERSION_8192F) { - // for (p = RF_PATH_A; p < c.rf_path_count; p++) - // (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0); + } else if (GET_CHIP_VER(priv) == VERSION_8192F) { + for (p = RF_PATH_A; p < c.rf_path_count; p++) + (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0); } else if (GET_CHIP_VER(priv) == VERSION_8822B) { for (p = RF_PATH_A; p < c.rf_path_count; p++) (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0); @@ -850,15 +858,18 @@ odm_txpowertracking_callback_thermal_meter_jaguar_series3( } else if (GET_CHIP_VER(priv) == VERSION_8198F) { for (p = RF_PATH_A; p < c.rf_path_count; p++) (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0); + } else if (GET_CHIP_VER(priv) == VERSION_8192F) { + for (p = RF_PATH_A; p < c.rf_path_count; p++) + (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0); } } else { RF_DBG(dm, DBG_RF_TX_PWR_TRACK, ">>> decrese power --->\n"); if (GET_CHIP_VER(priv) == VERSION_8197F) { for (p = RF_PATH_A; p < c.rf_path_count; p++) (*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, 0); - //} else if (GET_CHIP_VER(priv) == VERSION_8192F) { - // for (p = RF_PATH_A; p < c.rf_path_count; p++) - // (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0); + } else if (GET_CHIP_VER(priv) == VERSION_8192F) { + for (p = RF_PATH_A; p < c.rf_path_count; p++) + (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0); } else if (GET_CHIP_VER(priv) == VERSION_8822B) { for (p = RF_PATH_A; p < c.rf_path_count; p++) (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0); @@ -868,13 +879,16 @@ odm_txpowertracking_callback_thermal_meter_jaguar_series3( } else if (GET_CHIP_VER(priv) == VERSION_8198F) { for (p = RF_PATH_A; p < c.rf_path_count; p++) (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0); + } else if (GET_CHIP_VER(priv) == VERSION_8192F) { + for (p = RF_PATH_A; p < c.rf_path_count; p++) + (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0); } } } #endif if (GET_CHIP_VER(priv) != VERSION_8198F) { - if ((delta_IQK >= c.threshold_iqk) && (!iqk_info->rfk_forbidden)) { + if ((delta_IQK >= c.threshold_iqk) && (!iqk_info->rfk_forbidden) && dm->is_linked) { RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk); dm->rf_calibrate_info.thermal_value_iqk = thermal_value; if (!(dm->support_ic_type & ODM_RTL8197F)) { diff --git a/hal/phydm/halrf/halphyrf_ap.h b/hal/phydm/halrf/halphyrf_ap.h index b66bcbc..8cc2797 100644 --- a/hal/phydm/halrf/halphyrf_ap.h +++ b/hal/phydm/halrf/halphyrf_ap.h @@ -52,6 +52,7 @@ #if (RTL8814B_SUPPORT == 1) #include "halrf/rtl8814b/halrf_iqk_8814b.h" #include "halrf/rtl8814b/halrf_dpk_8814b.h" + #include "halrf/rtl8814b/halrf_txgapk_8814b.h" #endif #if (RTL8197G_SUPPORT == 1) diff --git a/hal/phydm/halrf/halphyrf_ce.c b/hal/phydm/halrf/halphyrf_ce.c index 5ff9d74..6ba9606 100644 --- a/hal/phydm/halrf/halphyrf_ce.c +++ b/hal/phydm/halrf/halphyrf_ce.c @@ -115,6 +115,10 @@ void configure_txpower_track(void *dm_void, struct txpwrtrack_cfg *config) configure_txpower_track_8814b(config); #endif +#if RTL8723F_SUPPORT + if (dm->support_ic_type == ODM_RTL8723F) + configure_txpower_track_8723f(config); +#endif } @@ -376,12 +380,20 @@ void odm_pwrtrk_method(void *dm_void) if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8821 | ODM_RTL8812 | ODM_RTL8723B | ODM_RTL8814A | ODM_RTL8703B | ODM_RTL8188F | - ODM_RTL8822B | ODM_RTL8723D | ODM_RTL8821C | ODM_RTL8710B | + ODM_RTL8822B | ODM_RTL8821C | ODM_RTL8710B | ODM_RTL8192F)) { RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "***Enter PwrTrk MIX_MODE***\n"); for (p = RF_PATH_A; p < c.rf_path_count; p++) (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0); + } else if (dm->support_ic_type & ODM_RTL8723D) { + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "***Enter PwrTrk MIX_MODE***\n"); + p = (u8)odm_get_bb_reg(dm, R_0x948, 0x00000080); + (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0); + /*if open ant_div 0x948=140,do 2 path pwr_track*/ + if (odm_get_bb_reg(dm, R_0x948, 0x00000040)) + (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, 1, 0); } else { RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "***Enter PwrTrk BBSWING_MODE***\n"); @@ -780,7 +792,7 @@ void odm_txpowertracking_callback_thermal_meter(void *adapter) /* Wait sacn to do IQK by RF Jenyu*/ if (!(*dm->is_scan_in_process) && !iqk_info->rfk_forbidden && - !cali_info->is_iqk_in_progress) { + !cali_info->is_iqk_in_progress && dm->is_linked) { if (!(dm->support_ic_type & ODM_RTL8723B)) { /*Delta temperature is equal or larger than 20 Celsius*/ /*When threshold is 8*/ @@ -840,7 +852,7 @@ void odm_txpowertracking_callback_thermal_meter(void *adapter) cali_info->tx_powercount = 0; } -#if (RTL8822C_SUPPORT == 1 || RTL8814B_SUPPORT == 1) +#if (RTL8822C_SUPPORT == 1 || RTL8814B_SUPPORT == 1 || RTL8723F_SUPPORT == 1) void odm_txpowertracking_new_callback_thermal_meter(void *dm_void) { @@ -895,11 +907,17 @@ odm_txpowertracking_new_callback_thermal_meter(void *dm_void) thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0x7e); /* 0x42: RF Reg[6:1] Thermal Trim*/ } else { for (i = 0; i < c.rf_path_count; i++) { - thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10]*/ - thermal_value_temp[i] = (s8)thermal_value[i] + phydm_get_thermal_offset(dm); + thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */ - RF_DBG(dm, DBG_RF_TX_PWR_TRACK, - "thermal_value_temp[%d](%d) = thermal_value[%d](%d) + power_time_thermal(%d)\n", i, thermal_value_temp[i], i, thermal_value[i], phydm_get_thermal_offset(dm)); + if (dm->support_ic_type == ODM_RTL8814B) { + thermal_value_temp[i] = (s8)thermal_value[i] + phydm_get_multi_thermal_offset(dm, i); + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "thermal_value_temp[%d](%d) = thermal_value[%d](%d) + multi_thermal_trim(%d)\n", i, thermal_value_temp[i], i, thermal_value[i], phydm_get_multi_thermal_offset(dm, i)); + } else { + thermal_value_temp[i] = (s8)thermal_value[i] + phydm_get_thermal_offset(dm); + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "thermal_value_temp[%d](%d) = thermal_value[%d](%d) + thermal_trim(%d)\n", i, thermal_value_temp[i], i, thermal_value[i], phydm_get_thermal_offset(dm)); + } if (thermal_value_temp[i] > 63) thermal_value[i] = 63; @@ -1048,7 +1066,7 @@ odm_txpowertracking_new_callback_thermal_meter(void *dm_void) (*c.odm_tx_pwr_track_set_pwr)(dm, tracking_method, p, 0); /* Wait sacn to do IQK by RF Jenyu*/ - if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) { + if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden) && (dm->is_linked || *dm->mp_mode)) { /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/ if (delta_IQK >= c.threshold_iqk) { cali_info->thermal_value_iqk = thermal_value[RF_PATH_A]; diff --git a/hal/phydm/halrf/halphyrf_ce.h b/hal/phydm/halrf/halphyrf_ce.h index 3e2e16a..dcded1e 100644 --- a/hal/phydm/halrf/halphyrf_ce.h +++ b/hal/phydm/halrf/halphyrf_ce.h @@ -49,6 +49,7 @@ #if (RTL8814B_SUPPORT == 1) #include "halrf/rtl8814b/halrf_iqk_8814b.h" #include "halrf/rtl8814b/halrf_dpk_8814b.h" + #include "halrf/rtl8814b/halrf_txgapk_8814b.h" #endif #include "halrf/halrf_powertracking_ce.h" diff --git a/hal/phydm/halrf/halphyrf_iot.c b/hal/phydm/halrf/halphyrf_iot.c index ef55944..16d9084 100644 --- a/hal/phydm/halrf/halphyrf_iot.c +++ b/hal/phydm/halrf/halphyrf_iot.c @@ -125,6 +125,7 @@ odm_txpowertracking_callback_thermal_meter( u8 power_tracking_type = rf->pwt_type; u8 xtal_offset_eanble = 0; s8 thermal_value_temp = 0; + u8 xtal_track_efuse = 0; struct txpwrtrack_cfg c = {0}; @@ -157,9 +158,12 @@ odm_txpowertracking_callback_thermal_meter( #endif /*for Xtal Offset*/ + odm_efuse_one_byte_read(dm, 0xf7, &xtal_track_efuse, false); + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "Read efuse 0xf7=0x%x\n", xtal_track_efuse); + xtal_track_efuse = xtal_track_efuse & 0x3; if (dm->support_ic_type == ODM_RTL8195B || dm->support_ic_type == ODM_RTL8721D || - dm->support_ic_type == ODM_RTL8710C) + (dm->support_ic_type == ODM_RTL8710C && xtal_track_efuse == 0x2)) (*c.get_delta_swing_xtal_table)(dm, (s8 **)&delta_swing_table_xtal_up, (s8 **)&delta_swing_table_xtal_down); @@ -316,7 +320,7 @@ odm_txpowertracking_callback_thermal_meter( /* JJ ADD 20161014 */ if (dm->support_ic_type == ODM_RTL8195B || dm->support_ic_type == ODM_RTL8721D || - dm->support_ic_type == ODM_RTL8710C) { + (dm->support_ic_type == ODM_RTL8710C && xtal_track_efuse == 0x2)) { /*Save xtal_offset from Xtal table*/ cali_info->xtal_offset_last = cali_info->xtal_offset; /*recording last Xtal offset*/ RF_DBG(dm, DBG_RF_TX_PWR_TRACK, @@ -371,7 +375,7 @@ odm_txpowertracking_callback_thermal_meter( if (dm->support_ic_type == ODM_RTL8195B || dm->support_ic_type == ODM_RTL8721D || - dm->support_ic_type == ODM_RTL8710C) { + (dm->support_ic_type == ODM_RTL8710C && xtal_track_efuse == 0x2)) { /*Save xtal_offset from Xtal table*/ cali_info->xtal_offset_last = cali_info->xtal_offset; /*recording last Xtal offset*/ RF_DBG(dm, DBG_RF_TX_PWR_TRACK, @@ -539,9 +543,17 @@ odm_txpowertracking_callback_thermal_meter( } #endif /* JJ ADD 20161014 */ + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "cali_info->xtal_offset_last=%d cali_info->xtal_offset=%d\n", + cali_info->xtal_offset_last, cali_info->xtal_offset); + + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "xtal_offset_eanble=%d cali_info->txpowertrack_control=%d rf->eeprom_thermal=%d xtal_track_efuse=%d\n", + xtal_offset_eanble, cali_info->txpowertrack_control, rf->eeprom_thermal, xtal_track_efuse); + if (dm->support_ic_type == ODM_RTL8195B || dm->support_ic_type == ODM_RTL8721D || - dm->support_ic_type == ODM_RTL8710C) { + (dm->support_ic_type == ODM_RTL8710C && xtal_track_efuse == 0x2)) { if (xtal_offset_eanble != 0 && cali_info->txpowertrack_control && (rf->eeprom_thermal != 0xff)) { RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter Xtal Tracking**********\n"); @@ -559,7 +571,7 @@ odm_txpowertracking_callback_thermal_meter( } #if (!RTL8721D_SUPPORT) /* Wait sacn to do IQK by RF Jenyu*/ - if ((!*dm->is_scan_in_process) && (!iqk_info->rfk_forbidden)) { + if ((!*dm->is_scan_in_process) && (!iqk_info->rfk_forbidden) && (dm->is_linked || *dm->mp_mode)) { /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/ if (delta_IQK >= c.threshold_iqk) { cali_info->thermal_value_iqk = thermal_value; diff --git a/hal/phydm/halrf/halphyrf_win.c b/hal/phydm/halrf/halphyrf_win.c index c9c704c..ff1b856 100644 --- a/hal/phydm/halrf/halphyrf_win.c +++ b/hal/phydm/halrf/halphyrf_win.c @@ -109,6 +109,10 @@ void configure_txpower_track( configure_txpower_track_8814b(config); #endif +#if RTL8723F_SUPPORT + if (dm->support_ic_type == ODM_RTL8723F) + configure_txpower_track_8723f(config); +#endif } @@ -230,8 +234,11 @@ odm_txpowertracking_callback_thermal_meter( rf_calibrate_info.rega24 will be initialized when ODM HW configuring, but MP configures with para files. */ #if (DM_ODM_SUPPORT_TYPE & ODM_WIN) #if (MP_DRIVER == 1) +#ifndef RTL8723F_SUPPORT cali_info->rega24 = 0x090e1317; #endif +#endif + #elif (DM_ODM_SUPPORT_TYPE & ODM_CE) if (*(dm->mp_mode) == true) cali_info->rega24 = 0x090e1317; @@ -700,7 +707,7 @@ odm_txpowertracking_callback_thermal_meter( #if !(DM_ODM_SUPPORT_TYPE & ODM_AP) /* Wait sacn to do IQK by RF Jenyu*/ - if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) { + if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden) && dm->is_linked) { if (!IS_HARDWARE_TYPE_8723B(adapter)) { /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/ if (delta_IQK >= c.threshold_iqk) { @@ -753,7 +760,7 @@ odm_txpowertracking_callback_thermal_meter( cali_info->tx_powercount = 0; } -#if (RTL8822C_SUPPORT == 1 || RTL8814B_SUPPORT == 1) +#if (RTL8822C_SUPPORT == 1 || RTL8814B_SUPPORT == 1 || RTL8723F_SUPPORT == 1) void odm_txpowertracking_new_callback_thermal_meter(void *dm_void) { @@ -808,11 +815,17 @@ odm_txpowertracking_new_callback_thermal_meter(void *dm_void) thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0x7e); /* 0x42: RF Reg[6:1] Thermal Trim*/ } else { for (i = 0; i < c.rf_path_count; i++) { - thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10]*/ - thermal_value_temp[i] = (s8)thermal_value[i] + phydm_get_thermal_offset(dm); + thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */ - RF_DBG(dm, DBG_RF_TX_PWR_TRACK, - "thermal_value_temp[%d](%d) = thermal_value[%d](%d) + power_time_thermal(%d)\n", i, thermal_value_temp[i], i, thermal_value[i], phydm_get_thermal_offset(dm)); + if (dm->support_ic_type == ODM_RTL8814B) { + thermal_value_temp[i] = (s8)thermal_value[i] + phydm_get_multi_thermal_offset(dm, i); + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "thermal_value_temp[%d](%d) = thermal_value[%d](%d) + multi_thermal_trim(%d)\n", i, thermal_value_temp[i], i, thermal_value[i], phydm_get_multi_thermal_offset(dm, i)); + } else { + thermal_value_temp[i] = (s8)thermal_value[i] + phydm_get_thermal_offset(dm); + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "thermal_value_temp[%d](%d) = thermal_value[%d](%d) + thermal_trim(%d)\n", i, thermal_value_temp[i], i, thermal_value[i], phydm_get_thermal_offset(dm)); + } if (thermal_value_temp[i] > 63) thermal_value[i] = 63; @@ -871,7 +884,9 @@ odm_txpowertracking_new_callback_thermal_meter(void *dm_void) cali_info->thermal_value_lck = thermal_value[RF_PATH_A]; /*Use RTLCK, so close power tracking driver LCK*/ - if ((!(dm->support_ic_type & ODM_RTL8814A)) && (!(dm->support_ic_type & ODM_RTL8822B))) { + if ((!(dm->support_ic_type & ODM_RTL8814A)) && + (!(dm->support_ic_type & ODM_RTL8822B)) && + (!(dm->support_ic_type & ODM_RTL8723F))) { if (c.phy_lc_calibrate) (*c.phy_lc_calibrate)(dm); } else @@ -960,7 +975,7 @@ odm_txpowertracking_new_callback_thermal_meter(void *dm_void) (*c.odm_tx_pwr_track_set_pwr)(dm, tracking_method, p, 0); /* Wait sacn to do IQK by RF Jenyu*/ - if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) { + if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden) && (dm->is_linked || *dm->mp_mode)) { /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/ if (delta_IQK >= c.threshold_iqk) { cali_info->thermal_value_iqk = thermal_value[RF_PATH_A]; @@ -1026,26 +1041,39 @@ odm_iq_calibrate( if (*dm->is_fcs_mode_enable) return; #endif + if (dm->is_linked) { + RF_DBG(dm, DBG_RF_IQK, + "interval=%d ch=%d prech=%d scan=%s rfk_f =%s\n", + dm->linked_interval, *dm->channel, dm->pre_channel, + *dm->is_scan_in_process == TRUE ? "TRUE":"FALSE", + iqk_info->rfk_forbidden == TRUE ? "TRUE":"FALSE"); - if ((dm->is_linked) && (!iqk_info->rfk_forbidden)) { - RF_DBG(dm, DBG_RF_IQK, "interval=%d ch=%d prech=%d scan=%s\n", dm->linked_interval, - *dm->channel, dm->pre_channel, *dm->is_scan_in_process == TRUE ? "TRUE":"FALSE"); + if (iqk_info->rfk_forbidden) { + RF_DBG(dm, DBG_RF_IQK, "return by rfk_forbidden\n"); + return; + } + + if (*dm->is_scan_in_process) { + RF_DBG(dm, DBG_RF_IQK, "return by is_scan_in_process\n"); + return; + } if (*dm->channel != dm->pre_channel) { dm->pre_channel = *dm->channel; dm->linked_interval = 0; } - if ((dm->linked_interval < 3) && (!*dm->is_scan_in_process)) + if (dm->linked_interval < 3) dm->linked_interval++; if (dm->linked_interval == 2) PHY_IQCalibrate(adapter, false); - } else + } else { dm->linked_interval = 0; - - RF_DBG(dm, DBG_RF_IQK, "<=%s interval=%d ch=%d prech=%d scan=%s\n", __FUNCTION__, dm->linked_interval, - *dm->channel, dm->pre_channel, *dm->is_scan_in_process == TRUE?"TRUE":"FALSE"); + RF_DBG(dm, DBG_RF_IQK, "is_linked =%s, interval =%d\n", + dm->is_linked == TRUE ? "TRUE":"FALSE", + dm->linked_interval); + } } void phydm_rf_init(struct dm_struct *dm) diff --git a/hal/phydm/halrf/halphyrf_win.h b/hal/phydm/halrf/halphyrf_win.h index e456f18..3769d60 100644 --- a/hal/phydm/halrf/halphyrf_win.h +++ b/hal/phydm/halrf/halphyrf_win.h @@ -40,6 +40,7 @@ #if (RTL8814B_SUPPORT == 1) #include "halrf/rtl8814b/halrf_iqk_8814b.h" + #include "halrf/rtl8814b/halrf_txgapk_8814b.h" #endif enum spur_cal_method { diff --git a/hal/phydm/halrf/halrf.c b/hal/phydm/halrf/halrf.c index 4efcd5c..3d82225 100644 --- a/hal/phydm/halrf/halrf.c +++ b/hal/phydm/halrf/halrf.c @@ -95,7 +95,8 @@ u32 halrf_psd_log2base(u32 val) return result; } - +#if (RTL8822B_SUPPORT == 1 || RTL8821C_SUPPORT == 1 ||\ + RTL8814B_SUPPORT == 1 || RTL8822C_SUPPORT == 1) void halrf_iqk_xym_enable(struct dm_struct *dm, u8 xym_enable) { struct dm_iqk_info *iqk_info = &dm->IQK_info; @@ -276,7 +277,7 @@ void halrf_iqk_xym_dump(void *dm_void) odm_write_4byte(dm, 0x1b1c, tmp2); _iqk_page_switch(dm); } - +#endif void halrf_iqk_info_dump(void *dm_void, u32 *_used, char *output, u32 *_out_len) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -484,6 +485,11 @@ void phydm_get_iqk_cfir(void *dm_void, u8 idx, u8 path, boolean debug) case ODM_RTL8822C: phy_get_iqk_cfir_8822c(dm, idx, path, debug); break; +#endif +#if (RTL8814B_SUPPORT == 1) + case ODM_RTL8814B: + phy_get_iqk_cfir_8814b(dm, idx, path, debug); + break; #endif default: break; @@ -507,6 +513,11 @@ void halrf_iqk_dbg_cfir_backup(void *dm_void) case ODM_RTL8822C: phy_iqk_dbg_cfir_backup_8822c(dm); break; +#endif +#if (RTL8814B_SUPPORT == 1) + case ODM_RTL8814B: + phy_iqk_dbg_cfir_backup_8814b(dm); + break; #endif default: break; @@ -629,6 +640,7 @@ void halrf_do_imr_test(void *dm_void, u8 flag_imr_test) } } +#if (RTL8822B_SUPPORT == 1 || RTL8821C_SUPPORT == 1 || RTL8822C_SUPPORT == 1 || RTL8814B_SUPPORT == 1) void halrf_iqk_debug(void *dm_void, u32 *const dm_value, u32 *_used, char *output, u32 *_out_len) { @@ -669,6 +681,7 @@ void halrf_iqk_debug(void *dm_void, u32 *const dm_value, u32 *_used, else if (dm_value[0] == 0x30) halrf_do_imr_test(dm, (u8)dm_value[1]); } +#endif void halrf_iqk_hwtx_check(void *dm_void, boolean is_check) { @@ -777,6 +790,16 @@ void halrf_rf_lna_setting(void *dm_void, enum halrf_lna_set type) halrf_rf_lna_setting_8821c(dm_void, type); break; #endif +#if (RTL8710C_SUPPORT == 1) + case ODM_RTL8710C: + halrf_rf_lna_setting_8710c(dm_void, type); + break; +#endif +#if (RTL8721D_SUPPORT == 1) + case ODM_RTL8721D: + halrf_rf_lna_setting_8721d(dm, type); + break; +#endif #if (RTL8814B_SUPPORT == 1) case ODM_RTL8814B: break; @@ -823,12 +846,24 @@ void halrf_support_ability_debug(void *dm_void, char input[][16], u32 *_used, "04. (( %s ))HAL_RF_TXGAPK\n", ((rf->rf_supportability & HAL_RF_TXGAPK) ? ("V") : ("."))); + PDM_SNPF(out_len, used, output + used, out_len - used, + "05. (( %s ))HAL_RF_DACK\n", + ((rf->rf_supportability & HAL_RF_DACK) ? ("V") : + ("."))); + PDM_SNPF(out_len, used, output + used, out_len - used, + "06. (( %s ))DPK_TRACK\n", + ((rf->rf_supportability & HAL_RF_DPK_TRACK) ? ("V") : + ("."))); #ifdef CONFIG_2G_BAND_SHIFT PDM_SNPF(out_len, used, output + used, out_len - used, "07. (( %s ))HAL_2GBAND_SHIFT\n", ((rf->rf_supportability & HAL_2GBAND_SHIFT) ? ("V") : ("."))); #endif + PDM_SNPF(out_len, used, output + used, out_len - used, + "08. (( %s ))HAL_RF_RXDCK\n", + ((rf->rf_supportability & HAL_RF_RXDCK) ? ("V") : + ("."))); } else { if (dm_value[1] == 1) /* enable */ @@ -906,6 +941,9 @@ void halrf_cmn_info_init(void *dm_void, enum halrf_cmninfo_init cmn_info, case HALRF_CMNINFO_PWT_TYPE: rf->pwt_type = (u8)value; break; + case HALRF_CMNINFO_MP_POWER_TRACKING_TYPE: + rf->mp_pwt_type = (u8)value; + break; default: break; } @@ -943,6 +981,7 @@ void halrf_cmn_info_set(void *dm_void, u32 cmn_info, u64 value) { /* This init variable may be changed in run time. */ struct dm_struct *dm = (struct dm_struct *)dm_void; + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; struct _hal_rf_ *rf = &dm->rf_table; switch (cmn_info) { @@ -980,6 +1019,9 @@ void halrf_cmn_info_set(void *dm_void, u32 cmn_info, u64 value) rf->halrf_psd_data.average = (u32)value; break; #endif + case HALRF_CMNINFO_POWER_TRACK_CONTROL: + cali_info->txpowertrack_control = (u8)value; + break; default: /* do nothing */ break; @@ -1006,6 +1048,9 @@ u64 halrf_cmn_info_get(void *dm_void, u32 cmn_info) case HALRF_CMNINFO_IQK_SEGMENT: return_value = dm->IQK_info.segment_iqk; break; + case HALRF_CMNINFO_IQK_TIMES: + return_value = dm->IQK_info.iqk_times; + break; #endif default: /* do nothing */ @@ -1029,6 +1074,7 @@ void halrf_supportability_init_mp(void *dm_void) HAL_RF_LCK | HAL_RF_DPK | HAL_RF_DACK | + /*HAL_RF_TXGAPK |*/ HAL_RF_DPK_TRACK | 0; #endif @@ -1052,6 +1098,8 @@ void halrf_supportability_init_mp(void *dm_void) HAL_RF_DPK | HAL_RF_DACK | HAL_RF_DPK_TRACK | + HAL_RF_RXDCK | + HAL_RF_TXGAPK | 0; break; #endif @@ -1069,11 +1117,11 @@ void halrf_supportability_init_mp(void *dm_void) #if (RTL8195B_SUPPORT == 1) case ODM_RTL8195B: rf->rf_supportability = - HAL_RF_TX_PWR_TRACK | + /*HAL_RF_TX_PWR_TRACK |*/ HAL_RF_IQK | HAL_RF_LCK | HAL_RF_DPK | - HAL_RF_TXGAPK | + /*HAL_RF_TXGAPK |*/ HAL_RF_DPK_TRACK | 0; break; @@ -1137,7 +1185,7 @@ void halrf_supportability_init_mp(void *dm_void) /*HAL_RF_LCK |*/ HAL_RF_DPK | /*@HAL_RF_TXGAPK |*/ - /*HAL_RF_DPK_TRACK |*/ + HAL_RF_DPK_TRACK | 0; break; #endif @@ -1153,6 +1201,18 @@ void halrf_supportability_init_mp(void *dm_void) 0; break; #endif +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + rf->rf_supportability = + HAL_RF_TX_PWR_TRACK | + HAL_RF_IQK | + HAL_RF_LCK | + HAL_RF_DPK | + HAL_RF_TXGAPK | + HAL_RF_DPK_TRACK | + 0; + break; +#endif default: rf->rf_supportability = @@ -1207,6 +1267,8 @@ void halrf_supportability_init(void *dm_void) HAL_RF_DPK | HAL_RF_DACK | HAL_RF_DPK_TRACK | + HAL_RF_RXDCK | + HAL_RF_TXGAPK | 0; break; #endif @@ -1228,7 +1290,7 @@ void halrf_supportability_init(void *dm_void) HAL_RF_IQK | HAL_RF_LCK | HAL_RF_DPK | - HAL_RF_TXGAPK | + /*HAL_RF_TXGAPK |*/ HAL_RF_DPK_TRACK | 0; break; @@ -1292,7 +1354,7 @@ void halrf_supportability_init(void *dm_void) /*HAL_RF_LCK |*/ HAL_RF_DPK | /*@HAL_RF_TXGAPK |*/ - /*HAL_RF_DPK_TRACK |*/ + HAL_RF_DPK_TRACK | #ifdef CONFIG_2G_BAND_SHIFT HAL_2GBAND_SHIFT | #endif @@ -1311,6 +1373,18 @@ void halrf_supportability_init(void *dm_void) 0; break; #endif +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + rf->rf_supportability = + HAL_RF_TX_PWR_TRACK | + HAL_RF_IQK | + HAL_RF_LCK | + HAL_RF_DPK | + HAL_RF_TXGAPK | + HAL_RF_DPK_TRACK | + 0; + break; +#endif default: rf->rf_supportability = @@ -1338,9 +1412,14 @@ void halrf_watchdog(void *dm_void) if (rf->is_dpk_in_progress || dm->rf_calibrate_info.is_iqk_in_progress || rf->is_tssi_in_progress) return; - +#if !(RTL8723F_SUPPORT == 1) phydm_rf_watchdog(dm); +#endif halrf_dpk_track(dm); +#if (RTL8723F_SUPPORT == 1) + halrf_xtal_thermal_track(dm); +#endif + } #if 0 @@ -1378,6 +1457,31 @@ halrf_iqk_init( } #endif +void halrf_rfk_power_save(void *dm_void, boolean is_power_save) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct dm_iqk_info *iqk_info = &dm->IQK_info; + + switch (dm->support_ic_type) { +#if (RTL8822C_SUPPORT == 1) + case ODM_RTL8822C: + halrf_rfk_power_save_8822c(dm, is_power_save); + break; +#endif + +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + halrf_rfk_power_save_8723f(dm, is_power_save); + break; +#endif + + default: + break; + } +} + + + void halrf_reload_iqk(void *dm_void, boolean reset) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -1386,21 +1490,32 @@ void halrf_reload_iqk(void *dm_void, boolean reset) u32 tmp; u32 bit_mask_20_16 = BIT(20) | BIT(19) | BIT(18) | BIT(17) | BIT(16); + halrf_rfk_power_save(dm, false); switch (dm->support_ic_type) { #if (RTL8822C_SUPPORT == 1) - case ODM_RTL8822C: + case ODM_RTL8822C: iqk_reload_iqk_8822c(dm, reset); break; #endif +#if (RTL8195B_SUPPORT == 1) + case ODM_RTL8195B: + iqk_reload_iqk_8195b(dm, reset); + break; +#endif + default: break; } + halrf_rfk_power_save(dm, true); } void halrf_rfk_handshake(void *dm_void, boolean is_before_k) { struct dm_struct *dm = (struct dm_struct *)dm_void; + if (!dm->mp_mode) + return; + if (*dm->mp_mode) return; @@ -1409,6 +1524,32 @@ void halrf_rfk_handshake(void *dm_void, boolean is_before_k) case ODM_RTL8822C: halrf_rfk_handshake_8822c(dm, is_before_k); break; +#endif +#if (RTL8710C_SUPPORT == 1) + case ODM_RTL8710C: + halrf_rfk_handshake_8710c(dm, is_before_k); + break; +#endif +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + halrf_rfk_handshake_8723f(dm, is_before_k); + break; +#endif + default: + break; + } +} + +void halrf_bbreset(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + + switch (dm->support_ic_type) { +#if (RTL8814B_SUPPORT == 1) + case ODM_RTL8814B: + phydm_bb_reset_8814b(dm); + break; #endif default: break; @@ -1422,29 +1563,39 @@ void halrf_rf_k_connect_trigger(void *dm_void, boolean is_recovery, struct dm_dpk_info *dpk_info = &dm->dpk_info; struct _hal_rf_ *rf = &dm->rf_table; + if (!dm->mp_mode) + return; + if (dm->mp_mode && rf->is_con_tx && rf->is_single_tone && - rf->is_carrier_suppresion) { - if (*dm->mp_mode && - (*rf->is_con_tx || *rf->is_single_tone || - *rf->is_carrier_suppresion)) + rf->is_carrier_suppresion) { + if (*dm->mp_mode & + (*rf->is_con_tx || *rf->is_single_tone || + *rf->is_carrier_suppresion)) return; } + /*[TX GAP K]*/ + halrf_txgapk_trigger(dm); /*[LOK, IQK]*/ halrf_segment_iqk_trigger(dm, true, seg_time); /*[TSSI Trk]*/ halrf_tssi_trigger(dm); - /*[DPK]*/ +#if 1 if(dpk_info->is_dpk_by_channel == true) halrf_dpk_trigger(dm); else halrf_dpk_reload(dm); - +#endif //ADDA restore to MP_UI setting; config_halrf_path_adda_setting_trigger(dm); + +#if (RTL8723F_SUPPORT == 1) + halrf_spur_compensation_8723f(dm); +#endif + halrf_bbreset(dm); } void config_halrf_path_adda_setting_trigger(void *dm_void) @@ -1458,7 +1609,24 @@ void config_halrf_path_adda_setting_trigger(void *dm_void) } -void halrf_dack_trigger(void *dm_void) +void halrf_dack_restore(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct _hal_rf_ *rf = &dm->rf_table; + + if (!(rf->rf_supportability & HAL_RF_DACK)) + return; + switch (dm->support_ic_type) { +#if (RTL8822C_SUPPORT == 1) + case ODM_RTL8822C: + halrf_dack_restore_8822c(dm); + break; +#endif + default: + break; + } +} +void halrf_dack_trigger(void *dm_void, boolean force) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct _hal_rf_ *rf = &dm->rf_table; @@ -1473,7 +1641,7 @@ void halrf_dack_trigger(void *dm_void) switch (dm->support_ic_type) { #if (RTL8822C_SUPPORT == 1) case ODM_RTL8822C: - halrf_dac_cal_8822c(dm); + halrf_dac_cal_8822c(dm, force); break; #endif #if (RTL8812F_SUPPORT == 1) @@ -1530,20 +1698,19 @@ void halrf_segment_iqk_trigger(void *dm_void, boolean clear, return; #endif - if (dm->mp_mode && - rf->is_con_tx && - rf->is_single_tone && - rf->is_carrier_suppresion) - if (*dm->mp_mode && - ((*rf->is_con_tx || - *rf->is_single_tone || - *rf->is_carrier_suppresion))) - return; + if (!dm->mp_mode) + return; + + if (dm->mp_mode && rf->is_con_tx && rf->is_single_tone && + rf->is_carrier_suppresion) { + if (*dm->mp_mode & + (*rf->is_con_tx || *rf->is_single_tone || + *rf->is_carrier_suppresion)) + return; + } -#if (DM_ODM_SUPPORT_TYPE == ODM_CE) if (!(rf->rf_supportability & HAL_RF_IQK)) return; -#endif #if DISABLE_BB_RF return; @@ -1551,6 +1718,7 @@ void halrf_segment_iqk_trigger(void *dm_void, boolean clear, if (iqk_info->rfk_forbidden) return; + rf->rfk_type = RF01_IQK; halrf_rfk_handshake(dm, true); if (!dm->rf_calibrate_info.is_iqk_in_progress) { @@ -1560,6 +1728,7 @@ void halrf_segment_iqk_trigger(void *dm_void, boolean clear, start_time = odm_get_current_time(dm); dm->IQK_info.segment_iqk = segment_iqk; + halrf_rfk_power_save(dm, false); switch (dm->support_ic_type) { #if (RTL8822B_SUPPORT == 1) case ODM_RTL8822B: @@ -1671,9 +1840,17 @@ void halrf_segment_iqk_trigger(void *dm_void, boolean clear, phy_iq_calibrate_8814a(dm, false); break; #endif +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + phy_iq_calibrate_8723f(dm, false); + break; +#endif + default: break; } + + halrf_rfk_power_save(dm, true); dm->rf_calibrate_info.iqk_progressing_time = odm_get_progressing_time(dm, start_time); RF_DBG(dm, DBG_RF_IQK, "[IQK]IQK progressing_time = %lld ms\n", @@ -1704,15 +1881,16 @@ void halrf_iqk_trigger(void *dm_void, boolean is_recovery) return; #endif - if (dm->mp_mode && - rf->is_con_tx && - rf->is_single_tone && - rf->is_carrier_suppresion) - if (*dm->mp_mode && - ((*rf->is_con_tx || - *rf->is_single_tone || - *rf->is_carrier_suppresion))) + if (!dm->mp_mode) + return; + + if (dm->mp_mode && rf->is_con_tx && rf->is_single_tone && + rf->is_carrier_suppresion) { + if (*dm->mp_mode & + (*rf->is_con_tx || *rf->is_single_tone || + *rf->is_carrier_suppresion)) return; + } if (!(rf->rf_supportability & HAL_RF_IQK)) return; @@ -1724,6 +1902,7 @@ void halrf_iqk_trigger(void *dm_void, boolean is_recovery) if (iqk_info->rfk_forbidden) return; + rf->rfk_type = RF01_IQK; halrf_rfk_handshake(dm, true); if (!dm->rf_calibrate_info.is_iqk_in_progress) { @@ -1731,6 +1910,7 @@ void halrf_iqk_trigger(void *dm_void, boolean is_recovery) dm->rf_calibrate_info.is_iqk_in_progress = true; odm_release_spin_lock(dm, RT_IQK_SPINLOCK); start_time = odm_get_current_time(dm); + halrf_rfk_power_save(dm, false); switch (dm->support_ic_type) { #if (RTL8188E_SUPPORT == 1) case ODM_RTL8188E: @@ -1842,9 +2022,17 @@ void halrf_iqk_trigger(void *dm_void, boolean is_recovery) phy_iq_calibrate_8197g(dm, false, false); break; #endif +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + phy_iq_calibrate_8723f(dm, is_recovery); + break; +#endif + default: break; } + + halrf_rfk_power_save(dm, true); rf->iqk_progressing_time = odm_get_progressing_time(dm, start_time); RF_DBG(dm, DBG_RF_LCK, "[IQK]Trigger IQK progressing_time = %lld ms\n", rf->iqk_progressing_time); @@ -1871,15 +2059,16 @@ void halrf_lck_trigger(void *dm_void) return; #endif - if (dm->mp_mode && - rf->is_con_tx && - rf->is_single_tone && - rf->is_carrier_suppresion) - if (*dm->mp_mode && - ((*rf->is_con_tx || - *rf->is_single_tone || - *rf->is_carrier_suppresion))) + if (!dm->mp_mode) + return; + + if (dm->mp_mode && rf->is_con_tx && rf->is_single_tone && + rf->is_carrier_suppresion) { + if (*dm->mp_mode & + (*rf->is_con_tx || *rf->is_single_tone || + *rf->is_carrier_suppresion)) return; + } if (!(rf->rf_supportability & HAL_RF_LCK)) return; @@ -1890,7 +2079,7 @@ void halrf_lck_trigger(void *dm_void) if (iqk_info->rfk_forbidden) return; while (*dm->is_scan_in_process) { - RF_DBG(dm, DBG_RF_IQK, "[LCK]scan is in process, bypass LCK\n"); + RF_DBG(dm, DBG_RF_LCK, "[LCK]scan is in process, bypass LCK\n"); return; } @@ -1987,6 +2176,17 @@ void halrf_lck_trigger(void *dm_void) #endif #if (RTL8814B_SUPPORT == 1) case ODM_RTL8814B: + phy_lc_calibrate_8814b(dm); + break; +#endif +#if (RTL8197G_SUPPORT == 1) + case ODM_RTL8197G: + phy_lc_calibrate_8197g(dm); + break; +#endif +#if (RTL8198F_SUPPORT == 1) + case ODM_RTL8198F: + phy_lc_calibrate_8198f(dm); break; #endif #if (RTL8710C_SUPPORT == 1) @@ -1994,12 +2194,18 @@ void halrf_lck_trigger(void *dm_void) phy_lc_calibrate_8710c(dm); break; #endif +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + phy_lc_calibrate_8723f(dm); + break; +#endif + default: break; } dm->rf_calibrate_info.lck_progressing_time = odm_get_progressing_time(dm, start_time); - RF_DBG(dm, DBG_RF_IQK, "[IQK]LCK progressing_time = %lld ms\n", + RF_DBG(dm, DBG_RF_LCK, "[LCK]LCK progressing_time = %lld ms\n", dm->rf_calibrate_info.lck_progressing_time); #if (RTL8822B_SUPPORT == 1 || RTL8821C_SUPPORT == 1) halrf_lck_dbg(dm); @@ -2008,8 +2214,8 @@ void halrf_lck_trigger(void *dm_void) dm->rf_calibrate_info.is_lck_in_progress = false; odm_release_spin_lock(dm, RT_IQK_SPINLOCK); } else { - RF_DBG(dm, DBG_RF_IQK, - "= Return the LCK CMD, because RFK is in Progress =\n"); + RF_DBG(dm, DBG_RF_LCK, + "[LCK]= Return the LCK CMD, because RFK is in Progress =\n"); } } @@ -2035,6 +2241,25 @@ void halrf_aac_check(struct dm_struct *dm) } } +void halrf_rxdck(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct _hal_rf_ *rf = &dm->rf_table; + + if (!(rf->rf_supportability & HAL_RF_RXDCK)) + return; + + switch (dm->support_ic_type) { + case ODM_RTL8822C: +#if (RTL8822C_SUPPORT == 1) + halrf_rxdck_8822c(dm); + break; +#endif + default: + break; + } +} + void halrf_x2k_check(struct dm_struct *dm) { @@ -2053,6 +2278,12 @@ void halrf_x2k_check(struct dm_struct *dm) phy_x2_check_8812f(dm); break; #endif + case ODM_RTL8723F: +#if (RTL8723F_SUPPORT == 1) + phy_x2_check_8723f(dm); + break; +#endif + default: break; } @@ -2063,6 +2294,9 @@ void halrf_set_rfsupportability(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct _hal_rf_ *rf = &dm->rf_table; + if (!dm->mp_mode) + return; + if (rf->manual_rf_supportability && *rf->manual_rf_supportability != 0xffffffff) { rf->rf_supportability = *rf->manual_rf_supportability; @@ -2073,6 +2307,24 @@ void halrf_set_rfsupportability(void *dm_void) } } +void halrf_rfe_definition(struct dm_struct *dm) +{ + struct _hal_rf_ *rf = &dm->rf_table; + + switch (dm->support_ic_type) { + case ODM_RTL8822C: +#if (RTL8822C_SUPPORT == 1) + if (dm->rfe_type == 21 || dm->rfe_type == 22) { + rf->ext_pa_5g = 1; + rf->ext_lna_5g = 1; + } + break; +#endif + default: + break; + } +} + void halrf_init(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -2082,10 +2334,11 @@ void halrf_init(void *dm_void) rf->aac_checked = false; halrf_init_debug_setting(dm); halrf_set_rfsupportability(dm); + halrf_rfe_definition(dm); #if 1 /*Init all RF funciton*/ halrf_aac_check(dm); - halrf_dack_trigger(dm); + halrf_dack_trigger(dm, false); halrf_x2k_check(dm); #endif @@ -2096,6 +2349,13 @@ void halrf_init(void *dm_void) halrf_tssi_dck(dm, true); halrf_tssi_get_efuse(dm); halrf_tssi_set_de(dm); +#if (RTL8723F_SUPPORT == 1) + halrf_do_tssi(dm); + halrf_rx_port_ctl_8723f(dm); +#endif + + /*TX Gap K*/ + halrf_txgapk_write_gain_table(dm); } void halrf_dpk_trigger(void *dm_void) @@ -2112,15 +2372,16 @@ void halrf_dpk_trigger(void *dm_void) return; #endif - if (dm->mp_mode && - rf->is_con_tx && - rf->is_single_tone && - rf->is_carrier_suppresion) - if (*dm->mp_mode && - ((*rf->is_con_tx || - *rf->is_single_tone || - *rf->is_carrier_suppresion))) + if (!dm->mp_mode) + return; + + if (dm->mp_mode && rf->is_con_tx && rf->is_single_tone && + rf->is_carrier_suppresion) { + if (*dm->mp_mode & + (*rf->is_con_tx || *rf->is_single_tone || + *rf->is_carrier_suppresion)) return; + } if (!(rf->rf_supportability & HAL_RF_DPK)) return; @@ -2132,6 +2393,7 @@ void halrf_dpk_trigger(void *dm_void) if (iqk_info->rfk_forbidden) return; + rf->rfk_type = RF03_DPK; halrf_rfk_handshake(dm, true); if (!rf->is_dpk_in_progress) { @@ -2139,7 +2401,7 @@ void halrf_dpk_trigger(void *dm_void) rf->is_dpk_in_progress = true; odm_release_spin_lock(dm, RT_IQK_SPINLOCK); start_time = odm_get_current_time(dm); - + halrf_rfk_power_save(dm, false); switch (dm->support_ic_type) { #if (RTL8822C_SUPPORT == 1) case ODM_RTL8822C: @@ -2182,6 +2444,11 @@ void halrf_dpk_trigger(void *dm_void) do_dpk_8814b(dm); break; #endif +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + do_dpk_8723f(dm); + break; +#endif #if (DM_ODM_SUPPORT_TYPE & (ODM_IOT)) #if (RTL8195B_SUPPORT == 1) @@ -2198,6 +2465,7 @@ void halrf_dpk_trigger(void *dm_void) default: break; } + halrf_rfk_power_save(dm, true); rf->dpk_progressing_time = odm_get_progressing_time(dm, start_time); RF_DBG(dm, DBG_RF_DPK, "[DPK]DPK progressing_time = %lld ms\n", rf->dpk_progressing_time); @@ -2264,20 +2532,18 @@ void halrf_set_dpkenable(void *dm_void, boolean is_dpk_enable) #if (RTL8195B_SUPPORT == 1) case ODM_RTL8195B: dpk_set_is_dpk_enable_8195b(dm, is_dpk_enable); - break; + break; #endif #if (RTL8721D_SUPPORT == 1) - case RTL8721D_SUPPORT: - dpk_set_is_dpk_enable_8721d(dm, is_dpk_enable); - break; + case ODM_RTL8721D: + dpk_set_is_dpk_enable_8721d(dm, is_dpk_enable); + break; #endif #endif - - - default: - break; + default: + break; } } @@ -2576,6 +2842,12 @@ void halrf_dpk_enable_disable(void *dm_void) break; #endif +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + dpk_enable_disable_8723f(dm); + break; +#endif + #endif default: break; @@ -2598,20 +2870,26 @@ void halrf_dpk_track(void *dm_void) if (rf->is_dpk_in_progress || dm->rf_calibrate_info.is_iqk_in_progress || dm->is_psd_in_process || (dpk_info->dpk_path_ok == 0) || - !(rf->rf_supportability & HAL_RF_DPK_TRACK) || rf->is_tssi_in_progress) + !(rf->rf_supportability & HAL_RF_DPK_TRACK) || rf->is_tssi_in_progress + || rf->is_txgapk_in_progress) return; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + if (*dm->is_fcs_mode_enable) + return; +#endif + switch (dm->support_ic_type) { #if (RTL8814B_SUPPORT == 1) case ODM_RTL8814B: dpk_track_8814b(dm); - break; + break; #endif #if (RTL8822C_SUPPORT == 1) case ODM_RTL8822C: dpk_track_8822c(dm); - break; + break; #endif #if (RTL8195B_SUPPORT == 1) @@ -2626,6 +2904,12 @@ void halrf_dpk_track(void *dm_void) break; #endif +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + dpk_track_8723f(dm); + break; +#endif + #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) #if (RTL8197F_SUPPORT == 1) @@ -2643,19 +2927,19 @@ void halrf_dpk_track(void *dm_void) #if (RTL8198F_SUPPORT == 1) case ODM_RTL8198F: dpk_track_8198f(dm); - break; + break; #endif #if (RTL8812F_SUPPORT == 1) case ODM_RTL8812F: dpk_track_8812f(dm); - break; + break; #endif #if (RTL8197G_SUPPORT == 1) case ODM_RTL8197G: dpk_track_8197g(dm); - break; + break; #endif #endif @@ -2731,6 +3015,278 @@ void halrf_dpk_reload(void *dm_void) } } +void halrf_dpk_switch(void *dm_void, u8 enable) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct dm_dpk_info *dpk_info = &dm->dpk_info; + struct _hal_rf_ *rf = &dm->rf_table; + + if (enable) { + rf->rf_supportability = rf->rf_supportability | HAL_RF_DPK; + dpk_info->is_dpk_enable = true; + halrf_dpk_enable_disable(dm); + halrf_dpk_trigger(dm); + halrf_set_dpk_track(dm, 1); + } else { + halrf_set_dpk_track(dm, 0); + dpk_info->is_dpk_enable = false; + halrf_dpk_enable_disable(dm); + rf->rf_supportability = rf->rf_supportability & ~HAL_RF_DPK; + } +} + +void _halrf_dpk_info_by_chip(void *dm_void, u32 *_used, char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + u32 used = *_used; + u32 out_len = *_out_len; + + switch (dm->support_ic_type) { +#if (RTL8822C_SUPPORT == 1) + case ODM_RTL8822C: + dpk_info_by_8822c(dm, &used, output, &out_len); + break; +#endif + +#if (RTL8812F_SUPPORT == 1) + case ODM_RTL8812F: + dpk_info_by_8812f(dm, &used, output, &out_len); + break; +#endif + +#if (RTL8197G_SUPPORT == 1) + case ODM_RTL8197G: + dpk_info_by_8197g(dm, &used, output, &out_len); + break; +#endif + + default: + break; + } + + *_used = used; + *_out_len = out_len; +} + +void _halrf_display_dpk_info(void *dm_void, u32 *_used, char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct dm_dpk_info *dpk_info = &dm->dpk_info; + struct _hal_rf_ *rf = &(dm->rf_table); + + u32 used = *_used; + u32 out_len = *_out_len; + char *ic_name = NULL; + u8 path; + + switch (dm->support_ic_type) { + +#if (RTL8822C_SUPPORT) + case ODM_RTL8822C: + ic_name = "8822C"; + break; +#endif + +#if (RTL8814B_SUPPORT) + case ODM_RTL8814B: + ic_name = "8814B"; + break; +#endif + +#if (RTL8812F_SUPPORT) + case ODM_RTL8812F: + ic_name = "8812F"; + break; +#endif + +#if (RTL8198F_SUPPORT) + case ODM_RTL8198F: + ic_name = "8198F"; + break; +#endif + +#if (RTL8197F_SUPPORT) + case ODM_RTL8197F: + ic_name = "8197F"; + break; +#endif + +#if (RTL8192F_SUPPORT) + case ODM_RTL8192F: + ic_name = "8192F"; + break; +#endif + +#if (RTL8197G_SUPPORT) + case ODM_RTL8197G: + ic_name = "8197G"; + break; +#endif + +#if (RTL8710B_SUPPORT) + case ODM_RTL8721D: + ic_name = "8721D"; + break; +#endif + +#if (RTL8195B_SUPPORT) + case ODM_RTL8195B: + ic_name = "8195B"; + break; +#endif + } + + PDM_SNPF(out_len, used, output + used, out_len - used, + "\n===============[ DPK info %s ]===============\n", ic_name); + + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %s %s\n", + "DPK type", (dm->fw_offload_ability & PHYDM_RF_DPK_OFFLOAD) ? "FW" : "Driver", + (dpk_info->is_dpk_by_channel) ? "(By channel)" : "(By group)"); + + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %d (%d)\n", + "FW Ver (Sub Ver)", dm->fw_version, dm->fw_sub_version); + + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %s\n", + "DPK Ver", HALRF_DPK_VER); + + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %s\n", + "RFK init ver", HALRF_RFK_INIT_VER); + + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %d / %d (RFE type:%d)\n", + "Ext_PA 2G / 5G", dm->ext_pa, dm->ext_pa_5g, dm->rfe_type); + + if ((dpk_info->dpk_ch == 0) && (dpk_info->thermal_dpk[0] == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, "\n %-25s\n", + "No DPK had been done before!!!"); + return; + } + + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %d / %d / %d\n", + "DPK Cal / OK / Reload", dpk_info->dpk_cal_cnt, dpk_info->dpk_ok_cnt, + dpk_info->dpk_reload_cnt); + + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %s\n", + "RFK H2C timeout", (rf->is_rfk_h2c_timeout) ? "Yes" : "No"); + + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %s\n", + "DPD Reload", (dpk_info->dpk_status & BIT(0)) ? "Yes" : "No"); + + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %s\n", + "DPD status", dpk_info->is_dpk_enable ? "Enable" : "Disable"); + + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %s\n", + "DPD track status", (rf->rf_supportability & HAL_RF_DPK_TRACK) ? "Enable" : "Disable"); + + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %s / %s / %d / %s\n", + "TSSI / Band / CH / BW", dpk_info->is_tssi_mode == 1 ? "On" : "Off", + dpk_info->dpk_band == 0 ? "2G" : "5G", dpk_info->dpk_ch, + dpk_info->dpk_bw == 3 ? "20M" : (dpk_info->dpk_bw == 2 ? "40M" : "80M")); + + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %s / %s / %s / %s\n", + "DPK result (path)", dpk_info->dpk_path_ok & BIT(0) ? "OK" : "Fail", + (dm->support_ic_type & ODM_IC_2SS) ? ((dpk_info->dpk_path_ok & BIT(1)) >> 1 ? "OK" : "Fail") : "NA", + (dm->support_ic_type & ODM_IC_3SS) ? ((dpk_info->dpk_path_ok & BIT(2)) >> 2 ? "OK" : "Fail") : "NA", + (dm->support_ic_type & ODM_IC_4SS) ? ((dpk_info->dpk_path_ok & BIT(3)) >> 3 ? "OK" : "Fail") : "NA"); +#if 0 + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %d / %d / %d / %d\n", + "DPK thermal (path)", dpk_info->thermal_dpk[0], dpk_info->thermal_dpk[1], + dpk_info->thermal_dpk[2], dpk_info->thermal_dpk[3]); +#endif + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = ", + "DPK thermal (path)"); + for (path = 0; path < KPATH; path++) { + PDM_SNPF(out_len, used, output + used, out_len - used, + path == (KPATH - 1) ? "%d\n" : "%d / ", + dpk_info->thermal_dpk[path]); + } + + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = 0x%x\n", + "DPK bkup GNT control", dpk_info->gnt_control); + + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = 0x%x\n", + "DPK bkup GNT value", dpk_info->gnt_value); + + _halrf_dpk_info_by_chip(dm, &used, output, &out_len); + + *_used = used; + *_out_len = out_len; +} + +void halrf_dpk_debug_cmd(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct dm_dpk_info *dpk_info = &dm->dpk_info; + struct _hal_rf_ *rf = &(dm->rf_table); + + char *cmd[5] = {"-h", "on", "off", "info", "switch"}; + u32 used = *_used; + u32 out_len = *_out_len; + u8 i; + + if ((strcmp(input[2], cmd[4]) != 0)) { + if (!(rf->rf_supportability & HAL_RF_DPK)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "DPK is Unsupported!!!\n"); + return; + } + } + + if ((strcmp(input[2], cmd[0]) == 0)) { + for (i = 1; i < 4; i++) { + PDM_SNPF(out_len, used, output + used, out_len - used, + " %s\n", cmd[i]); + } + } else if ((strcmp(input[2], cmd[1]) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "DPK is Enabled!!\n"); + dpk_info->is_dpk_enable = true; + halrf_dpk_enable_disable(dm); + } else if ((strcmp(input[2], cmd[2]) == 0)){ + PDM_SNPF(out_len, used, output + used, out_len - used, + "DPK is Disabled!!\n"); + dpk_info->is_dpk_enable = false; + halrf_dpk_enable_disable(dm); + } else if ((strcmp(input[2], cmd[3]) == 0)) + _halrf_display_dpk_info(dm, &used, output, &out_len); + else if ((strcmp(input[2], cmd[4]) == 0) && (strcmp(input[3], cmd[1]) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "DPK Switch on!!\n"); + halrf_dpk_switch(dm, 1); + } else if ((strcmp(input[2], cmd[4]) == 0) && (strcmp(input[3], cmd[2]) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "DPK Switch off!!\n"); + halrf_dpk_switch(dm, 0); + } else { + PDM_SNPF(out_len, used, output + used, out_len - used, + "DPK Trigger start!!\n"); + halrf_dpk_trigger(dm); + PDM_SNPF(out_len, used, output + used, out_len - used, + "DPK Trigger finish!!\n"); + } +} + +void halrf_dpk_c2h_report_transfer(void *dm_void, boolean is_ok, u8 *buf, u8 buf_size) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct _hal_rf_ *rf = &dm->rf_table; + struct dm_dpk_info *dpk_info = &dm->dpk_info; + + if (!(rf->rf_supportability & HAL_RF_DPK)) + return; + + switch (dm->support_ic_type) { +#if (RTL8822C_SUPPORT == 1) + case ODM_RTL8822C: + dpk_c2h_report_transfer_8822c(dm, is_ok, buf, buf_size); + break; +#endif + default: + break; + } +} + void halrf_dpk_info_rsvd_page(void *dm_void, u8 *buf, u32 *buf_size) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -2768,6 +3324,12 @@ void halrf_iqk_info_rsvd_page(void *dm_void, u8 *buf, u32 *buf_size) iqk_info_rsvd_page_8822c(dm, buf, buf_size); break; #endif +#if (RTL8195B_SUPPORT == 1) + case ODM_RTL8195B: + iqk_info_rsvd_page_8195b(dm, buf, buf_size); + break; +#endif + default: break; } @@ -2828,7 +3390,19 @@ halrf_config_rfk_with_header_file(void *dm_void, u32 config_type) odm_read_and_config_mp_8721d_cal_init(dm); } #endif +#if (RTL8723F_SUPPORT == 1) + if (dm->support_ic_type == ODM_RTL8723F) { + if (config_type == CONFIG_BB_RF_CAL_INIT) + odm_read_and_config_mp_8723f_cal_init(dm); + } +#endif +#if 1 + if (dm->fw_offload_ability & PHYDM_PHY_PARAM_OFFLOAD) { + result = phydm_set_reg_by_fw(dm, PHYDM_HALMAC_CMD_END, 0, 0, 0, (enum rf_path)0, 0); + RF_DBG(dm, DBG_RF_IQK,"phy param offload end!result = %d", result); + } +#endif return result; } @@ -2836,29 +3410,59 @@ void halrf_txgapk_trigger(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct _hal_rf_ *rf = &dm->rf_table; + u64 start_time = 0x0; - u64 start_time; + if (!(rf->rf_supportability & HAL_RF_TXGAPK)) + return; + + rf->rfk_type = RF04_TXGAPK; + halrf_rfk_handshake(dm, true); start_time = odm_get_current_time(dm); + rf->is_txgapk_in_progress = true; + halrf_rfk_power_save(dm, false); switch (dm->support_ic_type) { #if (DM_ODM_SUPPORT_TYPE & (ODM_IOT)) #if (RTL8195B_SUPPORT == 1) case ODM_RTL8195B: - phy_txgap_calibrate_8195b(dm, false); + /*phy_txgap_calibrate_8195b(dm, false);*/ break; #endif #if (RTL8721D_SUPPORT == 1) case ODM_RTL8721D: - phy_txgap_calibrate_8721d(dm, false); + /*phy_txgap_calibrate_8721d(dm, false);*/ break; #endif +#endif + +#if (RTL8814B_SUPPORT == 1) + case ODM_RTL8814B: + /*phy_txgap_calibrate_8814b(dm, false);*/ + break; +#endif + +#if (RTL8822C_SUPPORT == 1) + case ODM_RTL8822C: + halrf_txgapk_8822c(dm); + break; +#endif + +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + halrf_txgapk_8723f(dm); + break; #endif default: break; - } + } + halrf_rfk_power_save(dm, true); + rf->is_txgapk_in_progress = false; + + halrf_rfk_handshake(dm, false); + rf->dpk_progressing_time = odm_get_progressing_time(dm_void, start_time); RF_DBG(dm, DBG_RF_TXGAPK, "[TGGC]TXGAPK progressing_time = %lld ms\n", @@ -2895,6 +3499,12 @@ void halrf_tssi_get_efuse(void *dm_void) } #endif +#if (RTL8723F_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8723F) { + halrf_tssi_get_efuse_8723f(dm); + } +#endif + } void halrf_do_rxbb_dck(void *dm_void) @@ -2928,8 +3538,30 @@ void halrf_do_tssi(void *dm_void) halrf_do_tssi_8197g(dm); #endif +#if (RTL8723F_SUPPORT == 1) + if (dm->support_ic_type == ODM_RTL8723F) + halrf_rfk_power_save(dm, false); + halrf_do_tssi_8723f(dm); + halrf_rfk_power_save(dm, true); +#endif + } +void halrf_set_tssi_enable(void *dm_void, boolean enable) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct _hal_rf_ *rf = &(dm->rf_table); + + if (enable == 1) { + rf->power_track_type = 4; + odm_set_bb_reg(dm, R_0x1e7c, 0x40000000, 0x1); + } else { + rf->power_track_type = 0; + odm_set_bb_reg(dm, R_0x1e7c, 0x40000000, 0x0); + } +} + + void halrf_do_thermal(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -2955,6 +3587,10 @@ u32 halrf_set_tssi_value(void *dm_void, u32 tssi_value) if (dm->support_ic_type & ODM_RTL8814B) return halrf_set_tssi_value_8814b(dm, tssi_value); #endif +#if (RTL8723F_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8723F) + return halrf_tssi_set_de_8723f(dm, tssi_value); +#endif return 0; } @@ -2987,7 +3623,15 @@ void halrf_tssi_set_de_for_tx_verify(void *dm_void, u32 tssi_de, u8 path) halrf_tssi_set_de_for_tx_verify_8812f(dm, tssi_de, path); #endif +#if (RTL8197G_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8197G) + halrf_tssi_set_de_for_tx_verify_8197g(dm, tssi_de, path); +#endif +#if (RTL8723F_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8723F) + halrf_tssi_set_de_for_tx_verify_8723f(dm, tssi_de, path); +#endif } u32 halrf_query_tssi_value(void *dm_void) @@ -3046,8 +3690,16 @@ void halrf_tssi_dck(void *dm_void, u8 direct_do) halrf_rfk_handshake(dm, true); #if (RTL8814B_SUPPORT == 1) - if (dm->support_ic_type & ODM_RTL8814B) + if (dm->support_ic_type & ODM_RTL8814B) { +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) + if (dm->rfe_type == 1 || dm->rfe_type == 4 || dm->rfe_type == 5) + return; +#else + if (dm->rfe_type == 1 || dm->rfe_type == 6) + return; +#endif halrf_tssi_dck_8814b(dm, direct_do); + } #endif #if (RTL8822C_SUPPORT == 1) @@ -3077,7 +3729,11 @@ void halrf_calculate_tssi_codeword(void *dm_void) if (dm->support_ic_type & ODM_RTL8814B) halrf_calculate_tssi_codeword_8814b(dm, RF_PATH_A); #endif - + +#if (RTL8822C_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8822C) + halrf_calculate_tssi_codeword_8822c(dm); +#endif } void halrf_set_tssi_codeword(void *dm_void) @@ -3087,11 +3743,17 @@ void halrf_set_tssi_codeword(void *dm_void) #if !(DM_ODM_SUPPORT_TYPE & ODM_IOT) struct _halrf_tssi_data *tssi = &rf->halrf_tssi_data; #endif - + #if (RTL8814B_SUPPORT == 1) if (dm->support_ic_type & ODM_RTL8814B) halrf_set_tssi_codeword_8814b(dm, tssi->tssi_codeword); #endif + +#if (RTL8822C_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8822C) + halrf_set_tssi_codeword_8822c(dm, tssi->tssi_codeword); +#endif + } u8 halrf_get_tssi_codeword_for_txindex(void *dm_void) @@ -3099,9 +3761,13 @@ u8 halrf_get_tssi_codeword_for_txindex(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; #if (RTL8814B_SUPPORT == 1) - if (dm->support_ic_type & ODM_RTL8814B) + if (dm->support_ic_type & ODM_RTL8814B) { +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) + return 80; +#else return 60; - /*return halrf_get_tssi_codeword_8814b(dm);*/ +#endif + } #endif #if (RTL8822C_SUPPORT == 1) @@ -3122,6 +3788,49 @@ u8 halrf_get_tssi_codeword_for_txindex(void *dm_void) return 60; } +void halrf_tssi_clean_de( + void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + +#if (RTL8812F_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8812F) + halrf_tssi_clean_de_8812f(dm); +#endif + +#if (RTL8814B_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8814B) + halrf_tssi_clean_de_8814b(dm); +#endif + +#if (RTL8197G_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8197G) + halrf_tssi_clean_de_8197g(dm); +#endif + +} + +u32 halrf_tssi_trigger_de(void *dm_void, u8 path) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + +#if (RTL8812F_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8812F) + return halrf_tssi_trigger_de_8812f(dm, path); +#endif + +#if (RTL8814B_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8814B) + return halrf_tssi_trigger_de_8814b(dm, path); +#endif + +#if (RTL8197G_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8197G) + return halrf_tssi_trigger_de_8197g(dm, path); +#endif + return 0; +} + u32 halrf_tssi_get_de(void *dm_void, u8 path) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -3145,12 +3854,43 @@ u32 halrf_tssi_get_de(void *dm_void, u8 path) if (dm->support_ic_type & ODM_RTL8197G) return halrf_tssi_get_de_8197g(dm, path); #endif + + return 0; +} + +u32 halrf_get_online_tssi_de(void *dm_void, u8 path, s32 pout) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + +#if (RTL8723F_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8723F) + return halrf_get_online_tssi_de_8723f(dm, path, pout); +#endif return 0; } void halrf_tssi_trigger(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; + struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info); + struct _hal_rf_ *rf = &(dm->rf_table); + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) + if (*dm->mp_mode == 1) { + if (cali_info->txpowertrack_control == 0 || + cali_info->txpowertrack_control == 1) { + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "[TSSI]======>%s MP Mode UI chose thermal tracking. return !!!\n", __func__); + return; + } + } else { + if (rf->power_track_type >= 0 && rf->power_track_type <= 3) { + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "[TSSI]======>%s Normal Mode efues is thermal tracking. return !!!\n", __func__); + return; + } + } +#endif halrf_calculate_tssi_codeword(dm); halrf_set_tssi_codeword(dm); @@ -3162,6 +3902,245 @@ void halrf_tssi_trigger(void *dm_void) halrf_do_tssi(dm); } +void halrf_txgapk_write_gain_table(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + +#if (RTL8822C_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8822C) + halrf_txgapk_save_all_tx_gain_table_8822c(dm); +#endif +} + +void halrf_txgapk_reload_tx_gain(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + +#if (RTL8822C_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8822C) + halrf_txgapk_reload_tx_gain_8822c(dm); +#endif +} + +void halrf_txgap_enable_disable(void *dm_void, u8 enable) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct _hal_rf_ *rf = &(dm->rf_table); + + if (enable) { + rf->rf_supportability = rf->rf_supportability | HAL_RF_TXGAPK; + halrf_txgapk_trigger(dm); + } else { + rf->rf_supportability = rf->rf_supportability & ~HAL_RF_TXGAPK; + halrf_txgapk_reload_tx_gain(dm); + } +} + +#if (RTL8723F_SUPPORT == 1) +void halrf_xtal_thermal_track(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct _hal_rf_ *rf = &dm->rf_table; + struct _halrf_tssi_data *tssi = &rf->halrf_tssi_data; + struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info); + s8 *delta_swing_table_xtal_up = NULL; + u8 xtal_offset_eanble = 0, i =0; + s8 thermal_value = 0, thermal_detla = 0; + u8 thermal_base = 0; + s8 xtal_table_up[DELTA_SWINGIDX_SIZE] = {0}; + s8 xtal_table_down[DELTA_SWINGIDX_SIZE] = {0}; + u32 reg_val = 0, crystal_cap = 0; + + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "[RF][xtal] ======>%s\n", __func__); + + if ( dm->support_ic_type == ODM_RTL8723F) { + if (rf->is_dpk_in_progress || dm->rf_calibrate_info.is_iqk_in_progress || + dm->is_psd_in_process || rf->is_tssi_in_progress || + !(rf->rf_supportability & HAL_RF_DPK_TRACK) || + rf->is_txgapk_in_progress) + return; + + if(tssi->thermal[0] == 0xff) { + //RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "[RF][xtal] thermal 0xFF, return!\n"); + return; + } else { + thermal_base = tssi->thermal[0]; + //RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "[RF][xtal] thermal_base = 0x%x\n", thermal_base); + } + + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "[RF][xtal] thermal_base = 0x%x\n", thermal_base); + + thermal_value = (s8)odm_get_rf_reg(dm, RF_PATH_A, RF_0x42, 0xfc00); /* 0x42: RF Reg[15:10]*/ + + thermal_detla = (s8)(thermal_value - thermal_base); + + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "[RF][xtal] cali_info->xtal_offset = 0x%x\n", cali_info->xtal_offset); + + cali_info->xtal_offset_last = cali_info->xtal_offset; + /* + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "[RF][Xtal] cali_info->delta_swing_table_xtal_p = %d\n", cali_info->delta_swing_table_xtal_p[2]); + */ + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "[RF][Xtal] thermal_value = 0x%x, thermal_detla = 0x%x, xtal_offset_last = 0x%x\n", + thermal_value, thermal_detla, cali_info->xtal_offset_last); + odm_move_memory(dm, xtal_table_up, cali_info->delta_swing_table_xtal_p, sizeof(xtal_table_up));//(void *) + odm_move_memory(dm, xtal_table_down, cali_info->delta_swing_table_xtal_n, sizeof(xtal_table_down)); + /* + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "[RF][Xtal] xtal_table_up[1] = %d\n", xtal_table_up[1]);*/ + if(thermal_detla < 0) { + + if (thermal_detla < -29) + i = 29; + else + i = (u8)(-1 * thermal_detla); + cali_info->xtal_offset = xtal_table_down[i]; + } else { + + if (thermal_detla >= 30) + i = 29; + else + i = thermal_detla; + + cali_info->xtal_offset = xtal_table_up[i]; + } + + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "[RF][Xtal] xtal_offset = %d\n", cali_info->xtal_offset); + if (cali_info->xtal_offset_last == cali_info->xtal_offset) + xtal_offset_eanble = 0; + else + xtal_offset_eanble = 1; + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "[RF][Xtal] xtal_offset_eanble = %d\n", xtal_offset_eanble); + if (xtal_offset_eanble != 0) { + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter Xtal Tracking**********\n"); + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "[RF][Xtal] R_0x103c[16:10] = 0x%x\n", odm_get_mac_reg(dm, R_0x103c, 0x0001FC00)); + + crystal_cap = dm->dm_cfo_track.crystal_cap_default & 0x7F; + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "[RF][Xtal] DEFAULT crystal_cap = 0x%x\n", crystal_cap); + reg_val = crystal_cap + cali_info->xtal_offset; + //reg_val = (u32)(odm_get_mac_reg(dm, R_0x103c, 0x0001FC00) + cali_info->xtal_offset); + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "[RF][Xtal] reg_val = 0x%x\n", reg_val); + /* write 0x103c[23:17] = 0x103c[16:10] = crystal_cap */ + crystal_cap = reg_val | (reg_val << 7); + odm_set_mac_reg(dm, R_0x103c, 0x00FFFC00, crystal_cap); + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "[RF][Xtal] R_0x103c[16:10] = 0x%x\n", odm_get_mac_reg(dm, R_0x103c, 0x0001FC00)); + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "[RF][Xtal] R_0x103c[23:17] = 0x%x\n", odm_get_mac_reg(dm, R_0x103c, 0x00FE0000)); + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********End Xtal Tracking**********\n"); + } + odm_set_rf_reg(dm, RF_PATH_A, RF_0x42, 0x30000, 0x3); + //delay + } + /*RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "[RF][xtal] <======%s\n", __func__);*/ +} +#endif + +void _halrf_dump_subpage(void *dm_void, u32 *_used, char *output, u32 *_out_len, u8 page) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + u32 used = *_used; + u32 out_len = *_out_len; + u32 addr; + + PDM_SNPF(out_len, used, output + used, out_len - used, + "\n===============[ Subpage_%d start]===============\n", page); + + RF_DBG(dm, DBG_RF_RFK, " ===============[ Subpage_%d start]===============\n", page); + + odm_set_bb_reg(dm, R_0x1b00, BIT(2) | BIT(1), page); + + for (addr = 0x1b00; addr < 0x1c00; addr += 0x10) { + PDM_SNPF(out_len, used, output + used, out_len - used, + " 0x%x : 0x%08x 0x%08x 0x%08x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD), + odm_get_bb_reg(dm, addr + 0x4, MASKDWORD), + odm_get_bb_reg(dm, addr + 0x8, MASKDWORD), + odm_get_bb_reg(dm, addr + 0xc, MASKDWORD)); + RF_DBG(dm, DBG_RF_RFK, " 0x%x : 0x%08x 0x%08x 0x%08x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD), + odm_get_bb_reg(dm, addr + 0x4, MASKDWORD), + odm_get_bb_reg(dm, addr + 0x8, MASKDWORD), + odm_get_bb_reg(dm, addr + 0xc, MASKDWORD)); + } + + *_used = used; + *_out_len = out_len; +} + +void halrf_dump_rfk_reg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct _hal_rf_ *rf = &dm->rf_table; + + char help[] = "-h"; + u32 var1[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u32 reg_1b00, supportability; + u8 page; + + if (!(dm->support_ic_type & (ODM_IC_11AC_SERIES | ODM_IC_JGR3_SERIES))) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "CMD is Unsupported due to IC type!!!\n"); + RF_DBG(dm, DBG_RF_RFK, "[RFK] CMD is Unsupported due to IC type!!!\n"); + return; + } else if (rf->is_dpk_in_progress || dm->rf_calibrate_info.is_iqk_in_progress || + dm->is_psd_in_process || rf->is_tssi_in_progress || rf->is_txgapk_in_progress) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "Bypass CMD due to RFK is doing!!!\n"); + RF_DBG(dm, DBG_RF_RFK, "[RFK] Bypass CMD due to RFK is doing!!!\n"); + return; + } + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + if (*dm->is_fcs_mode_enable) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "Bypass CMD due to FCS mode!!!\n"); + RF_DBG(dm, DBG_RF_RFK, "[RFK] Bypass CMD due to FCS mode!!!\n"); + return; + } +#endif + supportability = rf->rf_supportability; + + /*to avoid DPK track interruption*/ + rf->rf_supportability = rf->rf_supportability & ~HAL_RF_DPK_TRACK; + + reg_1b00 = odm_get_bb_reg(dm, R_0x1b00, MASKDWORD); + + if (input[2]) + PHYDM_SSCANF(input[2], DCMD_DECIMAL, &var1[0]); + + if ((strcmp(input[2], help) == 0)) + PDM_SNPF(out_len, used, output + used, out_len - used, + "dump subpage {0:Page0, 1:Page1, 2:Page2, 3:Page3, 4:all}\n"); + else if (var1[0] > 4) + PDM_SNPF(out_len, used, output + used, out_len - used, + "Wrong subpage number!!\n"); + else if (var1[0] == 4) { + for (page = 0; page < 4; page++) + _halrf_dump_subpage(dm, &used, output, &out_len, page); + } else + _halrf_dump_subpage(dm, &used, output, &out_len, (u8)var1[0]); + + odm_set_bb_reg(dm, R_0x1b00, MASKDWORD, reg_1b00); + + rf->rf_supportability = supportability; + + *_used = used; + *_out_len = out_len; +} + /*Golbal function*/ void halrf_reload_bp(void *dm_void, u32 *bp_reg, u32 *bp, u32 num) { @@ -3438,4 +4417,11 @@ void halrf_mode(void *dm_void, u32 *i_value, u32 *q_value) *q_value = t; #endif } +void halrf_delay_10us(u16 v1) +{ + u16 i = 0; + + for (i = 0; i < v1; i++) + ODM_delay_us(10); +} diff --git a/hal/phydm/halrf/halrf.h b/hal/phydm/halrf/halrf.h index 7219224..33fbf9b 100644 --- a/hal/phydm/halrf/halrf.h +++ b/hal/phydm/halrf/halrf.h @@ -38,6 +38,7 @@ #include "halrf/rtl8822c/halrf_iqk_8822c.h" #include "halrf/rtl8822c/halrf_tssi_8822c.h" #include "halrf/rtl8822c/halrf_dpk_8822c.h" +#include "halrf/rtl8822c/halrf_txgapk_8822c.h" #endif #if (DM_ODM_SUPPORT_TYPE & ODM_AP) @@ -57,6 +58,7 @@ #include "halrf/rtl8814b/halrf_rfk_init_8814b.h" #include "halrf/rtl8814b/halrf_iqk_8814b.h" #include "halrf/rtl8814b/halrf_dpk_8814b.h" +#include "halrf/rtl8814b/halrf_txgapk_8814b.h" #endif /*@============================================================*/ @@ -69,12 +71,12 @@ #define IQK_VER_8192F "0x01" #define IQK_VER_8723B "0x1e" #define IQK_VER_8812A "0x02" -#define IQK_VER_8821A "0x01" +#define IQK_VER_8821A "0x02" #elif (DM_ODM_SUPPORT_TYPE & (ODM_CE)) #define IQK_VER_8188E "0x01" #define IQK_VER_8192E "0x01" #define IQK_VER_8192F "0x01" -#define IQK_VER_8723B "0x1e" +#define IQK_VER_8723B "0x1f" #define IQK_VER_8812A "0x01" #define IQK_VER_8821A "0x01" #elif (DM_ODM_SUPPORT_TYPE & (ODM_AP)) @@ -99,19 +101,21 @@ #define IQK_VER_8710B "0x01" #define IQK_VER_8723D "0x02" #define IQK_VER_8822B "0x32" -#define IQK_VER_8822C "0x0c" +#define IQK_VER_8822C "0x14" #define IQK_VER_8821C "0x23" -#define IQK_VER_8198F "0x0a" -#define IQK_VER_8814B "0x0e" -#define IQK_VER_8812F "0x08" -#define IQK_VER_8710C "0x05" -#define IQK_VER_8197G "0x02" +#define IQK_VER_8198F "0x0b" +#define IQK_VER_8814B "0x15" +#define IQK_VER_8812F "0x0c" +#define IQK_VER_8710C "0x0a" +#define IQK_VER_8197G "0x03" +#define IQK_VER_8723F "0x00" + /*LCK version*/ -#define LCK_VER_8188E "0x01" -#define LCK_VER_8192E "0x01" +#define LCK_VER_8188E "0x02" +#define LCK_VER_8192E "0x02" #define LCK_VER_8192F "0x01" -#define LCK_VER_8723B "0x01" +#define LCK_VER_8723B "0x02" #define LCK_VER_8812A "0x01" #define LCK_VER_8821A "0x01" #define LCK_VER_8814A "0x01" @@ -122,11 +126,12 @@ #define LCK_VER_8723D "0x01" #define LCK_VER_8822B "0x02" #define LCK_VER_8822C "0x00" -#define LCK_VER_8821C "0x02" -#define LCK_VER_8814B "0x01" +#define LCK_VER_8821C "0x03" +#define LCK_VER_8814B "0x02" #define LCK_VER_8195B "0x02" -#define LCK_VER_8710C "0x01" -#define LCK_VER_8197G "0x00" +#define LCK_VER_8710C "0x02" +#define LCK_VER_8197G "0x01" +#define LCK_VER_8198F "0x01" /*power tracking version*/ #define PWRTRK_VER_8188E "0x01" @@ -160,27 +165,31 @@ #define DPK_VER_8710B "NONE" #define DPK_VER_8723D "NONE" #define DPK_VER_8822B "NONE" -#define DPK_VER_8822C "0x19" +#define DPK_VER_8822C "0x20" #define DPK_VER_8821C "NONE" -#define DPK_VER_8192F "0x0d" +#define DPK_VER_8192F "0x11" #define DPK_VER_8198F "0x0e" -#define DPK_VER_8814B "0x08" -#define DPK_VER_8195B "0x0b" -#define DPK_VER_8812F "0x06" -#define DPK_VER_8197G "0x04" +#define DPK_VER_8814B "0x0f" +#define DPK_VER_8195B "0x0c" +#define DPK_VER_8812F "0x0a" +#define DPK_VER_8197G "0x09" /*RFK_INIT version*/ #define RFK_INIT_VER_8822B "0x8" -#define RFK_INIT_VER_8822C "0x7" +#define RFK_INIT_VER_8822C "0x8" #define RFK_INIT_VER_8195B "0x1" #define RFK_INIT_VER_8198F "0x8" #define RFK_INIT_VER_8814B "0xa" -#define RFK_INIT_VER_8812F "0x3" -#define RFK_INIT_VER_8197G "0x3" +#define RFK_INIT_VER_8812F "0x4" +#define RFK_INIT_VER_8197G "0x4" /*DACK version*/ -#define DACK_VER_8822C "0x6" -#define DACK_VER_8814B "0x3" +#define DACK_VER_8822C "0xa" +#define DACK_VER_8814B "0x4" + +/*TXGAPK version*/ +#define TXGAPK_VER_8814B "0x1" +#define TXGAPK_VER_8195B "0x2" /*Kfree tracking version*/ #define KFREE_VER_8188E \ @@ -223,6 +232,7 @@ #define TSSI_VER_8821C "0x1" #define TSSI_VER_8814B "0x1" #define TSSI_VER_8197G "0x1" +#define TSSI_VER_8723F "0x1" /*PA Bias Calibration version*/ #define PABIASK_VER_8188E \ @@ -278,6 +288,7 @@ (dm->support_ic_type == ODM_RTL8821C) ? IQK_VER_8821C : \ (dm->support_ic_type == ODM_RTL8814B) ? IQK_VER_8814B : \ (dm->support_ic_type == ODM_RTL8710C) ? IQK_VER_8710C : \ + (dm->support_ic_type == ODM_RTL8723F) ? IQK_VER_8723F : \ (dm->support_ic_type == ODM_RTL8197G) ? IQK_VER_8197G : "unknown" #define HALRF_LCK_VER \ @@ -333,6 +344,7 @@ (dm->support_ic_type == ODM_RTL8723D) ? DPK_VER_8723D : \ (dm->support_ic_type == ODM_RTL8822B) ? DPK_VER_8822B : \ (dm->support_ic_type == ODM_RTL8822C) ? DPK_VER_8822C : \ + (dm->support_ic_type == ODM_RTL8812F) ? DPK_VER_8812F : \ (dm->support_ic_type == ODM_RTL8821C) ? DPK_VER_8821C : \ (dm->support_ic_type == ODM_RTL8814B) ? DPK_VER_8814B : \ (dm->support_ic_type == ODM_RTL8197G) ? DPK_VER_8197G : "unknown" @@ -361,7 +373,8 @@ (dm->support_ic_type == ODM_RTL8822C) ? TSSI_VER_8822C : \ (dm->support_ic_type == ODM_RTL8821C) ? TSSI_VER_8821C : \ (dm->support_ic_type == ODM_RTL8814B) ? TSSI_VER_8814B : \ - (dm->support_ic_type == ODM_RTL8197G) ? TSSI_VER_8197G : "unknown" + (dm->support_ic_type == ODM_RTL8197G) ? TSSI_VER_8197G : \ + (dm->support_ic_type == ODM_RTL8723F) ? TSSI_VER_8723F : "unknown" #define HALRF_PABIASK_VER \ (dm->support_ic_type == ODM_RTL8188E) ? PABIASK_VER_8188E : \ @@ -385,6 +398,7 @@ #define HALRF_RFK_INIT_VER \ (dm->support_ic_type == ODM_RTL8822B) ? RFK_INIT_VER_8822B : \ (dm->support_ic_type == ODM_RTL8822C) ? RFK_INIT_VER_8822C : \ + (dm->support_ic_type == ODM_RTL8812F) ? RFK_INIT_VER_8812F : \ (dm->support_ic_type == ODM_RTL8198F) ? RFK_INIT_VER_8198F : \ (dm->support_ic_type == ODM_RTL8814B) ? RFK_INIT_VER_8814B : \ (dm->support_ic_type == ODM_RTL8197G) ? RFK_INIT_VER_8197G : "unknown" @@ -423,7 +437,9 @@ enum halrf_func_idx { /*F_XXX = PHYDM XXX function*/ RF04_TXGAPK = 4, RF05_DACK = 5, RF06_DPK_TRK = 6, - RF07_2GBAND_SHIFT = 7 + RF07_2GBAND_SHIFT = 7, + RF08_RXDCK = 8, + RF09_RFK = 9 }; enum halrf_ability { @@ -434,7 +450,8 @@ enum halrf_ability { HAL_RF_TXGAPK = BIT(RF04_TXGAPK), HAL_RF_DACK = BIT(RF05_DACK), HAL_RF_DPK_TRACK = BIT(RF06_DPK_TRK), - HAL_2GBAND_SHIFT = BIT(RF07_2GBAND_SHIFT) + HAL_2GBAND_SHIFT = BIT(RF07_2GBAND_SHIFT), + HAL_RF_RXDCK = BIT(RF08_RXDCK) }; enum halrf_shift_band { @@ -450,6 +467,8 @@ enum halrf_dbg_comp { DBG_RF_DPK = BIT(RF03_DPK), DBG_RF_TXGAPK = BIT(RF04_TXGAPK), DBG_RF_DACK = BIT(RF05_DACK), + DBG_RF_DPK_TRACK = BIT(RF06_DPK_TRK), + DBG_RF_RFK = BIT(RF09_RFK), DBG_RF_MP = BIT(29), DBG_RF_TMP = BIT(30), DBG_RF_INIT = BIT(31) @@ -467,7 +486,9 @@ enum halrf_cmninfo_init { HALRF_CMNINFO_MP_PSD_START_POINT, HALRF_CMNINFO_MP_PSD_STOP_POINT, HALRF_CMNINFO_MP_PSD_AVERAGE, - HALRF_CMNINFO_IQK_TIMES + HALRF_CMNINFO_IQK_TIMES, + HALRF_CMNINFO_MP_POWER_TRACKING_TYPE, + HALRF_CMNINFO_POWER_TRACK_CONTROL }; enum halrf_cmninfo_hook { @@ -500,6 +521,7 @@ enum halrf_k_segment_time { #define TSSI_EFUSE_NUM 25 #define TSSI_EFUSE_KFREE_NUM 4 +#define TSSI_DE_DIFF_EFUSE_NUM 10 struct _halrf_tssi_data { s32 cck_offset_patha; @@ -509,6 +531,7 @@ struct _halrf_tssi_data { s16 txagc_codeword[TSSI_CODE_NUM]; u16 tssi_codeword[TSSI_CODE_NUM]; s8 tssi_efuse[PHYDM_MAX_RF_PATH][TSSI_EFUSE_NUM]; + s8 tssi_de_diff_efuse[PHYDM_MAX_RF_PATH][TSSI_DE_DIFF_EFUSE_NUM]; s8 tssi_kfree_efuse[PHYDM_MAX_RF_PATH][TSSI_EFUSE_KFREE_NUM]; u8 thermal[PHYDM_MAX_RF_PATH]; u32 index[PHYDM_MAX_RF_PATH][14]; @@ -516,8 +539,18 @@ struct _halrf_tssi_data { u8 get_thermal; u8 tssi_finish_bit[PHYDM_MAX_RF_PATH]; u8 thermal_trigger; + s8 tssi_de; }; +struct _halrf_txgapk_info { + u32 txgapk_rf3f_bp[5][12][PHYDM_MAX_RF_PATH]; /* band(2Gcck/2GOFDM/5GL/5GM/5GH)/idx/path */ + boolean txgapk_bp_done; + s8 offset[12][PHYDM_MAX_RF_PATH]; + s8 fianl_offset[12][PHYDM_MAX_RF_PATH]; + u8 read_txgain; +}; + + /*@============================================================*/ /*@ structure */ /*@============================================================*/ @@ -544,18 +577,29 @@ struct _hal_rf_ { boolean is_dpk_in_progress; boolean is_tssi_in_progress; boolean is_bt_iqk_timeout; + boolean is_rfk_h2c_timeout; boolean aac_checked; + boolean is_txgapk_in_progress; u8 *mp_rate_index; u32 *manual_rf_supportability; u32 p_rate_index; u8 pwt_type; u32 rf_dbg_comp; + u8 rfk_type; + u32 gnt_control; + + u8 ext_lna; /*@with 2G external LNA NO/Yes = 0/1*/ + u8 ext_lna_5g; /*@with 5G external LNA NO/Yes = 0/1*/ + u8 ext_pa; /*@with 2G external PNA NO/Yes = 0/1*/ + u8 ext_pa_5g; /*@with 5G external PNA NO/Yes = 0/1*/ #if !(DM_ODM_SUPPORT_TYPE & ODM_IOT) struct _halrf_psd_data halrf_psd_data; struct _halrf_tssi_data halrf_tssi_data; #endif + struct _halrf_txgapk_info halrf_txgapk_info; u8 power_track_type; + u8 mp_pwt_type; u8 pre_band_type; }; @@ -625,6 +669,8 @@ u32 halrf_psd_log2base(u32 val); void halrf_dpk_trigger(void *dm_void); +void halrf_txgapk_trigger(void *dm_void); + u8 halrf_dpk_result_check(void *dm_void); void halrf_dpk_sram_read(void *dm_void); @@ -635,6 +681,13 @@ void halrf_dpk_track(void *dm_void); void halrf_dpk_reload(void *dm_void); +void halrf_dpk_switch(void *dm_void, u8 enable); + +void halrf_dpk_debug_cmd(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); + +void halrf_dpk_c2h_report_transfer(void *dm_void, boolean is_ok, u8 *buf, u8 buf_size); + void halrf_dpk_info_rsvd_page(void *dm_void, u8 *buf, u32 *buf_size); /*Global function*/ @@ -677,6 +730,8 @@ void halrf_tssi_get_efuse(void *dm_void); void halrf_do_tssi(void *dm_void); +void halrf_set_tssi_enable(void *dm_void, boolean enable); + void halrf_do_thermal(void *dm_void); u32 halrf_set_tssi_value(void *dm_void, u32 tssi_value); @@ -701,10 +756,22 @@ void halrf_set_tssi_codeword(void *dm_void); u8 halrf_get_tssi_codeword_for_txindex(void *dm_void); +void halrf_tssi_clean_de(void *dm_void); + +u32 halrf_tssi_trigger_de(void *dm_void, u8 path); + u32 halrf_tssi_get_de(void *dm_void, u8 path); +u32 halrf_get_online_tssi_de(void *dm_void, u8 path, s32 pout); + void halrf_tssi_trigger(void *dm_void); +void halrf_txgapk_write_gain_table(void *dm_void); + +void halrf_txgapk_reload_tx_gain(void *dm_void); + +void halrf_txgap_enable_disable(void *dm_void, u8 enable); + void halrf_set_dpk_track(void *dm_void, u8 enable); void halrf_set_dpkbychannel(void *dm_void, boolean dpk_by_ch); @@ -725,7 +792,23 @@ void halrf_reload_iqk(void *dm_void, boolean reset); void halrf_dack_dbg(void *dm_void); +void halrf_dack_trigger(void *dm_void, boolean force); + +void halrf_dack_restore(void *dm_void); + void halrf_iqk_info_rsvd_page(void *dm_void, u8 *buf, u32 *buf_size); void halrf_set_rfsupportability(void *dm_void); + +void halrf_rxdck(void *dm_void); + +void halrf_delay_10us(u16 v1); + +void halrf_dump_rfk_reg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); + +void halrf_xtal_thermal_track(void *dm_void); + +void halrf_rfk_power_save(void *dm_void, boolean is_power_save); + #endif /*__HALRF_H__*/ diff --git a/hal/phydm/halrf/halrf_debug.c b/hal/phydm/halrf/halrf_debug.c index 9c1783a..3f2d142 100644 --- a/hal/phydm/halrf/halrf_debug.c +++ b/hal/phydm/halrf/halrf_debug.c @@ -89,7 +89,7 @@ void halrf_basic_profile(void *dm_void, u32 *_used, char *output, u32 *_out_len) #endif #if (RTL8192F_SUPPORT) - case ODM_RTL8197F: + case ODM_RTL8192F: rf_release_ver = RF_RELEASE_VERSION_8192F; break; #endif @@ -173,6 +173,9 @@ void halrf_debug_trace(void *dm_void, char input[][16], u32 *_used, PDM_SNPF(out_len, used, output + used, out_len - used, "04. (( %s ))TXGAPK\n", ((rf->rf_dbg_comp & DBG_RF_TXGAPK) ? ("V") : ("."))); + PDM_SNPF(out_len, used, output + used, out_len - used, + "06. (( %s ))DPK_TRACK\n", + ((rf->rf_dbg_comp & DBG_RF_DPK_TRACK) ? ("V") : ("."))); PDM_SNPF(out_len, used, output + used, out_len - used, "29. (( %s ))MP\n", ((rf->rf_dbg_comp & DBG_RF_MP) ? ("V") : ("."))); @@ -200,6 +203,23 @@ void halrf_debug_trace(void *dm_void, char input[][16], u32 *_used, *_out_len = out_len; } +void halrf_dack_debug_cmd(void *dm_void, char input[][16]) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct _hal_rf_ *rf = &dm->rf_table; + u32 dm_value[10] = {0}; + u8 i; + + for (i = 0; i < 7; i++) + if (input[i + 1]) + PHYDM_SSCANF(input[i + 2], DCMD_DECIMAL, &dm_value[i]); + + if (dm_value[0] == 1) + halrf_dack_trigger(dm, true); + else + halrf_dack_trigger(dm, false); +} + struct halrf_command { char name[16]; u8 id; @@ -214,6 +234,9 @@ enum halrf_CMD_ID { HALRF_IQK, HALRF_IQK_DEBUG, HALRF_DPK, + HALRF_DACK, + HALRF_DACK_DEBUG, + HALRF_DUMP_RFK_REG, #ifdef CONFIG_2G_BAND_SHIFT HAL_BAND_SHIFT, #endif @@ -226,8 +249,11 @@ struct halrf_command halrf_cmd_ary[] = { {"profile", HALRF_PROFILE}, {"iqk_info", HALRF_IQK_INFO}, {"iqk", HALRF_IQK}, - {"dpk", HALRF_DPK}, {"iqk_dbg", HALRF_IQK_DEBUG}, + {"dpk", HALRF_DPK}, + {"dack", HALRF_DACK}, + {"dack_dbg", HALRF_DACK_DEBUG}, + {"dump_rfk_reg", HALRF_DUMP_RFK_REG}, #ifdef CONFIG_2G_BAND_SHIFT {"band_shift", HAL_BAND_SHIFT}, #endif @@ -300,7 +326,8 @@ void halrf_cmd_parser(void *dm_void, char input[][16], u32 *_used, char *output, #endif break; case HALRF_IQK_DEBUG: - + PDM_SNPF(out_len, used, output + used, out_len - used, + "IQK DEBUG!!!!!\n"); for (i = 0; i < 5; i++) { if (input[i + 1]) { PHYDM_SSCANF(input[i + 2], DCMD_HEX, @@ -310,17 +337,28 @@ void halrf_cmd_parser(void *dm_void, char input[][16], u32 *_used, char *output, } if (input_idx >= 1) { -#if (RTL8822B_SUPPORT == 1 || RTL8821C_SUPPORT == 1) - if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C)) +#if (RTL8822B_SUPPORT == 1 || RTL8821C_SUPPORT == 1 || RTL8822C_SUPPORT == 1 || RTL8814B_SUPPORT == 1) + if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C | ODM_RTL8822C | ODM_RTL8814B)) halrf_iqk_debug(dm, (u32 *)rf_var, &used, output, &out_len); #endif } break; case HALRF_DPK: + halrf_dpk_debug_cmd(dm, input, &used, output, &out_len); + break; + case HALRF_DACK: PDM_SNPF(out_len, used, output + used, out_len - used, - "DPK Trigger\n"); - halrf_dpk_trigger(dm); + "DACK Trigger\n"); + halrf_dack_debug_cmd(dm, &input[0]); + break; + case HALRF_DACK_DEBUG: + PDM_SNPF(out_len, used, output + used, out_len - used, + "DACK DEBUG\n"); + halrf_dack_dbg(dm); + break; + case HALRF_DUMP_RFK_REG: + halrf_dump_rfk_reg(dm, input, &used, output, &out_len); break; default: break; @@ -337,15 +375,18 @@ void halrf_init_debug_setting(void *dm_void) struct _hal_rf_ *rf = &dm->rf_table; rf->rf_dbg_comp = + + DBG_RF_RFK | #if DBG -#if 0 - /*DBG_RF_TX_PWR_TRACK |*/ +#if 1 + /*DBG_RF_TX_PWR_TRACK | */ /*DBG_RF_IQK | */ /*DBG_RF_LCK | */ /*DBG_RF_DPK | */ - /*DBG_RF_DACK | */ /*DBG_RF_TXGAPK | */ - /*DBG_RF_MP | */ + /*DBG_RF_DACK | */ + /*DBG_RF_DPK_TRACK | */ + /*DBG_RF_MP | */ /*DBG_RF_TMP | */ /*DBG_RF_INIT | */ #endif diff --git a/hal/phydm/halrf/halrf_debug.h b/hal/phydm/halrf/halrf_debug.h index ff1ff96..c13f3c5 100644 --- a/hal/phydm/halrf/halrf_debug.h +++ b/hal/phydm/halrf/halrf_debug.h @@ -96,6 +96,23 @@ static __inline void RF_DBG(PDM_ODM_T dm, int comp, char *fmt, ...) #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) static __inline void RF_DBG(struct dm_struct *dm, int comp, char *fmt, ...) { +#if 0 + RT_STATUS rt_status; + va_list args; + char buf[128] = {0};/*PRINT_MAX_SIZE*/ + + if ((comp & dm->rf_table.rf_dbg_comp) == 0) + return; + + if (NULL != fmt) { + va_start(args, fmt); + rt_status = (RT_STATUS)RtlStringCbVPrintfA(buf, sizeof(buf), fmt, args); + va_end(args); + if (rt_status == RT_STATUS_SUCCESS) { + halrf_rt_trace(buf); + } + } +#endif } #else #define RF_DBG(dm, comp, fmt, args...) diff --git a/hal/phydm/halrf/halrf_dpk.h b/hal/phydm/halrf/halrf_dpk.h index e3abe2d..cb7dc4e 100644 --- a/hal/phydm/halrf/halrf_dpk.h +++ b/hal/phydm/halrf/halrf_dpk.h @@ -43,6 +43,22 @@ #define AVG_THERMAL_NUM_DPK 8 #define THERMAL_DPK_AVG_NUM 4 +/*define RF path numer*/ +#if (RTL8198F_SUPPORT == 1 || RTL8814B_SUPPORT == 1) +#define KPATH 4 +#elif (RTL8192F_SUPPORT == 1 || RTL8197F_SUPPORT == 1 ||RTL8197G_SUPPORT == 1 ||\ + RTL8822C_SUPPORT == 1 || RTL8812F_SUPPORT == 1 || RTL8723F_SUPPORT == 1) +#define KPATH 2 +#else +#define KPATH 1 +#endif + +#if (RTL8814B_SUPPORT == 1 || RTL8721D_SUPPORT == 1) +#define GROUP_5G 6 +#elif (RTL8195B_SUPPORT == 1) +#define GROUP_5G 13 +#endif + /*@---------------------------End Define Parameters---------------------------*/ struct dm_dpk_info { @@ -51,19 +67,30 @@ struct dm_dpk_info { boolean is_dpk_pwr_on; boolean is_dpk_by_channel; boolean is_tssi_mode; - boolean is_reload; - u16 dpk_path_ok; + u8 dpk_status; /*bit[0]:reload;bit[1]:cal;bit[2]:cal_ok*/ + u16 dpk_path_ok; /*@BIT(15)~BIT(12) : 5G reserved, BIT(11)~BIT(8) 5G_S3~5G_S0*/ /*@BIT(7)~BIT(4) : 2G reserved, BIT(3)~BIT(0) 2G_S3~2G_S0*/ - u8 thermal_dpk[4]; /*path*/ - u8 thermal_dpk_avg[4][AVG_THERMAL_NUM_DPK]; /*path*/ - u8 pre_pwsf[4]; + u8 thermal_dpk[KPATH]; /*path*/ + u8 thermal_dpk_avg[KPATH][AVG_THERMAL_NUM_DPK]; /*path*/ + u8 pre_pwsf[KPATH]; u8 thermal_dpk_avg_index; u32 gnt_control; u32 gnt_value; u8 dpk_ch; u8 dpk_band; u8 dpk_bw; + u32 dpk_rf18[2]; + u32 dpk_cal_cnt; + u32 dpk_ok_cnt; + u32 dpk_reload_cnt; + +#if (RTL8822C_SUPPORT == 1 || RTL8812F_SUPPORT == 1 || RTL8197G_SUPPORT == 1) + u16 dc_i[2]; /*MDPD DC I path*/ + u16 dc_q[2]; /*MDPD DC Q path*/ + u8 corr_val[2]; /*Corr value path*/ + u8 corr_idx[2]; /*Corr index path*/ +#endif #if (RTL8822C_SUPPORT == 1 || RTL8812F_SUPPORT == 1) u8 result[2]; /*path*/ @@ -74,52 +101,63 @@ struct dm_dpk_info { #endif #if (RTL8198F_SUPPORT == 1 || RTL8192F_SUPPORT == 1 || RTL8197F_SUPPORT == 1 ||\ - RTL8814B_SUPPORT == 1 || RTL8197G_SUPPORT == 1) + RTL8814B_SUPPORT == 1 || RTL8197G_SUPPORT == 1) /*2G DPK data*/ - u8 dpk_result[4][3]; /*path/group*/ - u8 pwsf_2g[4][3]; /*path/group*/ - u32 lut_2g_even[4][3][64]; /*path/group/LUT data*/ - u32 lut_2g_odd[4][3][64]; /*path/group/LUT data*/ + u8 dpk_result[KPATH][3]; /*path/group*/ + u8 pwsf_2g[KPATH][3]; /*path/group*/ + u32 lut_2g_even[KPATH][3][64]; /*path/group/LUT data*/ + u32 lut_2g_odd[KPATH][3][64]; /*path/group/LUT data*/ s16 tmp_pas_i[32]; /*PAScan I data*/ s16 tmp_pas_q[32]; /*PAScan Q data*/ +#endif + +#if (RTL8814B_SUPPORT == 1) /*5G DPK data*/ - u8 dpk_5g_result[4][6]; /*path/group*/ - u8 pwsf_5g[4][6]; /*path/group*/ - u32 lut_5g[4][6][64]; /*path/group/LUT data*/ - u32 lut_2g[4][3][64]; /*path/group/LUT data*/ - /*8814B*/ + u8 dpk_5g_result[KPATH][GROUP_5G]; /*path/group*/ + u8 pwsf_5g[KPATH][GROUP_5G]; /*path/group*/ + u32 lut_5g[KPATH][GROUP_5G][64]; /*path/group/LUT data*/ + u32 lut_2g[KPATH][3][64]; /*path/group/LUT data*/ u8 rxbb[4]; /*path/group*/ u8 txbb[4]; /*path/group*/ u8 tx_gain; #endif -#if (RTL8195B_SUPPORT == 1) - /*2G DPK data*/ - u8 dpk_2g_result[1][3]; /*path/group*/ - u8 pwsf_2g[1][3]; /*path/group*/ - u32 lut_2g_even[1][3][16]; /*path/group/LUT data*/ - u32 lut_2g_odd[1][3][16]; /*path/group/LUT data*/ - /*5G DPK data*/ - u8 dpk_5g_result[1][13]; /*path/group*/ - u8 pwsf_5g[1][13]; /*path/group*/ - u32 lut_5g_even[1][13][16]; /*path/group/LUT data*/ - u32 lut_5g_odd[1][13][16]; /*path/group/LUT data*/ -#endif - -#if (RTL8721D_SUPPORT == 1) +#if (RTL8195B_SUPPORT == 1 || RTL8721D_SUPPORT == 1) u8 dpk_txagc; /*2G DPK data*/ - u8 dpk_2g_result[1][3]; /*path/group*/ - u8 pwsf_2g[1][3]; /*path/group*/ - u32 lut_2g_even[1][3][16]; /*path/group/LUT data*/ - u32 lut_2g_odd[1][3][16]; /*path/group/LUT data*/ + u8 dpk_2g_result[KPATH][3]; /*path/group*/ + u8 pwsf_2g[KPATH][3]; /*path/group*/ + u32 lut_2g_even[KPATH][3][16]; /*path/group/LUT data*/ + u32 lut_2g_odd[KPATH][3][16]; /*path/group/LUT data*/ /*5G DPK data*/ - u8 dpk_5g_result[1][6]; /*path/group*/ - u8 pwsf_5g[1][6]; /*path/group*/ - u32 lut_5g_even[1][6][16]; /*path/group/LUT data*/ - u32 lut_5g_odd[1][6][16]; /*path/group/LUT data*/ + u8 dpk_5g_result[KPATH][GROUP_5G]; /*path/group*/ + u8 pwsf_5g[KPATH][GROUP_5G]; /*path/group*/ + u32 lut_5g_even[KPATH][GROUP_5G][16]; /*path/group/LUT data*/ + u32 lut_5g_odd[KPATH][GROUP_5G][16]; /*path/group/LUT data*/ #endif +#if(RTL8723F_SUPPORT == 1) + u8 one_shot_cnt; + u8 dpk_current_path; + u8 thermal_init[KPATH]; + u8 dpk_delta_thermal[KPATH]; /*path*/ + s8 last_offset[KPATH]; /*path*/ + u8 txagc[KPATH]; /*path*/ + u8 tssi_txagc[KPATH][2]; /*path/0:txagc_rf,1:tssi_offset*/ + u16 digital_bbgain[KPATH]; /*path*/ + u16 pwsf[KPATH]; /*path*/ + +#endif }; +#if (RTL8822C_SUPPORT == 1) +struct dm_dpk_c2h_report { + u8 result[2]; /*ch0_result/ch1_result*/ + u8 therm[2][2]; /*therm0_s0/therm0_s1/therm1_s0/therm1_s1*/ + u8 therm_delta[2][2]; /*therm_delta0_s0/therm_delta0_s1/therm_delta1_s0/therm_delta1_s1*/ + u32 dpk_rf18[2]; /*dpk_ch0/dpk_ch1*/ + u8 dpk_status; /*dpk_status*/ +}; +#endif + #endif /*__HALRF_DPK_H__*/ diff --git a/hal/phydm/halrf/halrf_iqk.h b/hal/phydm/halrf/halrf_iqk.h index f066636..8a37d01 100644 --- a/hal/phydm/halrf/halrf_iqk.h +++ b/hal/phydm/halrf/halrf_iqk.h @@ -39,16 +39,24 @@ #define rxiqk_gs_limit 6 #define TXWBIQK_EN 1 #define RXWBIQK_EN 1 +#if (RTL8814A_SUPPORT == 1 || RTL8198F_SUPPORT == 1 ||\ + RTL8814B_SUPPORT) #define NUM 4 +#elif (RTL8822B_SUPPORT == 1 || RTL8822C_SUPPORT == 1 ||\ + RTL8812F_SUPPORT == 1 || RTL8197G_SUPPORT == 1 ||\ + RTL8723F_SUPPORT == 1) +#define NUM 2 +#else +#define NUM 1 +#endif + /*@-----------------------End Define Parameters-----------------------*/ struct dm_dack_info { - u32 ic_a; - u32 qc_a; - u32 ic_b; - u32 qc_b; boolean dack_en; u16 msbk_d[2][2][15]; + u8 dck_d[2][2][2]; + u16 biask_d[2][2]; }; struct dm_iqk_info { @@ -70,37 +78,52 @@ struct dm_iqk_info { u8 rxbb; u32 rf_reg58; boolean segment_iqk; + boolean is_tssi_mode; + u8 iqk_band; + u8 iqk_ch; + u8 iqk_bw; #if (RTL8814A_SUPPORT == 1 || RTL8822B_SUPPORT == 1 || RTL8821C_SUPPORT == 1 ||\ RTL8195B_SUPPORT == 1 || RTL8198F_SUPPORT == 1 ||\ RTL8814B_SUPPORT == 1 || RTL8822C_SUPPORT == 1 ||\ RTL8812F_SUPPORT == 1 || RTL8197G_SUPPORT == 1 ||\ - RTL8710C_SUPPORT == 1) + RTL8710C_SUPPORT == 1 || RTL8723F_SUPPORT == 1) u32 iqk_channel[2]; - boolean iqk_fail_report[2][4][2]; /*channel/path/TRX(TX:0, RX:1) */ + boolean iqk_fail_report[2][NUM][2]; /*channel/path/TRX(TX:0, RX:1) */ /*channel / path / TRX(TX:0, RX:1) / CFIR_real*/ /*channel index = 2 is just for debug*/ -#if (RTL8812F_SUPPORT == 1 || RTL8822C_SUPPORT == 1 ) +#if (RTL8814B_SUPPORT == 1) + u16 iqk_cfir_real[3][NUM][2][19]; + u16 iqk_cfir_imag[3][NUM][2][19]; +#elif (RTL8812F_SUPPORT == 1 || RTL8822C_SUPPORT == 1 ) u16 iqk_cfir_real[3][2][2][17]; /*channel / path / TRX(TX:0, RX:1) / CFIR_imag*/ /*channel index = 2 is just for debug*/ u16 iqk_cfir_imag[3][2][2][17]; + /*times/path*/ +#elif (RTL8195B_SUPPORT == 1) + u32 iqk_cfir_real[3][NUM][2][9]; + u32 iqk_cfir_imag[3][NUM][2][9]; + /*channel / path / TRX(TX:0, RX:1) / CFIR_imag*/ + /*channel index = 2 is just for debug*/ +#else + u32 iqk_cfir_real[3][NUM][2][8]; + /*channel / path / TRX(TX:0, RX:1) / CFIR_imag*/ + /*channel index = 2 is just for debug*/ + u32 iqk_cfir_imag[3][NUM][2][8]; +#endif + +#if (RTL8812F_SUPPORT == 1 || RTL8822C_SUPPORT == 1 ) u32 rx_cfir_real[2][2][17]; u32 rx_cfir_imag[2][2][17]; u32 rx_cfir[2][2]; - /*times/path*/ -#else - u32 iqk_cfir_real[3][4][2][8]; - /*channel / path / TRX(TX:0, RX:1) / CFIR_imag*/ - /*channel index = 2 is just for debug*/ - u32 iqk_cfir_imag[3][4][2][8]; #endif - u8 retry_count[2][4][3]; /* channel / path / (TXK:0, RXK1:1, RXK2:2) */ - u8 gs_retry_count[2][4][2]; /* channel / path / (GSRXK1:0, GSRXK2:1) */ + u8 retry_count[2][NUM][3]; /* channel / path / (TXK:0, RXK1:1, RXK2:2) */ + u8 gs_retry_count[2][NUM][2]; /* channel / path / (GSRXK1:0, GSRXK2:1) */ /* channel / path 0:SRXK1 fail, 1:RXK1 fail 2:RXK2 fail */ - u8 rxiqk_fail_code[2][4]; - u32 lok_idac[2][4]; /*channel / path*/ - u16 rxiqk_agc[2][4]; /*channel / path*/ - u32 bypass_iqk[2][4]; /*channel / 0xc94/0xe94*/ + u8 rxiqk_fail_code[2][NUM]; + u32 lok_idac[2][NUM]; /*channel / path*/ + u16 rxiqk_agc[2][NUM]; /*channel / path*/ + u32 bypass_iqk[2][NUM]; /*channel / 0xc94/0xe94*/ u32 txgap_result[8]; /*txagpK result */ u32 tmp_gntwl; boolean is_btg; @@ -109,13 +132,25 @@ struct dm_iqk_info { boolean is_hwtx; boolean xym_read; boolean trximr_enable; +#if (RTL8822B_SUPPORT == 1 || RTL8821C_SUPPORT == 1 ||\ + RTL8814B_SUPPORT == 1 || RTL8822C_SUPPORT == 1) u32 rx_xym[2][10]; u32 tx_xym[2][10]; u32 gs1_xym[2][6]; u32 gs2_xym[2][6]; u32 rxk1_xym[2][6]; + u32 nbtxk_1b38[2]; + u32 nbrxk_1b3c[2]; +#endif +#if (RTL8710C_SUPPORT == 1 || RTL8197G_SUPPORT == 1 ) u32 txxy[2][2]; u32 rxxy[2][2]; +#endif +#if (RTL8723F_SUPPORT == 1) + u32 txxy[2][2]; + u32 rxxy[2][2][2]; +#endif + #endif }; diff --git a/hal/phydm/halrf/halrf_kfree.c b/hal/phydm/halrf/halrf_kfree.c index 548b0e9..71a49dd 100644 --- a/hal/phydm/halrf/halrf_kfree.c +++ b/hal/phydm/halrf/halrf_kfree.c @@ -774,6 +774,9 @@ void phydm_get_thermal_trim_offset_8198f(void *dm_void) odm_efuse_one_byte_read(dm, PPG_THERMAL_OFFSET_98F, &pg_therm, false); + RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f efuse thermal trim 0x%X=0x%X\n", + PPG_THERMAL_OFFSET_98F, pg_therm); + if (pg_therm != 0) { pg_therm = pg_therm & 0x1f; if ((pg_therm & BIT(0)) == 0) @@ -797,33 +800,51 @@ void phydm_get_power_trim_offset_8198f(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u8 pg_power = 0, i, j; + u8 i, j; + u8 power_trim[6] = {0}; - odm_efuse_one_byte_read(dm, PPG_2GL_TXAB_98F, &pg_power, false); + odm_efuse_one_byte_read(dm, PPG_2GL_TXAB_98F, &power_trim[0], false); + odm_efuse_one_byte_read(dm, PPG_2GL_TXCD_98F, &power_trim[1], false); + odm_efuse_one_byte_read(dm, PPG_2GM_TXAB_98F, &power_trim[2], false); + odm_efuse_one_byte_read(dm, PPG_2GM_TXCD_98F, &power_trim[3], false); + odm_efuse_one_byte_read(dm, PPG_2GH_TXAB_98F, &power_trim[4], false); + odm_efuse_one_byte_read(dm, PPG_2GH_TXCD_98F, &power_trim[5], false); - if (pg_power != 0) { - power_trim_info->bb_gain[0][0] = pg_power & 0xf; - power_trim_info->bb_gain[0][1] = (pg_power & 0xf0) >> 4; + RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f efuse Power Trim 0x%X=0x%X 0x%X=0x%X 0x%X=0x%X 0x%X=0x%X 0x%X=0x%X 0x%X=0x%X\n", + PPG_2GL_TXAB_98F, power_trim[0], + PPG_2GL_TXCD_98F, power_trim[1], + PPG_2GM_TXAB_98F, power_trim[2], + PPG_2GM_TXCD_98F, power_trim[3], + PPG_2GH_TXAB_98F, power_trim[4], + PPG_2GH_TXCD_98F, power_trim[5] + ); - odm_efuse_one_byte_read(dm, PPG_2GL_TXCD_98F, &pg_power, false); - power_trim_info->bb_gain[0][2] = pg_power & 0xf; - power_trim_info->bb_gain[0][3] = (pg_power & 0xf0) >> 4; + j = 0; + for (i = 0; i < 6; i++) { + if (power_trim[i] == 0x0) + j++; + } - odm_efuse_one_byte_read(dm, PPG_2GM_TXAB_98F, &pg_power, false); - power_trim_info->bb_gain[1][0] = pg_power & 0xf; - power_trim_info->bb_gain[1][1] = (pg_power & 0xf0) >> 4; + if (j == 6) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f Power Trim no pg\n"); + } else { + power_trim_info->bb_gain[0][0] = power_trim[0] & 0xf; + power_trim_info->bb_gain[0][1] = (power_trim[0] & 0xf0) >> 4; - odm_efuse_one_byte_read(dm, PPG_2GM_TXCD_98F, &pg_power, false); - power_trim_info->bb_gain[1][2] = pg_power & 0xf; - power_trim_info->bb_gain[1][3] = (pg_power & 0xf0) >> 4; + power_trim_info->bb_gain[0][2] = power_trim[1] & 0xf; + power_trim_info->bb_gain[0][3] = (power_trim[1] & 0xf0) >> 4; - odm_efuse_one_byte_read(dm, PPG_2GH_TXAB_98F, &pg_power, false); - power_trim_info->bb_gain[2][0] = pg_power & 0xf; - power_trim_info->bb_gain[2][1] = (pg_power & 0xf0) >> 4; + power_trim_info->bb_gain[1][0] = power_trim[2] & 0xf; + power_trim_info->bb_gain[1][1] = (power_trim[2] & 0xf0) >> 4; - odm_efuse_one_byte_read(dm, PPG_2GH_TXCD_98F, &pg_power, false); - power_trim_info->bb_gain[2][2] = pg_power & 0xf; - power_trim_info->bb_gain[2][3] = (pg_power & 0xf0) >> 4; + power_trim_info->bb_gain[1][2] = power_trim[3] & 0xf; + power_trim_info->bb_gain[1][3] = (power_trim[3] & 0xf0) >> 4; + + power_trim_info->bb_gain[2][0] = power_trim[4] & 0xf; + power_trim_info->bb_gain[2][1] = (power_trim[4] & 0xf0) >> 4; + + power_trim_info->bb_gain[2][2] = power_trim[5] & 0xf; + power_trim_info->bb_gain[2][3] = (power_trim[5] & 0xf0) >> 4; power_trim_info->flag = power_trim_info->flag | KFREE_FLAG_ON | KFREE_FLAG_ON_2G; @@ -848,23 +869,32 @@ void phydm_get_pa_bias_offset_8198f(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u8 pg_pa_bias = 0, i; + u8 i, j; + u8 pa_bias[2] = {0}; u8 tx_pa_bias[4] = {0}; - odm_efuse_one_byte_read(dm, PPG_PABIAS_2GAB_98F, &pg_pa_bias, false); + odm_efuse_one_byte_read(dm, PPG_PABIAS_2GAB_98F, &pa_bias[0], false); + odm_efuse_one_byte_read(dm, PPG_PABIAS_2GCD_98F, &pa_bias[1], false); - if (pg_pa_bias != 0) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f efuse Tx PA Bias 0x%X=0x%X 0x%X=0x%X\n", + PPG_PABIAS_2GAB_98F, pa_bias[0], PPG_PABIAS_2GCD_98F, pa_bias[1]); + + j = 0; + for (i = 0; i < 2; i++) { + if (pa_bias[i] == 0x0) + j++; + } + + if (j == 2) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f Tx PA Bias no pg\n"); + } else { /*paht ab*/ - odm_efuse_one_byte_read(dm, PPG_PABIAS_2GAB_98F, - &pg_pa_bias, false); - tx_pa_bias[0] = pg_pa_bias & 0xf; - tx_pa_bias[1] = ((pg_pa_bias & 0xf0) >> 4); + tx_pa_bias[0] = pa_bias[0] & 0xf; + tx_pa_bias[1] = ((pa_bias[0] & 0xf0) >> 4); /*paht cd*/ - odm_efuse_one_byte_read(dm, PPG_PABIAS_2GCD_98F, - &pg_pa_bias, false); - tx_pa_bias[2] = pg_pa_bias & 0xf; - tx_pa_bias[3] = ((pg_pa_bias & 0xf0) >> 4); + tx_pa_bias[2] = pa_bias[1] & 0xf; + tx_pa_bias[3] = ((pa_bias[1] & 0xf0) >> 4); for (i = RF_PATH_A; i < 4; i++) { if ((tx_pa_bias[i] & 0x1) == 1) @@ -885,8 +915,6 @@ void phydm_get_pa_bias_offset_8198f(void *dm_void) odm_set_rf_reg(dm, i, 0x60, 0x0000f000, tx_pa_bias[i]); power_trim_info->pa_bias_flag |= PA_BIAS_FLAG_ON; - } else { - RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f tx pa bias no pg\n"); } } @@ -895,34 +923,39 @@ void phydm_get_set_lna_offset_8198f(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u8 pg_pa_bias = 0, i; + u8 i, j; + u8 lna_trim[4] = {0}; u8 cg[4] = {0}, cs[4] = {0}; u32 rf_reg; - odm_efuse_one_byte_read(dm, PPG_LNA_2GA_98F, &pg_pa_bias, false); + odm_efuse_one_byte_read(dm, PPG_LNA_2GA_98F, &lna_trim[0], false); + odm_efuse_one_byte_read(dm, PPG_LNA_2GB_98F, &lna_trim[1], false); + odm_efuse_one_byte_read(dm, PPG_LNA_2GC_98F, &lna_trim[2], false); + odm_efuse_one_byte_read(dm, PPG_LNA_2GD_98F, &lna_trim[3], false); - if (pg_pa_bias != 0) { - odm_efuse_one_byte_read(dm, PPG_LNA_2GA_98F, - &pg_pa_bias, false); - cg[0] = (pg_pa_bias & 0xc) >> 2; - cs[0] = pg_pa_bias & 0x3; + RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f efuse LNA Trim 0x%X=0x%X 0x%X=0x%X 0x%X=0x%X 0x%X=0x%X\n", + PPG_LNA_2GA_98F, lna_trim[0], + PPG_LNA_2GB_98F, lna_trim[1], + PPG_LNA_2GC_98F, lna_trim[2], + PPG_LNA_2GD_98F, lna_trim[3] + ); - odm_efuse_one_byte_read(dm, PPG_LNA_2GB_98F, - &pg_pa_bias, false); - cg[1] = (pg_pa_bias & 0xc) >> 2; - cs[1] = pg_pa_bias & 0x3; + j = 0; + for (i = 0; i < 4; i++) { + if (lna_trim[i] == 0x0) + j++; + } - odm_efuse_one_byte_read(dm, PPG_LNA_2GC_98F, - &pg_pa_bias, false); - cg[2] = (pg_pa_bias & 0xc) >> 2; - cs[2] = pg_pa_bias & 0x3; + if (j == 4) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f LNA no pg\n"); + } else { - odm_efuse_one_byte_read(dm, PPG_LNA_2GD_98F, - &pg_pa_bias, false); - cg[3] = (pg_pa_bias & 0xc) >> 2; - cs[3] = pg_pa_bias & 0x3; + for (i = 0; i < 4; i++) { + cg[i] = (lna_trim[i] & 0xc) >> 2; + cs[i] = lna_trim[i] & 0x3; + } - for (i = RF_PATH_A; i < 4; i++) { + for (i = RF_PATH_A; i <= RF_PATH_D; i++) { RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f lna cg[%d]=0x%x cs[%d]=0x%x\n", i, cg[i], i, cs[i]); @@ -949,8 +982,6 @@ void phydm_get_set_lna_offset_8198f(void *dm_void) } power_trim_info->lna_flag |= LNA_FLAG_ON; - } else { - RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f lna no pg\n"); } } @@ -959,7 +990,7 @@ void phydm_set_kfree_to_rf_8198f(void *dm_void, u8 e_rf_path, u8 data) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u32 band, i; + u32 i; s8 pwr_offset[3]; RF_DBG(dm, DBG_RF_MP, @@ -1000,10 +1031,11 @@ void phydm_set_kfree_to_rf_8198f(void *dm_void, u8 e_rf_path, u8 data) void phydm_clear_kfree_to_rf_8198f(void *dm_void, u8 e_rf_path, u8 data) { struct dm_struct *dm = (struct dm_struct *)dm_void; +#if 0 RF_DBG(dm, DBG_RF_MP, "[kfree] %s:Clear kfree to rf 0x55\n", __func__); -#if 0 + /*power_trim based on 55[19:14]*/ odm_set_rf_reg(dm, e_rf_path, RF_0x55, BIT(5), 1); /*enable 55[14] for 0.5db step*/ @@ -1032,7 +1064,6 @@ void phydm_clear_kfree_to_rf_8198f(void *dm_void, u8 e_rf_path, u8 data) odm_set_rf_reg(dm, e_rf_path, RF_0xf5, BIT(18), 0); /*write disable*/ odm_set_rf_reg(dm, e_rf_path, RF_0xef, BIT(7), 0); -#else odm_set_rf_reg(dm, e_rf_path, RF_0xdf, BIT(7), 1); /*odm_set_rf_reg(dm, e_rf_path, RF_0xf5, BIT(18), 0);*/ @@ -1247,7 +1278,7 @@ void phydm_get_tssi_trim_offset_8822c(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u8 i, j = 0; + u8 i, j; u8 pg_power[16] = {0}; odm_efuse_one_byte_read(dm, TSSI_2GM_TXA_22C, &pg_power[0], false); @@ -1267,14 +1298,14 @@ void phydm_get_tssi_trim_offset_8822c(void *dm_void) odm_efuse_one_byte_read(dm, TSSI_5GH2_TXA_22C, &pg_power[14], false); odm_efuse_one_byte_read(dm, TSSI_5GH2_TXB_22C, &pg_power[15], false); + j = 0; for (i = 0; i < 16; i++) { if (pg_power[i] == 0xff) j++; } - if (j == 15) { + if (j == 16) { RF_DBG(dm, DBG_RF_MP, "[kfree] 8822c tssi trim no PG\n"); - return; } else { power_trim_info->tssi_trim[0][0] = (s8)pg_power[0]; power_trim_info->tssi_trim[0][1] = (s8)pg_power[1]; @@ -1410,7 +1441,7 @@ void phydm_get_set_thermal_trim_offset_8812f(void *dm_void) odm_efuse_one_byte_read(dm, PPG_THERMAL_A_OFFSET_22C, &pg_therm, false); - if (pg_therm != 0xff) { + if (pg_therm != 0xff && pg_therm != 0x0) { /*s0*/ pg_therm = pg_therm & 0x1f; @@ -1438,7 +1469,7 @@ void phydm_get_set_thermal_trim_offset_8812f(void *dm_void) if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) RF_DBG(dm, DBG_RF_MP, "[kfree] 8812f thermalA:%d thermalB:%d\n", thermal[RF_PATH_A], - thermal[RF_PATH_B]); + thermal[RF_PATH_B]); } void phydm_set_power_trim_offset_8812f(void *dm_void) @@ -1518,8 +1549,10 @@ void phydm_get_set_power_trim_offset_8812f(void *dm_void) odm_efuse_one_byte_read(dm, PPG_5GL2_TXB_22C, &pg_power4, false); odm_efuse_one_byte_read(dm, PPG_5GM1_TXA_22C, &pg_power5, false); - if (pg_power1 != 0xff || pg_power2 != 0xff || pg_power3 != 0xff || - pg_power4 != 0xff || pg_power5 != 0xff) { + if ((pg_power1 != 0xff || pg_power2 != 0xff || pg_power3 != 0xff || + pg_power4 != 0xff || pg_power5 != 0xff) && + (pg_power1 != 0x0 || pg_power2 != 0x0 || pg_power3 != 0x0 || + pg_power4 != 0x0 || pg_power5 != 0x0)) { #if 0 odm_efuse_one_byte_read(dm, PPG_2GL_TXAB_22C, &pg_power, false); if (pg_power == 0xff) @@ -1609,7 +1642,7 @@ void phydm_get_tssi_trim_offset_8812f(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u8 i, j = 0; + u8 i, j ; u8 pg_power[16] = {0}; #if 0 @@ -1631,14 +1664,14 @@ void phydm_get_tssi_trim_offset_8812f(void *dm_void) odm_efuse_one_byte_read(dm, TSSI_5GH2_TXA_22C, &pg_power[14], false); odm_efuse_one_byte_read(dm, TSSI_5GH2_TXB_22C, &pg_power[15], false); + j = 0; for (i = 4; i < 16; i++) { - if (pg_power[i] == 0xff) + if (pg_power[i] == 0xff || pg_power[i] == 0x0) j++; } if (j == 12) { RF_DBG(dm, DBG_RF_MP, "[kfree] 8812f tssi trim no PG\n"); - return; } else { #if 0 power_trim_info->tssi_trim[0][0] = (s8)pg_power[0]; @@ -1721,7 +1754,7 @@ void phydm_get_set_pa_bias_offset_8812f(void *dm_void) odm_efuse_one_byte_read(dm, PPG_PABIAS_5GA_22C, &pg_pa_bias, false); - if (pg_pa_bias != 0xff) { + if (pg_pa_bias != 0xff && pg_pa_bias != 0x0) { #if 0 /*2G s0*/ odm_efuse_one_byte_read(dm, PPG_PABIAS_2GA_22C, @@ -1798,43 +1831,48 @@ void phydm_set_power_trim_rf_8195b(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u32 band, i; - s8 pwr_offset[3]; RF_DBG(dm, DBG_RF_MP, "[kfree] %s:Set kfree to rf 0x33\n", __func__); - odm_set_rf_reg(dm, RF_PATH_A, RF_0xee, BIT(19), 1); + if (power_trim_info->flag & KFREE_FLAG_ON) { + odm_set_rf_reg(dm, RF_PATH_A, RF_0xee, BIT(19), 1); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x0); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[0][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x1); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[1][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x2); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[2][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x4); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[3][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x5); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[4][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x6); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[5][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x7); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[6][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x8); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[7][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0xe); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[7][RF_PATH_A]); + if (power_trim_info->flag & KFREE_FLAG_ON_2G) { + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x0); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[0][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x1); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[1][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x2); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[2][RF_PATH_A]); + } - odm_set_rf_reg(dm, RF_PATH_A, RF_0xee, BIT(19), 0); + if (power_trim_info->flag & KFREE_FLAG_ON_5G) { + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x4); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[3][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x5); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[4][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x6); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[5][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x7); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[6][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x8); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[7][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0xe); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[7][RF_PATH_A]); + } + + odm_set_rf_reg(dm, RF_PATH_A, RF_0xee, BIT(19), 0); + } } @@ -1848,6 +1886,7 @@ void phydm_get_set_power_trim_offset_8195b(void *dm_void) odm_efuse_one_byte_read(dm, PPG_2GL_TXA_95B, &pg_power, false); if (pg_power != 0xff) { + odm_efuse_one_byte_read(dm, PPG_2GL_TXA_95B, &pg_power, false); power_trim_info->bb_gain[0][0] = pg_power & 0xf; odm_efuse_one_byte_read(dm, PPG_2GM_TXA_95B, &pg_power, false); @@ -1856,6 +1895,15 @@ void phydm_get_set_power_trim_offset_8195b(void *dm_void) odm_efuse_one_byte_read(dm, PPG_2GH_TXA_95B, &pg_power, false); power_trim_info->bb_gain[2][0] = pg_power & 0xf; + power_trim_info->flag = + power_trim_info->flag | KFREE_FLAG_ON | KFREE_FLAG_ON_2G; + } + + pg_power = 0xff; + + odm_efuse_one_byte_read(dm, PPG_5GL1_TXA_95B, &pg_power, false); + + if (pg_power != 0xff) { odm_efuse_one_byte_read(dm, PPG_5GL1_TXA_95B, &pg_power, false); power_trim_info->bb_gain[3][0] = pg_power & 0x1f; @@ -1871,13 +1919,12 @@ void phydm_get_set_power_trim_offset_8195b(void *dm_void) odm_efuse_one_byte_read(dm, PPG_5GH1_TXA_95B, &pg_power, false); power_trim_info->bb_gain[7][0] = pg_power & 0x1f; - phydm_set_power_trim_rf_8195b(dm); - power_trim_info->flag = - power_trim_info->flag | - KFREE_FLAG_ON | KFREE_FLAG_ON_2G | KFREE_FLAG_ON_5G; + power_trim_info->flag | KFREE_FLAG_ON | KFREE_FLAG_ON_5G; } + phydm_set_power_trim_rf_8195b(dm); + RF_DBG(dm, DBG_RF_MP, "[kfree] 8195b power trim flag:0x%02x\n", power_trim_info->flag); @@ -1901,10 +1948,10 @@ void phydm_get_set_pa_bias_offset_8195b(void *dm_void) RF_DBG(dm, DBG_RF_MP, "======>%s\n", __func__); + /*2G*/ odm_efuse_one_byte_read(dm, PPG_PABIAS_2GA_95B, &pg_pa_bias, false); if (pg_pa_bias != 0xff) { - /*2G*/ odm_efuse_one_byte_read(dm, PPG_PABIAS_2GA_95B, &pg_pa_bias, false); pg_pa_bias = pg_pa_bias & 0xf; @@ -1912,8 +1959,16 @@ void phydm_get_set_pa_bias_offset_8195b(void *dm_void) RF_DBG(dm, DBG_RF_MP, "[kfree] 2G pa_bias=0x%x\n", pg_pa_bias); odm_set_rf_reg(dm, RF_PATH_A, 0x60, 0x0000f000, pg_pa_bias); + } else { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8195b 2G tx pa bias no pg\n"); + } - /*5G*/ + /*5G*/ + pg_pa_bias = 0xff; + + odm_efuse_one_byte_read(dm, PPG_PABIAS_5GA_95B, &pg_pa_bias, false); + + if (pg_pa_bias != 0xff) { odm_efuse_one_byte_read(dm, PPG_PABIAS_5GA_95B, &pg_pa_bias, false); pg_pa_bias = pg_pa_bias & 0xf; @@ -1924,7 +1979,7 @@ void phydm_get_set_pa_bias_offset_8195b(void *dm_void) power_trim_info->pa_bias_flag |= PA_BIAS_FLAG_ON; } else { - RF_DBG(dm, DBG_RF_MP, "[kfree] 8195b tx pa bias no pg\n"); + RF_DBG(dm, DBG_RF_MP, "[kfree] 8195b 5G tx pa bias no pg\n"); } } @@ -1955,7 +2010,7 @@ void phydm_get_thermal_trim_offset_8721d(void *dm_void) power_trim_info->thermal); } -void phydm_set_power_trim_rf_8721d(void *dm_void, u8 pg_band) +void phydm_set_power_trim_rf_8721d(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; @@ -1963,33 +2018,53 @@ void phydm_set_power_trim_rf_8721d(void *dm_void, u8 pg_band) RF_DBG(dm, DBG_RF_MP, "[kfree] %s:Set kfree to rf 0x33\n", __func__); odm_set_rf_reg(dm, RF_PATH_A, RF_0xee, BIT(19), 1); - if (pg_band == 1) { - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x0); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[0][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x1); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[1][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x2); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[2][RF_PATH_A]); - } else if (pg_band == 2) { - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x4); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[3][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x5); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[4][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x6); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[5][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x7); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[6][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x8); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[7][RF_PATH_A]); - } + + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x0); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[0][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x1); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[1][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x2); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[2][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x3); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[2][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x4); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[3][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x5); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[4][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x6); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[5][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x7); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[6][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x8); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[7][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x9); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, RFREGOFFSETMASK, + power_trim_info->bb_gain[3][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0xa); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, RFREGOFFSETMASK, + power_trim_info->bb_gain[4][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0xb); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, RFREGOFFSETMASK, + power_trim_info->bb_gain[5][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0xc); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, RFREGOFFSETMASK, + power_trim_info->bb_gain[6][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0xd); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, RFREGOFFSETMASK, + power_trim_info->bb_gain[7][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0xe); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, RFREGOFFSETMASK, + power_trim_info->bb_gain[7][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0xee, BIT(19), 0); } @@ -1998,49 +2073,61 @@ void phydm_get_set_power_trim_offset_8721d(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u8 pg_power = 0xff, pg_power_5g = 0xff, i, j; - u8 pg_band = 0; + u8 pg_power = 0xff, i, j; + u8 pg_power1, pg_power2, pg_power3, pg_power4, pg_power5, pg_power6; - odm_efuse_one_byte_read(dm, PPG_2G_TXA_8721D, &pg_power, false); - odm_efuse_one_byte_read(dm, PPG_5GL1_TXA_8721D, &pg_power_5g, false); + odm_efuse_one_byte_read(dm, PPG_2G_TXA_8721D, &pg_power1, false); + odm_efuse_one_byte_read(dm, PPG_5GL1_TXA_8721D, &pg_power2, false); + odm_efuse_one_byte_read(dm, PPG_5GL2_TXA_8721D, &pg_power3, false); + odm_efuse_one_byte_read(dm, PPG_5GM1_TXA_8721D, &pg_power4, false); + odm_efuse_one_byte_read(dm, PPG_5GM2_TXA_8721D, &pg_power5, false); + odm_efuse_one_byte_read(dm, PPG_5GH1_TXA_8721D, &pg_power6, false); - if (pg_power != 0xff) { - pg_band = 1; + if (pg_power1 != 0xff || pg_power2 != 0xff || pg_power3 != 0xff || + pg_power4 != 0xff || pg_power5 != 0xff || pg_power6 != 0xff) { + odm_efuse_one_byte_read(dm, PPG_2G_TXA_8721D, &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; power_trim_info->bb_gain[0][0] = pg_power & 0xf; power_trim_info->bb_gain[1][0] = pg_power & 0xf; power_trim_info->bb_gain[2][0] = pg_power & 0xf; - phydm_set_power_trim_rf_8721d(dm, pg_band); - - power_trim_info->flag = - power_trim_info->flag | - KFREE_FLAG_ON | KFREE_FLAG_ON_2G; - } - if (pg_power_5g != 0xff) { - pg_band = 2; - power_trim_info->bb_gain[3][0] = pg_power_5g & 0x1f; + odm_efuse_one_byte_read(dm, PPG_5GL1_TXA_8721D, + &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[3][0] = pg_power & 0x1f; odm_efuse_one_byte_read(dm, PPG_5GL2_TXA_8721D, - &pg_power_5g, false); - power_trim_info->bb_gain[4][0] = pg_power_5g & 0x1f; + &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[4][0] = pg_power & 0x1f; odm_efuse_one_byte_read(dm, PPG_5GM1_TXA_8721D, - &pg_power_5g, false); - power_trim_info->bb_gain[5][0] = pg_power_5g & 0x1f; + &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[5][0] = pg_power & 0x1f; odm_efuse_one_byte_read(dm, PPG_5GM2_TXA_8721D, - &pg_power_5g, false); - power_trim_info->bb_gain[6][0] = pg_power_5g & 0x1f; + &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[6][0] = pg_power & 0x1f; odm_efuse_one_byte_read(dm, PPG_5GH1_TXA_8721D, - &pg_power_5g, false); - power_trim_info->bb_gain[7][0] = pg_power_5g & 0x1f; - - phydm_set_power_trim_rf_8721d(dm, pg_band); + &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[7][0] = pg_power & 0x1f; power_trim_info->flag = - power_trim_info->flag | - KFREE_FLAG_ON | KFREE_FLAG_ON_5G; + power_trim_info->flag | KFREE_FLAG_ON | + KFREE_FLAG_ON_2G | + KFREE_FLAG_ON_5G; + + phydm_set_power_trim_rf_8721d(dm); } RF_DBG(dm, DBG_RF_MP, "[kfree] 8721d power trim flag:0x%02x\n", @@ -2059,11 +2146,12 @@ void phydm_get_set_power_trim_offset_8721d(void *dm_void) void phydm_get_set_pa_bias_offset_8721d(void *dm_void) { +#if 0 struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; u8 pg_pa_bias = 0xff; -#if 0 + RF_DBG(dm, DBG_RF_MP, "======>%s\n", __func__); odm_efuse_one_byte_read(dm, PPG_PABIAS_2GA_95B, &pg_pa_bias, false); @@ -2099,16 +2187,25 @@ void phydm_get_thermal_trim_offset_8197g(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u8 pg_therm = 0; + u8 pg_therm = 0xff, i; - odm_efuse_one_byte_read(dm, PPG_THERMAL_OFFSET_97G, &pg_therm, false); + odm_efuse_one_byte_read(dm, PPG_THERMAL_A_OFFSET_97G, &pg_therm, false); - if (pg_therm != 0) { - pg_therm = pg_therm & 0x1f; - if ((pg_therm & BIT(0)) == 0) - power_trim_info->thermal = (-1 * (pg_therm >> 1)); - else - power_trim_info->thermal = (pg_therm >> 1); + if (pg_therm != 0x0) { + for (i = 0; i < 2; i++) { + if (i == 0) + odm_efuse_one_byte_read(dm, PPG_THERMAL_A_OFFSET_97G, &pg_therm, false); + else if (i == 1) + odm_efuse_one_byte_read(dm, PPG_THERMAL_B_OFFSET_97G, &pg_therm, false); + + RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g Efuse thermal S%d:0x%x\n", i, pg_therm); + + pg_therm = pg_therm & 0x1f; + if ((pg_therm & BIT(0)) == 0) + power_trim_info->multi_thermal[i] = (-1 * (pg_therm >> 1)); + else + power_trim_info->multi_thermal[i] = (pg_therm >> 1); + } power_trim_info->flag |= KFREE_FLAG_THERMAL_K_ON; } @@ -2116,9 +2213,11 @@ void phydm_get_thermal_trim_offset_8197g(void *dm_void) RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g thermal trim flag:0x%02x\n", power_trim_info->flag); - if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) - RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g thermal:%d\n", - power_trim_info->thermal); + for (i = 0; i < 2; i++) { + if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) + RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g thermal S%d:%d\n", + i ,power_trim_info->multi_thermal[i]); + } } void phydm_set_power_trim_offset_8197g(void *dm_void) @@ -2196,6 +2295,70 @@ void phydm_get_set_power_trim_offset_8197g(void *dm_void) } } +void phydm_get_tssi_trim_offset_8197g(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u8 i, j; + u8 pg_power[4] = {0}; + + odm_efuse_one_byte_read(dm, TSSI_2GL_TXA_97G, &pg_power[0], false); + odm_efuse_one_byte_read(dm, TSSI_2GL_TXB_97G, &pg_power[1], false); + odm_efuse_one_byte_read(dm, TSSI_2GH_TXA_97G, &pg_power[2], false); + odm_efuse_one_byte_read(dm, TSSI_2GH_TXB_97G, &pg_power[3], false); + + j = 0; + for (i = 0; i < 4; i++) { + if (pg_power[i] == 0x0) + j++; + } + + if (j == 4) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g tssi trim no PG\n"); + } else { + power_trim_info->tssi_trim[0][0] = (s8)pg_power[0]; + power_trim_info->tssi_trim[0][1] = (s8)pg_power[1]; + power_trim_info->tssi_trim[1][0] = (s8)pg_power[0]; + power_trim_info->tssi_trim[1][1] = (s8)pg_power[1]; + power_trim_info->tssi_trim[2][0] = (s8)pg_power[2]; + power_trim_info->tssi_trim[2][1] = (s8)pg_power[3]; + + power_trim_info->flag = + power_trim_info->flag | TSSI_TRIM_FLAG_ON; + + for (i = 0; i < KFREE_BAND_NUM; i++) { + for (j = 0; j < MAX_PATH_NUM_8197G; j++) { + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8197g tssi_trim[%d][%d]=0x%X\n", + i, j, power_trim_info->tssi_trim[i][j]); + } + } + } +} + +s8 phydm_get_tssi_trim_de_8197g(void *dm_void, u8 path) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u8 channel = *dm->channel, group = 0; + + if (channel >= 1 && channel <= 3) + group = 0; + else if (channel >= 4 && channel <= 9) + group = 1; + else if (channel >= 10 && channel <= 14) + group = 2; + else { + RF_DBG(dm, DBG_RF_MP, "[kfree] Channel(%d) is not exist in Group\n", + channel); + return 0; + } + + return power_trim_info->tssi_trim[group][path]; +} + void phydm_get_set_pa_bias_offset_8197g(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -2206,7 +2369,7 @@ void phydm_get_set_pa_bias_offset_8197g(void *dm_void) odm_efuse_one_byte_read(dm, PPG_PABIAS_2GAB_97G, &pg_pa_bias, false); - if (pg_pa_bias != 0xff) { + if (pg_pa_bias != 0x0) { /*paht ab*/ odm_efuse_one_byte_read(dm, PPG_PABIAS_2GAB_97G, &pg_pa_bias, false); @@ -2232,29 +2395,63 @@ void phydm_get_set_lna_offset_8197g(void *dm_void) struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; u8 pg_lna[2] = {0}, i, pg_lna_tmp = 0; - u32 rf_reg; + u32 lna_trim_addr[2] = {0x1884, 0x4184}; odm_efuse_one_byte_read(dm, PPG_LNA_2GA_97G, &pg_lna_tmp, false); if (pg_lna_tmp != 0) { odm_efuse_one_byte_read(dm, PPG_LNA_2GA_97G, - &pg_lna[0], false); + &pg_lna[RF_PATH_A], false); + power_trim_info->lna_trim[RF_PATH_A] = (s8)pg_lna[RF_PATH_A]; odm_efuse_one_byte_read(dm, PPG_LNA_2GB_97G, - &pg_lna[1], false); + &pg_lna[RF_PATH_B], false); + power_trim_info->lna_trim[RF_PATH_B] = (s8)pg_lna[RF_PATH_B]; for (i = RF_PATH_A; i < 2; i++) { - RF_DBG(dm, DBG_RF_MP, - "[kfree] 8197g lna\n"); - odm_set_rf_reg(dm, i, 0x88, 0x00000f00, pg_lna[i]); + if (odm_get_bb_reg(dm, lna_trim_addr[i], 0x00c00000) == 0x2) { + odm_set_rf_reg(dm, i, 0x88, 0x00000f00, (pg_lna[i] & 0xf)); + RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g lna trim CG 0x%x path=%d\n", (pg_lna[i] & 0xf), i); + } else if (odm_get_bb_reg(dm, lna_trim_addr[i], 0x00c00000) == 0x3) { + odm_set_rf_reg(dm, i, 0x88, 0x00000f00, ((pg_lna[i] & 0xf0) >> 4)); + RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g lna trim CS 0x%x path=%d\n", ((pg_lna[i] & 0xf0) >> 4), i); + } } power_trim_info->lna_flag |= LNA_FLAG_ON; } else { - RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g lna no pg\n"); + RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g lna trim no pg\n"); } } +void phydm_set_lna_trim_offset_8197g(void *dm_void, u8 path, u8 cg_cs, u8 enable) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *trim = &dm->power_trim_data; + + u8 i; + + if (enable == 0) { + for (i = RF_PATH_A; i < 2; i++) { + odm_set_rf_reg(dm, i, 0x88, 0x00000f00, 0x0); + RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g diversity lna trim disable\n"); + } + return; + } + + /*cg*/ + if (cg_cs == 0) { + odm_set_rf_reg(dm, path, 0x88, 0x00000f00, (trim->lna_trim[path] & 0xf)); + RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g diversity lna trim CG 0x%x path=%d\n", + (trim->lna_trim[path] & 0xf), path); + } else if (cg_cs == 1) { /*cs*/ + odm_set_rf_reg(dm, path, 0x88, 0x00000f00, ((trim->lna_trim[path] & 0xf0) >> 4)); + RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g diversity lna trim CS 0x%x path=%d\n", + ((trim->lna_trim[path] & 0xf0) >> 4), path); + } +} + + void phydm_get_thermal_trim_offset_8710c(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -2365,6 +2562,1020 @@ void phydm_get_set_pa_bias_offset_8710c(void *dm_void) } } +void phydm_set_power_trim_offset_8814b(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + u8 e_rf_path; + + for (e_rf_path = RF_PATH_A; e_rf_path < MAX_PATH_NUM_8814B; e_rf_path++) + { + if (power_trim_info->flag & KFREE_FLAG_ON) { + odm_set_rf_reg(dm, e_rf_path, RF_0xee, BIT(19), 1); + + if (power_trim_info->flag & KFREE_FLAG_ON_2G) { + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x0); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[0][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x1); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[0][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x2); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[0][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x3); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[0][e_rf_path]); + } + + if (power_trim_info->flag & KFREE_FLAG_ON_5G) { + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x4); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[3][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x5); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[4][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x6); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[5][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x7); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[6][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x8); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[7][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x9); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[3][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0xa); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[4][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0xb); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[5][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0xc); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[6][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0xd); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[7][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0xe); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[7][e_rf_path]); + } + + odm_set_rf_reg(dm, e_rf_path, RF_0xee, BIT(19), 0); + } + } +} + +void phydm_get_set_power_trim_offset_8814b(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u8 i, j; + u8 pg_power1, pg_power2; + u8 pg_power_2g[2] = {0}, pg_power_5g[20] = {0}; + + odm_efuse_one_byte_read(dm, PPG_2GL_TXAB_14B, &pg_power_2g[0], false); + odm_efuse_one_byte_read(dm, PPG_2GL_TXCD_14B, &pg_power_2g[1], false); + + j = 0; + for (i = 0; i < 2; i++) { + if (pg_power_2g[i] == 0xff) + j++; + } + + if (j == 2) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 2G power trim no PG\n"); + } else { + power_trim_info->bb_gain[0][RF_PATH_A] = pg_power_2g[0] & 0xf; + power_trim_info->bb_gain[0][RF_PATH_B] = (pg_power_2g[0] & 0xf0) >> 4; + + power_trim_info->bb_gain[0][RF_PATH_C] = pg_power_2g[1] & 0xf; + power_trim_info->bb_gain[0][RF_PATH_D] = (pg_power_2g[1] & 0xf0) >> 4; + + power_trim_info->flag = + power_trim_info->flag | KFREE_FLAG_ON | KFREE_FLAG_ON_2G; + } + + odm_efuse_one_byte_read(dm, PPG_5GL1_TXA_14B, &pg_power_5g[0], false); + odm_efuse_one_byte_read(dm, PPG_5GL1_TXB_14B, &pg_power_5g[1], false); + odm_efuse_one_byte_read(dm, PPG_5GL1_TXC_14B, &pg_power_5g[2], false); + odm_efuse_one_byte_read(dm, PPG_5GL1_TXD_14B, &pg_power_5g[3], false); + odm_efuse_one_byte_read(dm, PPG_5GL2_TXA_14B, &pg_power_5g[4], false); + odm_efuse_one_byte_read(dm, PPG_5GL2_TXB_14B, &pg_power_5g[5], false); + odm_efuse_one_byte_read(dm, PPG_5GL2_TXC_14B, &pg_power_5g[6], false); + odm_efuse_one_byte_read(dm, PPG_5GL2_TXD_14B, &pg_power_5g[7], false); + odm_efuse_one_byte_read(dm, PPG_5GM1_TXA_14B, &pg_power_5g[8], false); + odm_efuse_one_byte_read(dm, PPG_5GM1_TXB_14B, &pg_power_5g[9], false); + odm_efuse_one_byte_read(dm, PPG_5GM1_TXC_14B, &pg_power_5g[10], false); + odm_efuse_one_byte_read(dm, PPG_5GM1_TXD_14B, &pg_power_5g[11], false); + odm_efuse_one_byte_read(dm, PPG_5GM2_TXA_14B, &pg_power_5g[12], false); + odm_efuse_one_byte_read(dm, PPG_5GM2_TXB_14B, &pg_power_5g[13], false); + odm_efuse_one_byte_read(dm, PPG_5GM2_TXC_14B, &pg_power_5g[14], false); + odm_efuse_one_byte_read(dm, PPG_5GM2_TXD_14B, &pg_power_5g[15], false); + odm_efuse_one_byte_read(dm, PPG_5GH1_TXA_14B, &pg_power_5g[16], false); + odm_efuse_one_byte_read(dm, PPG_5GH1_TXB_14B, &pg_power_5g[17], false); + odm_efuse_one_byte_read(dm, PPG_5GH1_TXC_14B, &pg_power_5g[18], false); + odm_efuse_one_byte_read(dm, PPG_5GH1_TXD_14B, &pg_power_5g[19], false); + + j = 0; + for (i = 0; i < 20; i++) { + if (pg_power_5g[i] == 0xff) + j++; + } + + if (j == 20) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 5G power trim no PG\n"); + } else { + power_trim_info->bb_gain[3][RF_PATH_A] = pg_power_5g[0] & 0x1f; + power_trim_info->bb_gain[3][RF_PATH_B] = pg_power_5g[1] & 0x1f; + power_trim_info->bb_gain[3][RF_PATH_C] = pg_power_5g[2] & 0x1f; + power_trim_info->bb_gain[3][RF_PATH_D] = pg_power_5g[3] & 0x1f; + + power_trim_info->bb_gain[4][RF_PATH_A] = pg_power_5g[4] & 0x1f; + power_trim_info->bb_gain[4][RF_PATH_B] = pg_power_5g[5] & 0x1f; + power_trim_info->bb_gain[4][RF_PATH_C] = pg_power_5g[6] & 0x1f; + power_trim_info->bb_gain[4][RF_PATH_D] = pg_power_5g[7] & 0x1f; + + power_trim_info->bb_gain[5][RF_PATH_A] = pg_power_5g[8] & 0x1f; + power_trim_info->bb_gain[5][RF_PATH_B] = pg_power_5g[9] & 0x1f; + power_trim_info->bb_gain[5][RF_PATH_C] = pg_power_5g[10] & 0x1f; + power_trim_info->bb_gain[5][RF_PATH_D] = pg_power_5g[11] & 0x1f; + + power_trim_info->bb_gain[6][RF_PATH_A] = pg_power_5g[12] & 0x1f; + power_trim_info->bb_gain[6][RF_PATH_B] = pg_power_5g[13] & 0x1f; + power_trim_info->bb_gain[6][RF_PATH_C] = pg_power_5g[14] & 0x1f; + power_trim_info->bb_gain[6][RF_PATH_D] = pg_power_5g[15] & 0x1f; + + power_trim_info->bb_gain[7][RF_PATH_A] = pg_power_5g[16] & 0x1f; + power_trim_info->bb_gain[7][RF_PATH_B] = pg_power_5g[17] & 0x1f; + power_trim_info->bb_gain[7][RF_PATH_C] = pg_power_5g[18] & 0x1f; + power_trim_info->bb_gain[7][RF_PATH_D] = pg_power_5g[19] & 0x1f; + + power_trim_info->flag = + power_trim_info->flag | KFREE_FLAG_ON | KFREE_FLAG_ON_5G; + + } + + phydm_set_power_trim_offset_8814b(dm); + + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b power trim flag:0x%02x\n", + power_trim_info->flag); + + if (power_trim_info->flag & KFREE_FLAG_ON) { + for (i = 0; i < KFREE_BAND_NUM; i++) { + for (j = 0; j < MAX_PATH_NUM_8814B; j++) { + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b pwr_trim->bb_gain[%d][%d]=0x%X\n", + i, j, power_trim_info->bb_gain[i][j]); + } + } + } +} + +void phydm_get_tssi_trim_offset_8814b(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u8 i, j; + u8 tssi_trim_2g[8] = {0}, tssi_trim_5g[24] = {0}; + + odm_efuse_one_byte_read(dm, TSSI_2GM_TXA_14B, &tssi_trim_2g[0], false); + odm_efuse_one_byte_read(dm, TSSI_2GM_TXB_14B, &tssi_trim_2g[1], false); + odm_efuse_one_byte_read(dm, TSSI_2GM_TXC_14B, &tssi_trim_2g[2], false); + odm_efuse_one_byte_read(dm, TSSI_2GM_TXD_14B, &tssi_trim_2g[3], false); + odm_efuse_one_byte_read(dm, TSSI_2GH_TXA_14B, &tssi_trim_2g[4], false); + odm_efuse_one_byte_read(dm, TSSI_2GH_TXB_14B, &tssi_trim_2g[5], false); + odm_efuse_one_byte_read(dm, TSSI_2GH_TXC_14B, &tssi_trim_2g[6], false); + odm_efuse_one_byte_read(dm, TSSI_2GH_TXD_14B, &tssi_trim_2g[7], false); + + j = 0; + for (i = 0; i < 8; i++) { + if (tssi_trim_2g[i] == 0xff) + j++; + } + + if (j == 8) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 2g tssi trim no PG\n"); + } else { + power_trim_info->tssi_trim[0][RF_PATH_A] = (s8)tssi_trim_2g[0]; + power_trim_info->tssi_trim[0][RF_PATH_B] = (s8)tssi_trim_2g[1]; + power_trim_info->tssi_trim[0][RF_PATH_C] = (s8)tssi_trim_2g[2]; + power_trim_info->tssi_trim[0][RF_PATH_D] = (s8)tssi_trim_2g[3]; + power_trim_info->tssi_trim[1][RF_PATH_A] = (s8)tssi_trim_2g[0]; + power_trim_info->tssi_trim[1][RF_PATH_B] = (s8)tssi_trim_2g[1]; + power_trim_info->tssi_trim[1][RF_PATH_C] = (s8)tssi_trim_2g[2]; + power_trim_info->tssi_trim[1][RF_PATH_D] = (s8)tssi_trim_2g[3]; + power_trim_info->tssi_trim[2][RF_PATH_A] = (s8)tssi_trim_2g[4]; + power_trim_info->tssi_trim[2][RF_PATH_B] = (s8)tssi_trim_2g[5]; + power_trim_info->tssi_trim[2][RF_PATH_C] = (s8)tssi_trim_2g[6]; + power_trim_info->tssi_trim[2][RF_PATH_D] = (s8)tssi_trim_2g[7]; + + power_trim_info->flag = + power_trim_info->flag | TSSI_TRIM_FLAG_ON | KFREE_FLAG_ON_2G; + + for (i = 0; i < KFREE_BAND_NUM; i++) { + for (j = 0; j < MAX_PATH_NUM_8814B; j++) { + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2g tssi_trim[%d][%d]=0x%X\n", + i, j, power_trim_info->tssi_trim[i][j]); + } + } + } + + odm_efuse_one_byte_read(dm, TSSI_5GL1_TXA_14B, &tssi_trim_5g[0], false); + odm_efuse_one_byte_read(dm, TSSI_5GL1_TXB_14B, &tssi_trim_5g[1], false); + odm_efuse_one_byte_read(dm, TSSI_5GL1_TXC_14B, &tssi_trim_5g[2], false); + odm_efuse_one_byte_read(dm, TSSI_5GL1_TXD_14B, &tssi_trim_5g[3], false); + odm_efuse_one_byte_read(dm, TSSI_5GL2_TXA_14B, &tssi_trim_5g[4], false); + odm_efuse_one_byte_read(dm, TSSI_5GL2_TXB_14B, &tssi_trim_5g[5], false); + odm_efuse_one_byte_read(dm, TSSI_5GL2_TXC_14B, &tssi_trim_5g[6], false); + odm_efuse_one_byte_read(dm, TSSI_5GL2_TXD_14B, &tssi_trim_5g[7], false); + odm_efuse_one_byte_read(dm, TSSI_5GM1_TXA_14B, &tssi_trim_5g[8], false); + odm_efuse_one_byte_read(dm, TSSI_5GM1_TXB_14B, &tssi_trim_5g[9], false); + odm_efuse_one_byte_read(dm, TSSI_5GM1_TXC_14B, &tssi_trim_5g[10], false); + odm_efuse_one_byte_read(dm, TSSI_5GM1_TXD_14B, &tssi_trim_5g[11], false); + odm_efuse_one_byte_read(dm, TSSI_5GM2_TXA_14B, &tssi_trim_5g[12], false); + odm_efuse_one_byte_read(dm, TSSI_5GM2_TXB_14B, &tssi_trim_5g[13], false); + odm_efuse_one_byte_read(dm, TSSI_5GM2_TXC_14B, &tssi_trim_5g[14], false); + odm_efuse_one_byte_read(dm, TSSI_5GM2_TXD_14B, &tssi_trim_5g[15], false); + odm_efuse_one_byte_read(dm, TSSI_5GH1_TXA_14B, &tssi_trim_5g[16], false); + odm_efuse_one_byte_read(dm, TSSI_5GH1_TXB_14B, &tssi_trim_5g[17], false); + odm_efuse_one_byte_read(dm, TSSI_5GH1_TXC_14B, &tssi_trim_5g[18], false); + odm_efuse_one_byte_read(dm, TSSI_5GH1_TXD_14B, &tssi_trim_5g[19], false); + odm_efuse_one_byte_read(dm, TSSI_5GH2_TXA_14B, &tssi_trim_5g[20], false); + odm_efuse_one_byte_read(dm, TSSI_5GH2_TXB_14B, &tssi_trim_5g[21], false); + odm_efuse_one_byte_read(dm, TSSI_5GH2_TXC_14B, &tssi_trim_5g[22], false); + odm_efuse_one_byte_read(dm, TSSI_5GH2_TXD_14B, &tssi_trim_5g[23], false); + + j = 0; + for (i = 0; i < 24; i++) { + if (tssi_trim_5g[i] == 0xff) + j++; + } + + if (j == 24) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 5g tssi trim no PG\n"); + } else { + power_trim_info->tssi_trim[3][RF_PATH_A] = (s8)tssi_trim_5g[0]; + power_trim_info->tssi_trim[3][RF_PATH_B] = (s8)tssi_trim_5g[1]; + power_trim_info->tssi_trim[3][RF_PATH_C] = (s8)tssi_trim_5g[2]; + power_trim_info->tssi_trim[3][RF_PATH_D] = (s8)tssi_trim_5g[3]; + power_trim_info->tssi_trim[4][RF_PATH_A] = (s8)tssi_trim_5g[4]; + power_trim_info->tssi_trim[4][RF_PATH_B] = (s8)tssi_trim_5g[5]; + power_trim_info->tssi_trim[4][RF_PATH_C] = (s8)tssi_trim_5g[6]; + power_trim_info->tssi_trim[4][RF_PATH_D] = (s8)tssi_trim_5g[7]; + power_trim_info->tssi_trim[5][RF_PATH_A] = (s8)tssi_trim_5g[8]; + power_trim_info->tssi_trim[5][RF_PATH_B] = (s8)tssi_trim_5g[9]; + power_trim_info->tssi_trim[5][RF_PATH_C] = (s8)tssi_trim_5g[10]; + power_trim_info->tssi_trim[5][RF_PATH_D] = (s8)tssi_trim_5g[11]; + power_trim_info->tssi_trim[6][RF_PATH_A] = (s8)tssi_trim_5g[12]; + power_trim_info->tssi_trim[6][RF_PATH_B] = (s8)tssi_trim_5g[13]; + power_trim_info->tssi_trim[6][RF_PATH_C] = (s8)tssi_trim_5g[14]; + power_trim_info->tssi_trim[6][RF_PATH_D] = (s8)tssi_trim_5g[15]; + power_trim_info->tssi_trim[7][RF_PATH_A] = (s8)tssi_trim_5g[16]; + power_trim_info->tssi_trim[7][RF_PATH_B] = (s8)tssi_trim_5g[17]; + power_trim_info->tssi_trim[7][RF_PATH_C] = (s8)tssi_trim_5g[18]; + power_trim_info->tssi_trim[7][RF_PATH_D] = (s8)tssi_trim_5g[19]; + power_trim_info->tssi_trim[8][RF_PATH_A] = (s8)tssi_trim_5g[20]; + power_trim_info->tssi_trim[8][RF_PATH_B] = (s8)tssi_trim_5g[21]; + power_trim_info->tssi_trim[8][RF_PATH_C] = (s8)tssi_trim_5g[22]; + power_trim_info->tssi_trim[8][RF_PATH_D] = (s8)tssi_trim_5g[23]; + + power_trim_info->flag = + power_trim_info->flag | TSSI_TRIM_FLAG_ON | KFREE_FLAG_ON_5G; + + for (i = 0; i < KFREE_BAND_NUM; i++) { + for (j = 0; j < MAX_PATH_NUM_8814B; j++) { + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 5g tssi_trim[%d][%d]=0x%X\n", + i, j, power_trim_info->tssi_trim[i][j]); + } + } + } +} + +s8 phydm_get_tssi_trim_de_8814b(void *dm_void, u8 path) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u8 channel = *dm->channel, group = 0; + + if (channel >= 1 && channel <= 3) + group = 0; + else if (channel >= 4 && channel <= 9) + group = 1; + else if (channel >= 10 && channel <= 14) + group = 2; + else if (channel >= 36 && channel <= 50) + group = 3; + else if (channel >= 52 && channel <= 64) + group = 4; + else if (channel >= 100 && channel <= 118) + group = 5; + else if (channel >= 120 && channel <= 144) + group = 6; + else if (channel >= 149 && channel <= 165) + group = 7; + else if (channel >= 167 && channel <= 177) + group = 8; + else { + RF_DBG(dm, DBG_RF_MP, "[kfree] Channel(%d) is not exist in Group\n", + channel); + return 0; + } + + return power_trim_info->tssi_trim[group][path]; +} + +void phydm_set_pabias_bandedge_2g_rf_8814b(void *dm_void) +{ +#if 0 + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u32 rf_reg_51 = 0, rf_reg_52 = 0, rf_reg_53 = 0, rf_reg_3f = 0; + u8 i, j; + s32 pa_bias_tmp, bandedge_tmp, reg_tmp; + +#if 0 + /*2.4G bias*/ + /*rf3f == rf53*/ +#endif + for (i = 0; i < MAX_PATH_NUM_8814B; i++) { + rf_reg_51 = odm_get_rf_reg(dm, i, RF_0x51, RFREGOFFSETMASK); + rf_reg_52 = odm_get_rf_reg(dm, i, RF_0x52, RFREGOFFSETMASK); + rf_reg_53 = odm_get_rf_reg(dm, i, RF_0x53, RFREGOFFSETMASK); + + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2g rf(0x51)=0x%X rf(0x52)=0x%X rf(0x53)=0x%X path=%d\n", + rf_reg_51, rf_reg_52, rf_reg_53, i); + + /*2.4G bias*/ + rf_reg_3f = rf_reg_53; + pa_bias_tmp = rf_reg_3f & 0xf; + + reg_tmp = pa_bias_tmp + power_trim_info->pa_bias_trim[0][i]; + + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2g pa bias reg_tmp(%d) = pa_bias_tmp(%d) + power_trim_info->pa_bias_trim[0][%d](%d)\n", + reg_tmp, pa_bias_tmp, i, power_trim_info->pa_bias_trim[0][i]); + +#if 0 + if (reg_tmp < 0) { + reg_tmp = 0; + RF_DBG(dm, DBG_RF_MP, + "[kfree] 2g pa bias reg_tmp < 0. Set 0 path=%d\n", i); + } else if (reg_tmp > 7) { + reg_tmp = 7; + RF_DBG(dm, DBG_RF_MP, + "[kfree] 2g pa bias reg_tmp > 7. Set 7 path=%d\n", i); + } +#endif + + rf_reg_3f = ((rf_reg_3f & 0xffff0) | reg_tmp); + rf_reg_3f = ((rf_reg_3f & 0x0ffff) | 0x10000); + + odm_set_rf_reg(dm, i, RF_0xef, BIT(10), 0x1); + for (j = 0; j <= 0xf; j++) { + odm_set_rf_reg(dm, i, RF_0x30, RFREGOFFSETMASK, (j << 16)); + odm_set_rf_reg(dm, i, RF_0x3f, RFREGOFFSETMASK, rf_reg_3f); + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2G pa bias write RF_0x30=0x%05x RF_0x3f=0x%x path=%d\n", + (j << 16), rf_reg_3f, i); + } + odm_set_rf_reg(dm, i, RF_0xef, BIT(10), 0x0); + +#if 0 + /*2.4G bandedge*/ + /*rf3f =>*/ + /*rf51[3:1] = rf3f[17:15]*/ + /*rf52[2:0] = rf3f[14:12]*/ + /*rf52[18] = rf3f[11]*/ + /*rf51[6:4] = rf3f[10:8]*/ + /*rf51[11:8] = rf3f[7:4]*/ + /*rf51[16:13] = rf3f[3:0]*/ +#endif + /*2.4G bandedge*/ + rf_reg_3f = (((rf_reg_51 & 0xe) >> 1) << 15) | + ((rf_reg_52 & 0x7) << 12) | + (((rf_reg_52 & 0x40000) >> 18) << 11) | + (((rf_reg_51 & 0x70) >> 4) << 8) | + (((rf_reg_51 & 0xf00) >> 8) << 4) | + ((rf_reg_51 & 0x1e000) >> 13); + + bandedge_tmp = rf_reg_3f & 0xf; + + reg_tmp = bandedge_tmp + power_trim_info->pa_bias_trim[0][i]; + + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2g bandedge reg_tmp(%d) = bandedge_tmp(%d) + power_trim_info->pa_bias_trim[0][%d](%d)\n", + reg_tmp, bandedge_tmp, i, power_trim_info->pa_bias_trim[0][i]); + +#if 0 + if (reg_tmp < 0) { + reg_tmp = 0; + RF_DBG(dm, DBG_RF_MP, + "[kfree] 2g bandedge reg_tmp < 0. Set 0 path=%d\n", i); + } else if (reg_tmp > 7) { + reg_tmp = 7; + RF_DBG(dm, DBG_RF_MP, + "[kfree] 2g bandedge reg_tmp > 7. Set 7 path=%d\n", i); + } +#endif + + rf_reg_3f = ((rf_reg_3f & 0xffff0) | reg_tmp); + + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2G bandedge RF_0x30=0x%05X RF_0x3f=0x%x path=%d\n", + 0x00001, rf_reg_3f, i); + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2G bandedge RF_0x30=0x%05X RF_0x3f=0x%x path=%d\n", + 0x0000b, rf_reg_3f, i); + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2G bandedge RF_0x30=0x%05X RF_0x3f=0x%x path=%d\n", + 0x00023, rf_reg_3f, i); + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2G bandedge RF_0x30=0x%05X RF_0x3f=0x%x path=%d\n", + 0x00029, rf_reg_3f, i); + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2G bandedge RF_0x30=0x%05X RF_0x3f=0x%x path=%d\n", + 0x0002a, rf_reg_3f, i); + + odm_set_rf_reg(dm, i, RF_0xef, BIT(8), 0x1); + odm_set_rf_reg(dm, i, RF_0x33, RFREGOFFSETMASK, 0x00001); + odm_set_rf_reg(dm, i, RF_0x3f, RFREGOFFSETMASK, rf_reg_3f); + odm_set_rf_reg(dm, i, RF_0x33, RFREGOFFSETMASK, 0x0000b); + odm_set_rf_reg(dm, i, RF_0x3f, RFREGOFFSETMASK, rf_reg_3f); + odm_set_rf_reg(dm, i, RF_0x33, RFREGOFFSETMASK, 0x00023); + odm_set_rf_reg(dm, i, RF_0x3f, RFREGOFFSETMASK, rf_reg_3f); + odm_set_rf_reg(dm, i, RF_0x33, RFREGOFFSETMASK, 0x00029); + odm_set_rf_reg(dm, i, RF_0x3f, RFREGOFFSETMASK, rf_reg_3f); + odm_set_rf_reg(dm, i, RF_0x33, RFREGOFFSETMASK, 0x0002a); + odm_set_rf_reg(dm, i, RF_0x3f, RFREGOFFSETMASK, rf_reg_3f); + odm_set_rf_reg(dm, i, RF_0xef, BIT(8), 0x0); + + } +#endif +} + +void phydm_set_pabias_bandedge_5g_rf_8814b(void *dm_void) +{ +#if 0 + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u32 rf_reg_18[MAX_PATH_NUM_8814B] = {0}, + rf_reg_61[15][MAX_PATH_NUM_8814B] = {0}, + rf_reg_62[3][MAX_PATH_NUM_8814B] = {0}; + u8 i, j; + u32 bandedge[15][MAX_PATH_NUM_8814B] = {0}, + pa_bias[3][MAX_PATH_NUM_8814B] = {0}; + + s32 pa_bias_tmp, reg_tmp; + + + for (i = 0; i < MAX_PATH_NUM_8814B; i++) { + rf_reg_18[i] = odm_get_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK); + + for (j = 0; j < 3; j++) { + if (j == 0) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x10d24); + else if (j == 1) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x30d64); + else if (j == 2) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x50da9); + + rf_reg_62[j][i] = odm_get_rf_reg(dm, i, 0x62, RFREGOFFSETMASK); + +#if 0 + /*5G bias*/ + /*rf62[19:16] == rf30[11:8]*/ + /*rf62[15:12] == rf30[7:4]*/ + /*rf62[11:8] == rf3030[3:0]*/ +#endif + pa_bias[j][i] = (((rf_reg_62[j][i] & 0xf0000) >> 16) << 8) | + (((rf_reg_62[j][i] & 0xf000) >> 12) << 4) | + ((rf_reg_62[j][i] & 0xf00) >> 8); + } + + for (j = 0; j < 15; j++) { + if (j == 0) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x10d24);/*ch36*/ + else if (j == 1) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x11926);/*ch38*/ + else if (j == 2) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x1252a);/*ch42*/ + else if (j == 3) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x1253a);/*ch58*/ + else if (j == 4) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x1193e);/*ch62*/ + else if (j == 5) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x10d40);/*ch64*/ + else if (j == 6) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x30d64);/*ch100*/ + else if (j == 7) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x31966);/*ch102*/ + else if (j == 8) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x3256a);/*ch106*/ + else if (j == 9) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x3257a);/*ch122*/ + else if (j == 10) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x31986);/*ch134*/ + else if (j == 11) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x30d8c);/*ch140*/ + else if (j == 12) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x50d95);/*ch149*/ + else if (j == 13) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x51997);/*ch151*/ + else if (j == 14) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x5259b);/*ch155*/ + + + rf_reg_61[j][i] = odm_get_rf_reg(dm, i, RF_0x61, RFREGOFFSETMASK); +#if 0 + /*5G bandedge*/ + /*rf61[11:8] == rf30[11:8]*/ + /*rf61[7:4] == rf30[7:4]*/ + /*rf61[3:0] == rf3030[3:0]*/ +#endif + bandedge[j][i] = rf_reg_61[j][i] & 0xfff; + } + + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, rf_reg_18[i]); + } + + for (i = 0; i < MAX_PATH_NUM_8814B; i++) { + for (j = 0; j < 3; j++) { + RF_DBG(dm, DBG_RF_MP, + "[kfree] pa_bias[%d][%d]=0x%x\n", j, i, pa_bias[j][i]); + } + } + + for (i = 0; i < MAX_PATH_NUM_8814B; i++) { + for (j = 0; j < 15; j++) { + RF_DBG(dm, DBG_RF_MP, + "[kfree] bandedge[%d][%d]=0x%x\n", j, i, bandedge[j][i]); + } + } + + /*5G bias*/ + for (i = 0; i < MAX_PATH_NUM_8814B; i++) { + odm_set_rf_reg(dm, i, RF_0xee, BIT(8), 0x1); + for (j = 0; j <= 0xb; j++) { + + if (j >= 0 && j <= 3) + pa_bias_tmp = pa_bias[0][i] & 0xf; + else if (j >= 4 && j <= 0x7) + pa_bias_tmp = pa_bias[1][i] & 0xf; + else if (j >= 0x8 && j <= 0xb) + pa_bias_tmp = pa_bias[2][i] & 0xf; + + reg_tmp = pa_bias_tmp + power_trim_info->pa_bias_trim[1][i]; + + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 5g pa bias reg_tmp(%d) = pa_bias_tmp(%d) + power_trim_info->pa_bias_trim[1][%d](%d)\n", + reg_tmp, pa_bias_tmp, i, power_trim_info->pa_bias_trim[1][i]); +#if 0 + if (reg_tmp < 0) { + reg_tmp = 0; + RF_DBG(dm, DBG_RF_MP, + "[kfree] 5g pa bias reg_tmp < 0. Set 0 path=%d\n", i); + } else if (reg_tmp > 7) { + reg_tmp = 7; + RF_DBG(dm, DBG_RF_MP, + "[kfree] 5g pa bias reg_tmp > 7. Set 7 path=%d\n", i); + } +#endif + if (j >= 0 && j <= 3) + reg_tmp = ((pa_bias[0][i] & 0xffff0) | reg_tmp | (j << 12)); + else if (j >= 4 && j <= 0x7) + reg_tmp = ((pa_bias[1][i] & 0xffff0) | reg_tmp | (j << 12)); + else if (j >= 0x8 && j <= 0xb) + reg_tmp = ((pa_bias[2][i] & 0xffff0) | reg_tmp | (j << 12)); + + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b write RF_0x30=0x%05x path=%d\n", + reg_tmp, i); + + odm_set_rf_reg(dm, i, RF_0x30, RFREGOFFSETMASK, reg_tmp); + } + odm_set_rf_reg(dm, i, RF_0xee, BIT(8), 0x0); + } + + /*5G bandedge*/ + for (i = 0; i < MAX_PATH_NUM_8814B; i++) { + odm_set_rf_reg(dm, i, RF_0xee, BIT(9), 0x1); + for (j = 0; j <= 0xe; j++) { + reg_tmp = bandedge[j][i] + power_trim_info->pa_bias_trim[1][i]; + + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 5g bandedge reg_tmp(%d)(0x%X) = bandedge_org(%d) + power_trim_info->pa_bias_trim[1][%d](%d)\n", + reg_tmp, reg_tmp, bandedge[j][i], i, power_trim_info->pa_bias_trim[1][i]); +#if 0 + if (reg_tmp < 0) { + reg_tmp = 0; + RF_DBG(dm, DBG_RF_MP, + "[kfree] 5g bandedge reg_tmp < 0. Set 0 path=%d\n", i); + } else if (reg_tmp > 7) { + reg_tmp = 7; + RF_DBG(dm, DBG_RF_MP, + "[kfree] 5g bandedge reg_tmp > 7. Set 7 path=%d\n", i); + } +#endif + + reg_tmp = ((bandedge[j][i] & 0xffff0) | reg_tmp | (j << 12)); + + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b write RF_0x30=0x%05x path=%d\n", + reg_tmp, i); + + odm_set_rf_reg(dm, i, RF_0x30, RFREGOFFSETMASK, reg_tmp); + } + odm_set_rf_reg(dm, i, RF_0xee, BIT(9), 0x0); + } + +#endif +} + + +void phydm_get_pa_bias_offset_8814b(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u8 i, j, k; + u8 tssi_pa_bias_2g[2] = {0}, tssi_pa_bias_5g[2] = {0}; + + odm_efuse_one_byte_read(dm, PPG_PABIAS_2GAC_14B, &tssi_pa_bias_2g[0], false); + odm_efuse_one_byte_read(dm, PPG_PABIAS_2GBD_14B, &tssi_pa_bias_2g[1], false); + + j = 0; + for (i = 0; i < 2; i++) { + if (tssi_pa_bias_2g[i] == 0xff) + j++; + } + + if (j == 2) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 2g PA Bias K no PG\n"); + } else { + power_trim_info->pa_bias_trim[0][RF_PATH_A] = tssi_pa_bias_2g[0] & 0xf; + power_trim_info->pa_bias_trim[0][RF_PATH_C] = (tssi_pa_bias_2g[0] & 0xf0) >> 4; + power_trim_info->pa_bias_trim[0][RF_PATH_B] = tssi_pa_bias_2g[1] & 0xf; + power_trim_info->pa_bias_trim[0][RF_PATH_D] = (tssi_pa_bias_2g[1] & 0xf0) >> 4; + + for (k = 0; k < MAX_PATH_NUM_8814B; k++) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 2g PA Bias K efuse:0x%x path=%d\n", + power_trim_info->pa_bias_trim[0][k], k); + odm_set_rf_reg(dm, k, 0x60, 0x0000f000, power_trim_info->pa_bias_trim[0][k]); + } + +#if 0 + for (k = 0; k < MAX_PATH_NUM_8814B; k++) { + if ((power_trim_info->pa_bias_trim[0][k] & BIT(0)) == 0) + power_trim_info->pa_bias_trim[0][k] = (-1 * (power_trim_info->pa_bias_trim[0][k] >> 1)); + else + power_trim_info->pa_bias_trim[0][k] = (power_trim_info->pa_bias_trim[0][k] >> 1); + + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 2g PA Bias K power_trim_info->pa_bias_trim[0][%d]=0x%x\n", + k, power_trim_info->pa_bias_trim[0][k]); + } + + phydm_set_pabias_bandedge_2g_rf_8814b(dm); +#endif + } + + odm_efuse_one_byte_read(dm, PPG_PABIAS_5GAC_14B, &tssi_pa_bias_5g[0], false); + odm_efuse_one_byte_read(dm, PPG_PABIAS_5GBD_14B, &tssi_pa_bias_5g[1], false); + + j = 0; + for (i = 0; i < 2; i++) { + if (tssi_pa_bias_5g[i] == 0xff) + j++; + } + + if (j == 2) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 5g PA Bias K no PG\n"); + } else { + power_trim_info->pa_bias_trim[1][RF_PATH_A] = tssi_pa_bias_5g[0] & 0xf; + power_trim_info->pa_bias_trim[1][RF_PATH_C] = (tssi_pa_bias_5g[0] & 0xf0) >> 4; + power_trim_info->pa_bias_trim[1][RF_PATH_B] = tssi_pa_bias_5g[1] & 0xf; + power_trim_info->pa_bias_trim[1][RF_PATH_D] = (tssi_pa_bias_5g[1] & 0xf0) >> 4; + + for (k = 0; k < MAX_PATH_NUM_8814B; k++) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 5g PA Bias K efuse:0x%x path=%d\n", + power_trim_info->pa_bias_trim[1][k], k); + + odm_set_rf_reg(dm, k, 0x60, 0x000f0000, power_trim_info->pa_bias_trim[1][k]); + } +#if 0 + for (k = 0; k < MAX_PATH_NUM_8814B; k++) { + if ((power_trim_info->pa_bias_trim[1][k] & BIT(0)) == 0) + power_trim_info->pa_bias_trim[1][k] = (-1 * (power_trim_info->pa_bias_trim[1][k] >> 1)); + else + power_trim_info->pa_bias_trim[1][k] = (power_trim_info->pa_bias_trim[1][k] >> 1); + + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 5g PA Bias K power_trim_info->pa_bias_trim[1][%d]=0x%x\n", + k, power_trim_info->pa_bias_trim[1][k]); + } + + phydm_set_pabias_bandedge_5g_rf_8814b(dm); +#endif + } + + +} + +void phydm_get_thermal_trim_offset_8814b(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u8 pg_therm = 0xff, i; + + odm_efuse_one_byte_read(dm, PPG_THERMAL_A_OFFSET_14B, &pg_therm, false); + + if (pg_therm != 0xff) { + for (i = 0; i < MAX_PATH_NUM_8814B; i++) { + if (i == 0) + odm_efuse_one_byte_read(dm, PPG_THERMAL_A_OFFSET_14B, &pg_therm, false); + else if (i == 1) + odm_efuse_one_byte_read(dm, PPG_THERMAL_B_OFFSET_14B, &pg_therm, false); + else if (i == 2) + odm_efuse_one_byte_read(dm, PPG_THERMAL_C_OFFSET_14B, &pg_therm, false); + else if (i == 3) + odm_efuse_one_byte_read(dm, PPG_THERMAL_D_OFFSET_14B, &pg_therm, false); + + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b Efuse thermal S%d:0x%x\n", i, pg_therm); + pg_therm = pg_therm & 0x1f; + if ((pg_therm & BIT(0)) == 0) + power_trim_info->multi_thermal[i] = (-1 * (pg_therm >> 1)); + else + power_trim_info->multi_thermal[i] = (pg_therm >> 1); + } + + power_trim_info->flag |= KFREE_FLAG_THERMAL_K_ON; + } + + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b thermal trim flag:0x%02x\n", + power_trim_info->flag); + + for (i = 0; i < MAX_RF_PATH; i++) { + if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b thermal S%d:%d\n", + i ,power_trim_info->multi_thermal[i]); + } +} + +void phydm_get_thermal_trim_offset_8723f(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + u8 pg_therm = 0xff, thermal[2] = {0}; +#if 0 + odm_efuse_one_byte_read(dm, PPG_THERMAL_A_OFFSET_22C, &pg_therm, false); + + if (pg_therm != 0xff) { + /*s0*/ + pg_therm = pg_therm & 0x1f; + + thermal[RF_PATH_A] = + ((pg_therm & 0x1) << 3) | ((pg_therm >> 1) & 0x7); + + odm_set_rf_reg(dm, RF_PATH_A, RF_0x43, 0x000f0000, thermal[RF_PATH_A]); + + /*s1*/ + odm_efuse_one_byte_read(dm, PPG_THERMAL_B_OFFSET_22C, &pg_therm, false); + + pg_therm = pg_therm & 0x1f; + + thermal[RF_PATH_B] = ((pg_therm & 0x1) << 3) | ((pg_therm >> 1) & 0x7); + + odm_set_rf_reg(dm, RF_PATH_B, RF_0x43, 0x000f0000, thermal[RF_PATH_B]); + + power_trim_info->flag |= KFREE_FLAG_THERMAL_K_ON; + + } + + RF_DBG(dm, DBG_RF_MP, "[kfree] 8822c thermal trim flag:0x%02x\n", + power_trim_info->flag); + + if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) + RF_DBG(dm, DBG_RF_MP, "[kfree] 8822c thermalA:%d thermalB:%d\n", + thermal[RF_PATH_A], + thermal[RF_PATH_B]); +#endif +} + +void phydm_get_set_power_trim_offset_8723f(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + u8 pg_power = 0xff, i, j; + u8 pg_power1, pg_power2 , pg_power3, pg_power4, pg_power5; +#if 0 + odm_efuse_one_byte_read(dm, PPG_2GL_TXAB_22C, &pg_power1, false); + odm_efuse_one_byte_read(dm, PPG_2GM_TXAB_22C, &pg_power2, false); + odm_efuse_one_byte_read(dm, PPG_2GH_TXAB_22C, &pg_power3, false); + odm_efuse_one_byte_read(dm, PPG_5GL1_TXA_22C, &pg_power4, false); + odm_efuse_one_byte_read(dm, PPG_5GL1_TXB_22C, &pg_power5, false); + + if (pg_power1 != 0xff || pg_power2 != 0xff || pg_power3 != 0xff || + pg_power4 != 0xff || pg_power5 != 0xff) { + odm_efuse_one_byte_read(dm, PPG_2GL_TXAB_22C, &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[0][0] = pg_power & 0xf; + power_trim_info->bb_gain[0][1] = (pg_power & 0xf0) >> 4; + + odm_efuse_one_byte_read(dm, PPG_2GM_TXAB_22C, &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[1][0] = pg_power & 0xf; + power_trim_info->bb_gain[1][1] = (pg_power & 0xf0) >> 4; + + odm_efuse_one_byte_read(dm, PPG_2GH_TXAB_22C, &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[2][0] = pg_power & 0xf; + power_trim_info->bb_gain[2][1] = (pg_power & 0xf0) >> 4; + + odm_efuse_one_byte_read(dm, PPG_5GL1_TXA_22C, &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[3][0] = pg_power & 0x1f; + odm_efuse_one_byte_read(dm, PPG_5GL1_TXB_22C, &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[3][1] = pg_power & 0x1f; + + odm_efuse_one_byte_read(dm, PPG_5GL2_TXA_22C, &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[4][0] = pg_power & 0x1f; + odm_efuse_one_byte_read(dm, PPG_5GL2_TXB_22C, &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[4][1] = pg_power & 0x1f; + + odm_efuse_one_byte_read(dm, PPG_5GM1_TXA_22C, &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[5][0] = pg_power & 0x1f; + odm_efuse_one_byte_read(dm, PPG_5GM1_TXB_22C, &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[5][1] = pg_power & 0x1f; + + odm_efuse_one_byte_read(dm, PPG_5GM2_TXA_22C, &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[6][0] = pg_power & 0x1f; + odm_efuse_one_byte_read(dm, PPG_5GM2_TXB_22C, &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[6][1] = pg_power & 0x1f; + + odm_efuse_one_byte_read(dm, PPG_5GH1_TXA_22C, &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[7][0] = pg_power & 0x1f; + odm_efuse_one_byte_read(dm, PPG_5GH1_TXB_22C, &pg_power, false); + if (pg_power == 0xff) + pg_power = 0; + power_trim_info->bb_gain[7][1] = pg_power & 0x1f; + + power_trim_info->flag = + power_trim_info->flag | KFREE_FLAG_ON | + KFREE_FLAG_ON_2G | + KFREE_FLAG_ON_5G; + + phydm_set_power_trim_offset_8822c(dm); + } + + RF_DBG(dm, DBG_RF_MP, "[kfree] 8822c power trim flag:0x%02x\n", + power_trim_info->flag); + + if (power_trim_info->flag & KFREE_FLAG_ON) { + for (i = 0; i < KFREE_BAND_NUM; i++) { + for (j = 0; j < 2; j++) { + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8822c pwr_trim->bb_gain[%d][%d]=0x%X\n", + i, j, power_trim_info->bb_gain[i][j]); + } + } + } +#endif +} + +void phydm_get_tssi_trim_offset_8723f(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + u8 i, j, k; + u8 pg_power[16] = {0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff}; +#if 1 + odm_efuse_one_byte_read(dm, TSSI_2GM_TXA_22C, &pg_power[0], false); + odm_efuse_one_byte_read(dm, TSSI_2GM_TXB_22C, &pg_power[1], false); + odm_efuse_one_byte_read(dm, TSSI_2GH_TXA_22C, &pg_power[2], false); + odm_efuse_one_byte_read(dm, TSSI_2GH_TXB_22C, &pg_power[3], false); + odm_efuse_one_byte_read(dm, TSSI_5GL1_TXA_22C, &pg_power[4], false); + //odm_efuse_one_byte_read(dm, TSSI_5GL1_TXB_22C, &pg_power[5], false); + odm_efuse_one_byte_read(dm, TSSI_5GL2_TXA_22C, &pg_power[6], false); + //odm_efuse_one_byte_read(dm, TSSI_5GL2_TXB_22C, &pg_power[7], false); + odm_efuse_one_byte_read(dm, TSSI_5GM1_TXA_22C, &pg_power[8], false); + //odm_efuse_one_byte_read(dm, TSSI_5GM1_TXB_22C, &pg_power[9], false); + odm_efuse_one_byte_read(dm, TSSI_5GM2_TXA_22C, &pg_power[10], false); + //odm_efuse_one_byte_read(dm, TSSI_5GM2_TXB_22C, &pg_power[11], false); + odm_efuse_one_byte_read(dm, TSSI_5GH1_TXA_22C, &pg_power[12], false); + //odm_efuse_one_byte_read(dm, TSSI_5GH1_TXB_22C, &pg_power[13], false); + odm_efuse_one_byte_read(dm, TSSI_5GH2_TXA_22C, &pg_power[14], false); + //odm_efuse_one_byte_read(dm, TSSI_5GH2_TXB_22C, &pg_power[15], false); + + j = 0; + for (i = 0; i < 16; i++) { + if ((pg_power[i] & 0xff) == 0xff) + j++; + } + + if (j == 16) { + for (i = 0; i < 9; i++) + for(k = 0; i < 2; i++) + power_trim_info->tssi_trim[i][k] = 0; + RF_DBG(dm, DBG_RF_MP, "[kfree] 8723F tssi trim no PG\n"); + } else { + //power_trim_info->tssi_trim[0][0] = (s8)pg_power[0]; + //power_trim_info->tssi_trim[0][1] = (s8)pg_power[1]; + power_trim_info->tssi_trim[0][0] = (s8)pg_power[0]; + power_trim_info->tssi_trim[0][1] = (s8)pg_power[1]; + power_trim_info->tssi_trim[1][0] = (s8)pg_power[2]; + power_trim_info->tssi_trim[1][1] = (s8)pg_power[3]; + power_trim_info->tssi_trim[2][0] = (s8)pg_power[4]; + power_trim_info->tssi_trim[2][1] = (s8)pg_power[5]; + power_trim_info->tssi_trim[3][0] = (s8)pg_power[6]; + power_trim_info->tssi_trim[3][1] = (s8)pg_power[7]; + power_trim_info->tssi_trim[4][0] = (s8)pg_power[8]; + power_trim_info->tssi_trim[4][1] = (s8)pg_power[9]; + power_trim_info->tssi_trim[5][0] = (s8)pg_power[10]; + power_trim_info->tssi_trim[5][1] = (s8)pg_power[11]; + power_trim_info->tssi_trim[6][0] = (s8)pg_power[12]; + power_trim_info->tssi_trim[6][1] = (s8)pg_power[13]; + power_trim_info->tssi_trim[7][0] = (s8)pg_power[14]; + power_trim_info->tssi_trim[7][1] = (s8)pg_power[15]; + + power_trim_info->flag = + power_trim_info->flag | TSSI_TRIM_FLAG_ON; + + if (power_trim_info->flag & TSSI_TRIM_FLAG_ON) { + for (i = 0; i < 8; i++) { //KFREE_BAND_NUM + for (j = 0; j < 2; j++) { + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8723F tssi_trim[%d][%d]=0x%X\n", + i, j, power_trim_info->tssi_trim[i][j]); + } + } + } + } +#endif +} + +s8 phydm_get_tssi_trim_de_8723f(void *dm_void, u8 path) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + u8 channel = *dm->channel, group = 0; + + if (channel >= 1 && channel <= 7) { + group = 0; + } else if (channel >= 8 && channel <= 14) { + group = 1; + } else if (channel >= 36 && channel <= 50) { + group = 2; + } else if (channel >= 52 && channel <= 64) { + group = 3; + } else if (channel >= 100 && channel <= 128) { + group = 4; + } else if (channel >= 129 && channel <= 144) { + group = 5; + } else if (channel >= 149 && channel <= 163) { + group = 6; + } else if (channel >= 164 && channel <= 177) { + group = 7; + } else { + RF_DBG(dm, DBG_RF_MP, "[kfree] Channel(%d) is not exist in Group\n", channel); + return 0; + } + + return power_trim_info->tssi_trim[group][path]; +} s8 phydm_get_tssi_trim_de(void *dm_void, u8 path) { @@ -2374,8 +3585,14 @@ s8 phydm_get_tssi_trim_de(void *dm_void, u8 path) return phydm_get_tssi_trim_de_8822c(dm, path); else if (dm->support_ic_type & ODM_RTL8812F) return phydm_get_tssi_trim_de_8812f(dm, path); + else if (dm->support_ic_type & ODM_RTL8197G) + return phydm_get_tssi_trim_de_8197g(dm, path); + else if (dm->support_ic_type & ODM_RTL8814B) + return phydm_get_tssi_trim_de_8814b(dm, path); + else if (dm->support_ic_type & ODM_RTL8723F) + return phydm_get_tssi_trim_de_8723f(dm, path); else - return 0; + return 0; } void phydm_do_new_kfree(void *dm_void) @@ -2408,15 +3625,17 @@ void phydm_do_new_kfree(void *dm_void) /*phydm_get_set_pa_bias_offset_8721d(dm);*/ } - if (dm->support_ic_type & ODM_RTL8198F) + if (dm->support_ic_type & ODM_RTL8198F) { + phydm_get_pa_bias_offset_8198f(dm); phydm_get_set_lna_offset_8198f(dm); + } if (dm->support_ic_type & ODM_RTL8197G) { phydm_get_thermal_trim_offset_8197g(dm); phydm_get_set_power_trim_offset_8197g(dm); phydm_get_set_pa_bias_offset_8197g(dm); - /*phydm_get_tssi_trim_offset_8197g(dm);*/ - /*phydm_get_set_lna_offset_8197g(dm);*/ + phydm_get_tssi_trim_offset_8197g(dm); + phydm_get_set_lna_offset_8197g(dm); } if (dm->support_ic_type & ODM_RTL8710C) { @@ -2424,6 +3643,19 @@ void phydm_do_new_kfree(void *dm_void) phydm_get_set_power_trim_offset_8710c(dm); phydm_get_set_pa_bias_offset_8710c(dm); } + + if (dm->support_ic_type & ODM_RTL8814B) { + phydm_get_thermal_trim_offset_8814b(dm); + phydm_get_set_power_trim_offset_8814b(dm); + phydm_get_pa_bias_offset_8814b(dm); + phydm_get_tssi_trim_offset_8814b(dm); + } + if (dm->support_ic_type & ODM_RTL8723F) { + phydm_get_thermal_trim_offset_8723f(dm); + phydm_get_set_power_trim_offset_8723f(dm); + //phydm_get_set_pa_bias_offset_8723f(dm); + phydm_get_tssi_trim_offset_8723f(dm); + } } void phydm_set_kfree_to_rf(void *dm_void, u8 e_rf_path, u8 data) @@ -2531,9 +3763,6 @@ void phydm_get_pa_bias_offset(void *dm_void) if (dm->support_ic_type & ODM_RTL8822B) phydm_get_pa_bias_offset_8822b(dm_void); - - if (dm->support_ic_type & ODM_RTL8198F) - phydm_get_pa_bias_offset_8198f(dm); } s8 phydm_get_thermal_offset(void *dm_void) @@ -2547,6 +3776,17 @@ s8 phydm_get_thermal_offset(void *dm_void) return 0; } +s8 phydm_get_multi_thermal_offset(void *dm_void, u8 path) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) + return power_trim_info->multi_thermal[path]; + else + return 0; +} + void phydm_do_kfree(void *dm_void, u8 channel_to_sw) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -2707,3 +3947,12 @@ void phydm_config_kfree(void *dm_void, u8 channel_to_sw) } RF_DBG(dm, DBG_RF_MP, "<===[kfree] phy_ConfigKFree()\n"); } + +void phydm_set_lna_trim_offset (void *dm_void, u8 path, u8 cg_cs, u8 enable) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + if (dm->support_ic_type & ODM_RTL8197G) + phydm_set_lna_trim_offset_8197g(dm, path, cg_cs, enable); +} + diff --git a/hal/phydm/halrf/halrf_kfree.h b/hal/phydm/halrf/halrf_kfree.h index bea4b07..2de6b6b 100644 --- a/hal/phydm/halrf/halrf_kfree.h +++ b/hal/phydm/halrf/halrf_kfree.h @@ -164,10 +164,15 @@ #define PPG_5GH1_TXA_8721D 0x1E9 /*8197G*/ -#define PPG_THERMAL_OFFSET_97G 0x50 +#define PPG_THERMAL_A_OFFSET_97G 0x50 +#define PPG_THERMAL_B_OFFSET_97G 0x27 #define PPG_2GM_TXAB_97G 0x51 #define PPG_2GL_TXAB_97G 0x53 #define PPG_2GH_TXAB_97G 0x55 +#define TSSI_2GL_TXA_97G 0x1c +#define TSSI_2GL_TXB_97G 0x1d +#define TSSI_2GH_TXA_97G 0x1e +#define TSSI_2GH_TXB_97G 0x1f #define PPG_PABIAS_2GAB_97G 0x57 #define PPG_LNA_2GA_97G 0x21 #define PPG_LNA_2GB_97G 0x22 @@ -180,13 +185,83 @@ #define PPG_PABIAS_10C 0x1D6 #define PPG_LNA_10C 0x1D0 +/*8814B*/ +#define PPG_2GL_TXAB_14B 0x3ee +#define PPG_2GL_TXCD_14B 0x3ed +#define PPG_5GL1_TXA_14B 0x3ec +#define PPG_5GL1_TXB_14B 0x3eb +#define PPG_5GL1_TXC_14B 0x3ea +#define PPG_5GL1_TXD_14B 0x3e9 +#define PPG_5GL2_TXA_14B 0x3e8 +#define PPG_5GL2_TXB_14B 0x3e7 +#define PPG_5GL2_TXC_14B 0x3e6 +#define PPG_5GL2_TXD_14B 0x3e5 +#define PPG_5GM1_TXA_14B 0x3e4 +#define PPG_5GM1_TXB_14B 0x3e3 +#define PPG_5GM1_TXC_14B 0x3e2 +#define PPG_5GM1_TXD_14B 0x3e1 +#define PPG_5GM2_TXA_14B 0x3e0 +#define PPG_5GM2_TXB_14B 0x3df +#define PPG_5GM2_TXC_14B 0x3de +#define PPG_5GM2_TXD_14B 0x3dd +#define PPG_5GH1_TXA_14B 0x3dc +#define PPG_5GH1_TXB_14B 0x3db +#define PPG_5GH1_TXC_14B 0x3da +#define PPG_5GH1_TXD_14B 0x3d9 +#define PPG_PABIAS_5GAC_14B 0x3d8 +#define PPG_PABIAS_5GBD_14B 0x3d7 +#define PPG_PABIAS_2GAC_14B 0x3d6 +#define PPG_PABIAS_2GBD_14B 0x3d5 + +#define PPG_THERMAL_A_OFFSET_14B 0x3D4 +#define PPG_THERMAL_B_OFFSET_14B 0x3D3 +#define PPG_THERMAL_C_OFFSET_14B 0x3D2 +#define PPG_THERMAL_D_OFFSET_14B 0x3D1 + +#define TSSI_2GM_TXA_14B 0x3c0 +#define TSSI_2GM_TXB_14B 0x3bf +#define TSSI_2GM_TXC_14B 0x3be +#define TSSI_2GM_TXD_14B 0x3bd +#define TSSI_2GH_TXA_14B 0x3bc +#define TSSI_2GH_TXB_14B 0x3bb +#define TSSI_2GH_TXC_14B 0x3ba +#define TSSI_2GH_TXD_14B 0x3b9 +#define TSSI_5GL1_TXA_14B 0x3b8 +#define TSSI_5GL1_TXB_14B 0x3b7 +#define TSSI_5GL1_TXC_14B 0x3b6 +#define TSSI_5GL1_TXD_14B 0x3b5 +#define TSSI_5GL2_TXA_14B 0x3b4 +#define TSSI_5GL2_TXB_14B 0x3b3 +#define TSSI_5GL2_TXC_14B 0x3b2 +#define TSSI_5GL2_TXD_14B 0x3b1 +#define TSSI_5GM1_TXA_14B 0x3b0 +#define TSSI_5GM1_TXB_14B 0x3af +#define TSSI_5GM1_TXC_14B 0x3ae +#define TSSI_5GM1_TXD_14B 0x3ad +#define TSSI_5GM2_TXA_14B 0x3ac +#define TSSI_5GM2_TXB_14B 0x3ab +#define TSSI_5GM2_TXC_14B 0x3aa +#define TSSI_5GM2_TXD_14B 0x3a9 +#define TSSI_5GH1_TXA_14B 0x3a8 +#define TSSI_5GH1_TXB_14B 0x3a7 +#define TSSI_5GH1_TXC_14B 0x3a6 +#define TSSI_5GH1_TXD_14B 0x3a5 +#define TSSI_5GH2_TXA_14B 0x3a4 +#define TSSI_5GH2_TXB_14B 0x3a3 +#define TSSI_5GH2_TXC_14B 0x3a2 +#define TSSI_5GH2_TXD_14B 0x3a1 + + struct odm_power_trim_data { u8 flag; u8 pa_bias_flag; u8 lna_flag; s8 bb_gain[KFREE_BAND_NUM][MAX_RF_PATH]; s8 tssi_trim[KFREE_BAND_NUM][MAX_RF_PATH]; + s8 pa_bias_trim[KFREE_BAND_NUM][MAX_RF_PATH]; + s8 lna_trim[MAX_RF_PATH]; s8 thermal; + s8 multi_thermal[MAX_RF_PATH]; }; enum phydm_kfree_channeltosw { @@ -206,6 +281,8 @@ void phydm_get_pa_bias_offset(void *dm_void); s8 phydm_get_thermal_offset(void *dm_void); +s8 phydm_get_multi_thermal_offset(void *dm_void, u8 path); + void phydm_clear_kfree_to_rf(void *dm_void, u8 e_rf_path, u8 data); void phydm_config_new_kfree(void *dm_void); @@ -214,4 +291,6 @@ s8 phydm_get_tssi_trim_de(void *dm_void, u8 path); void phydm_config_kfree(void *dm_void, u8 channel_to_sw); +void phydm_set_lna_trim_offset (void *dm_void, u8 path, u8 cg_cs, u8 enable); + #endif /*__HALRF_KFREE_H__*/ diff --git a/hal/phydm/halrf/halrf_powertracking.c b/hal/phydm/halrf/halrf_powertracking.c index 25c5625..648e085 100644 --- a/hal/phydm/halrf/halrf_powertracking.c +++ b/hal/phydm/halrf/halrf_powertracking.c @@ -162,16 +162,39 @@ void halrf_set_pwr_track(void *dm_void, u8 enable) configure_txpower_track(dm, &c); if (enable) { rf->rf_supportability = rf->rf_supportability | HAL_RF_TX_PWR_TRACK; +#if !(RTL8723F_SUPPORT == 1) if (cali_info->txpowertrack_control == 1 || cali_info->txpowertrack_control == 3) halrf_do_tssi(dm); +#else + halrf_tssi_get_efuse(dm); + halrf_do_tssi(dm); +#endif + } else { rf->rf_supportability = rf->rf_supportability & ~HAL_RF_TX_PWR_TRACK; odm_clear_txpowertracking_state(dm); halrf_do_tssi(dm); halrf_calculate_tssi_codeword(dm); halrf_set_tssi_codeword(dm); + +//#if !(RTL8723F_SUPPORT == 1) for (i = 0; i < c.rf_path_count; i++) (*c.odm_tx_pwr_track_set_pwr)(dm, CLEAN_MODE, i, 0); +//#endif } + +#if (RTL8723F_SUPPORT == 1) + if (dm->mp_mode) { + if (*dm->mp_mode) + /*Re-do dpk when tssi mode is changed*/ + halrf_dpk_trigger(dm); + } +#endif + + if (cali_info->txpowertrack_control == 2 || + cali_info->txpowertrack_control == 3 || + cali_info->txpowertrack_control == 4 || + cali_info->txpowertrack_control == 5) + halrf_txgapk_reload_tx_gain(dm); } diff --git a/hal/phydm/halrf/halrf_powertracking_ap.c b/hal/phydm/halrf/halrf_powertracking_ap.c index d9dda08..28a8091 100644 --- a/hal/phydm/halrf/halrf_powertracking_ap.c +++ b/hal/phydm/halrf/halrf_powertracking_ap.c @@ -927,7 +927,7 @@ odm_txpowertracking_init( { struct dm_struct *dm = (struct dm_struct *)dm_void; #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) - if (!(dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B | ODM_IC_11N_SERIES))) + if (!(dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8814B | ODM_IC_11N_SERIES))) return; #endif @@ -987,6 +987,24 @@ get_swing_index( return i; } +s8 +get_txagc_default_index( + void *dm_void +) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + s8 tmp; + +#if RTL8814B_SUPPORT + if (dm->support_ic_type == ODM_RTL8814B) { + tmp = (s8)(odm_get_bb_reg(dm, R_0x18a0, 0x7f) & 0xff); + if (tmp & BIT(6)) + tmp = tmp | 0x80; + return tmp; + } else + return 0; +#endif +} void odm_txpowertracking_thermal_meter_init( @@ -995,9 +1013,12 @@ odm_txpowertracking_thermal_meter_init( { struct dm_struct *dm = (struct dm_struct *)dm_void; struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info); + struct _hal_rf_ *rf = &dm->rf_table; + struct _halrf_tssi_data *tssi = &rf->halrf_tssi_data; struct rtl8192cd_priv *priv = dm->priv; u8 p; u8 default_swing_index; + u8 i; #if (RTL8197F_SUPPORT == 1 || RTL8822B_SUPPORT == 1 || RTL8192F_SUPPORT == 1) if ((GET_CHIP_VER(priv) == VERSION_8197F) || (GET_CHIP_VER(priv) == VERSION_8822B) ||(GET_CHIP_VER(priv) == VERSION_8192F)) default_swing_index = get_swing_index(dm); @@ -1073,7 +1094,7 @@ odm_txpowertracking_thermal_meter_init( #if (RTL8192F_SUPPORT == 1) if (GET_CHIP_VER(priv) == VERSION_8192F) { - cali_info->default_ofdm_index = 30; + cali_info->default_ofdm_index = (default_swing_index >= (OFDM_TABLE_SIZE_92D - 1)) ? 30 : default_swing_index; cali_info->default_cck_index = 28; } #endif @@ -1087,10 +1108,27 @@ odm_txpowertracking_thermal_meter_init( #if RTL8188E_SUPPORT - cali_info->default_cck_index = 20; /* -6 dB */ -#elif RTL8192E_SUPPORT - cali_info->default_cck_index = 8; /* -12 dB */ + if (GET_CHIP_VER(priv) == VERSION_8188E) { + cali_info->default_cck_index = 20; /* -6 dB */ + } #endif + +#if RTL8192E_SUPPORT + if (GET_CHIP_VER(priv) == VERSION_8192E) { + cali_info->default_cck_index = 8; /* -12 dB */ + } +#endif + +#if RTL8814B_SUPPORT + if (GET_CHIP_VER(priv) == VERSION_8814B) { + cali_info->default_txagc_index = get_txagc_default_index(dm); + + for (i = 0; i < MAX_PATH_NUM_8814B; i++) + tssi->tssi_trk_txagc_offset[i] = + cali_info->default_txagc_index; + } +#endif + cali_info->bb_swing_idx_ofdm_base = cali_info->default_ofdm_index; cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index; dm->rf_calibrate_info.CCK_index = cali_info->default_cck_index; @@ -1207,7 +1245,7 @@ odm_txpowertracking_check_ap( struct _hal_rf_ *rf = &dm->rf_table; struct _halrf_tssi_data *tssi = &rf->halrf_tssi_data; -#if ((RTL8188E_SUPPORT == 1) || (RTL8192E_SUPPORT == 1) || (RTL8812A_SUPPORT == 1) || (RTL8881A_SUPPORT == 1) || (RTL8814A_SUPPORT == 1) || (RTL8197F_SUPPORT == 1) || (RTL8192F_SUPPORT == 1) || (RTL8198F_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8812F_SUPPORT == 1)) +#if ((RTL8188E_SUPPORT == 1) || (RTL8192E_SUPPORT == 1) || (RTL8812A_SUPPORT == 1) || (RTL8881A_SUPPORT == 1) || (RTL8814A_SUPPORT == 1) || (RTL8197F_SUPPORT == 1) || (RTL8192F_SUPPORT == 1) || (RTL8198F_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8812F_SUPPORT == 1) || (RTL8197G_SUPPORT == 1)) if (!dm->rf_calibrate_info.tm_trigger) { if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8812 | ODM_RTL8881A | ODM_RTL8814A | ODM_RTL8197F | ODM_RTL8822B | ODM_RTL8821C | ODM_RTL8192F | ODM_RTL8198F)) { odm_set_rf_reg(dm, RF_PATH_A, 0x42, (BIT(17) | BIT(16)), 0x3); @@ -1224,6 +1262,14 @@ odm_txpowertracking_check_ap( odm_set_rf_reg(dm, RF_PATH_B, 0x42, BIT(17), 0x1); odm_set_rf_reg(dm, RF_PATH_C, 0x42, BIT(17), 0x1); odm_set_rf_reg(dm, RF_PATH_D, 0x42, BIT(17), 0x1); + } else if (dm->support_ic_type & ODM_RTL8197G) { + odm_set_rf_reg(dm, RF_PATH_A, RF_0x42, BIT(17), 0x1); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x42, BIT(17), 0x0); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x42, BIT(17), 0x1); + + odm_set_rf_reg(dm, RF_PATH_B, RF_0x42, BIT(17), 0x1); + odm_set_rf_reg(dm, RF_PATH_B, RF_0x42, BIT(17), 0x0); + odm_set_rf_reg(dm, RF_PATH_B, RF_0x42, BIT(17), 0x1); } if (dm->support_ic_type & ODM_RTL8814B) { diff --git a/hal/phydm/halrf/halrf_powertracking_ap.h b/hal/phydm/halrf/halrf_powertracking_ap.h index dfeb323..098e284 100644 --- a/hal/phydm/halrf/halrf_powertracking_ap.h +++ b/hal/phydm/halrf/halrf_powertracking_ap.h @@ -228,6 +228,7 @@ struct dm_rf_calibration_struct { u8 bb_swing_idx_cck_base; u8 default_ofdm_index; u8 default_cck_index; + s8 default_txagc_index; boolean bb_swing_flag_cck; s8 absolute_ofdm_swing_idx[MAX_RF_PATH]; diff --git a/hal/phydm/halrf/halrf_powertracking_ce.c b/hal/phydm/halrf/halrf_powertracking_ce.c index 1ae098b..4fd3de0 100644 --- a/hal/phydm/halrf/halrf_powertracking_ce.c +++ b/hal/phydm/halrf/halrf_powertracking_ce.c @@ -664,6 +664,23 @@ u8 get_cck_swing_index(void *dm_void) return i; } +s8 +get_txagc_default_index( + void *dm_void +) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + s8 tmp; + + if (dm->support_ic_type == ODM_RTL8814B) { + tmp = (s8)(odm_get_bb_reg(dm, R_0x18a0, 0x7f) & 0xff); + if (tmp & BIT(6)) + tmp = tmp | 0x80; + return tmp; + } else + return 0; +} + void odm_txpowertracking_thermal_meter_init(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -696,8 +713,9 @@ void odm_txpowertracking_thermal_meter_init(void *dm_void) cali_info->thermal_value_iqk = rf->eeprom_thermal; cali_info->thermal_value_lck = rf->eeprom_thermal; -#if (RTL8822C_SUPPORT == 1 || RTL8814B_SUPPORT == 1) - if (dm->support_ic_type == ODM_RTL8822C) { +#if (RTL8822C_SUPPORT == 1 || RTL8814B_SUPPORT == 1 || RTL8723F_SUPPORT == 1) + if (dm->support_ic_type == ODM_RTL8822C || + dm->support_ic_type == ODM_RTL8723F) { cali_info->thermal_value_path[RF_PATH_A] = tssi->thermal[RF_PATH_A]; cali_info->thermal_value_path[RF_PATH_B] = tssi->thermal[RF_PATH_B]; cali_info->thermal_value_iqk = tssi->thermal[RF_PATH_A]; @@ -748,6 +766,8 @@ void odm_txpowertracking_thermal_meter_init(void *dm_void) else cali_info->default_ofdm_index = swing_idx; + cali_info->default_txagc_index = get_txagc_default_index(dm); + cali_info->default_cck_index = 24; } cali_info->default_bb_swing_index_flag = true; @@ -805,6 +825,12 @@ void odm_txpowertracking_check_ce(void *dm_void) #if (DM_ODM_SUPPORT_TYPE == ODM_CE) if (!(rf->rf_supportability & HAL_RF_TX_PWR_TRACK)) return; +#if (RTL8723F_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8723F) { + /*RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "[RF][TSSI] Pwrtrack return!\n");*/ + return; + } +#endif if ((rf->power_track_type & 0xf0) >> 4 != 0) { if (dm->support_ic_type & ODM_RTL8822C) { @@ -868,10 +894,17 @@ odm_txpowertracking_direct_ce(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct _hal_rf_ *rf = &dm->rf_table; + #if (DM_ODM_SUPPORT_TYPE == ODM_CE) if (!(rf->rf_supportability & HAL_RF_TX_PWR_TRACK)) return; + if (dm->support_ic_type & ODM_RTL8723F) { +#if (RTL8723F_SUPPORT == 1) + /*RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "[RF]===>%s 8723F TSSI, return!\n", __func__);*/ + return; +#endif + } if (dm->support_ic_type & ODM_RTL8822C) { /*halrf_tssi_cck(dm);*/ diff --git a/hal/phydm/halrf/halrf_powertracking_ce.h b/hal/phydm/halrf/halrf_powertracking_ce.h index 2f3067a..3fec1ab 100644 --- a/hal/phydm/halrf/halrf_powertracking_ce.h +++ b/hal/phydm/halrf/halrf_powertracking_ce.h @@ -199,6 +199,7 @@ struct dm_rf_calibration_struct { u8 bb_swing_idx_cck_base; u8 default_ofdm_index; u8 default_cck_index; + s8 default_txagc_index; boolean bb_swing_flag_cck; s8 absolute_ofdm_swing_idx[MAX_RF_PATH]; diff --git a/hal/phydm/halrf/halrf_powertracking_iot.c b/hal/phydm/halrf/halrf_powertracking_iot.c index dd6e02b..494fdec 100644 --- a/hal/phydm/halrf/halrf_powertracking_iot.c +++ b/hal/phydm/halrf/halrf_powertracking_iot.c @@ -34,7 +34,7 @@ * ************************************************************ */ -u32 ofdm_swing_table[OFDM_TABLE_SIZE] = { +const u32 ofdm_swing_table[OFDM_TABLE_SIZE] = { 0x7f8001fe, /* 0, +6.0dB */ 0x788001e2, /* 1, +5.5dB */ 0x71c001c7, /* 2, +5.0dB*/ @@ -74,7 +74,7 @@ u32 ofdm_swing_table[OFDM_TABLE_SIZE] = { 0x10000040, /* 36, -12.0dB*/ }; -u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8] = { +const u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8] = { {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */ {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */ {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB*/ @@ -110,7 +110,7 @@ u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8] = { {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB*/ }; -u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8] = { +const u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8] = { {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */ {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */ {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */ @@ -146,7 +146,7 @@ u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8] = { {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB*/ }; -u32 ofdm_swing_table_new[OFDM_TABLE_SIZE] = { +const u32 ofdm_swing_table_new[OFDM_TABLE_SIZE] = { 0x0b40002d, /* 0, -15.0dB */ 0x0c000030, /* 1, -14.5dB*/ 0x0cc00033, /* 2, -14.0dB*/ @@ -192,7 +192,7 @@ u32 ofdm_swing_table_new[OFDM_TABLE_SIZE] = { 0x7f8001fe /* 42, +6.0dB*/ }; -u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16] = { +const u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16] = { {0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ {0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ {0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ @@ -216,7 +216,7 @@ u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16] = { {0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/ }; -u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16] = { +const u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16] = { {0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ {0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ {0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ @@ -240,7 +240,7 @@ u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16] = { {0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/ }; -u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16] = { +const u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16] = { {0x44, 0x42, 0x3C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ {0x48, 0x46, 0x3F, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ {0x4D, 0x4A, 0x43, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ @@ -264,7 +264,7 @@ u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16] = { {0xD8, 0xD1, 0xBD, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/ }; -u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8] = { +const u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8] = { {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}, /* 0, -16.0dB*/ {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 1, -15.5dB*/ {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 2, -15.0dB*/ @@ -300,7 +300,7 @@ u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8] = { {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04} /* 32, +0dB*/ }; -u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8] = { +const u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8] = { {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}, /* 0, -16.0dB*/ {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 1, -15.5dB*/ {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 2, -15.0dB*/ @@ -336,7 +336,7 @@ u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8] = { {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00} /* 32, +0dB */ }; -u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D] = { +const u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D] = { 0x0CD, /*0 , -20dB*/ 0x0D9, 0x0E6, @@ -381,7 +381,7 @@ u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D] = { }; /* JJ ADD 20161014 */ -u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B] = { +const u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B] = { 0x0CD, /*0 , -20dB*/ 0x0D9, 0x0E6, @@ -426,7 +426,7 @@ u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B] = { }; /* Winnita ADD 20171116 PathA 0xAB4[10:0],PathB 0xAB4[21:11]*/ -u32 cck_swing_table_ch1_ch14_8192f[CCK_TABLE_SIZE_8192F] = { +const u32 cck_swing_table_ch1_ch14_8192f[CCK_TABLE_SIZE_8192F] = { 0x0CD, /*0 , -20dB*/ 0x0D9, 0x0E6, @@ -471,7 +471,7 @@ u32 cck_swing_table_ch1_ch14_8192f[CCK_TABLE_SIZE_8192F] = { }; /* Winnita ADD 201805 PathA 0xAB4[10:0]*/ -u32 cck_swing_table_ch1_ch14_8721d[CCK_TABLE_SIZE_8721D] = { +const u32 cck_swing_table_ch1_ch14_8721d[CCK_TABLE_SIZE_8721D] = { 0x0CD, /*0 , -20dB*/ 0x0D9, 0x0E6, @@ -515,7 +515,7 @@ u32 cck_swing_table_ch1_ch14_8721d[CCK_TABLE_SIZE_8721D] = { 0x7FF, }; -u32 cck_swing_table_ch1_ch14_8710c[CCK_TABLE_SIZE_8710C] = { +const u32 cck_swing_table_ch1_ch14_8710c[CCK_TABLE_SIZE_8710C] = { 0x0CD, /*0 , -20dB*/ 0x0D9, 0x0E6, @@ -559,7 +559,7 @@ u32 cck_swing_table_ch1_ch14_8710c[CCK_TABLE_SIZE_8710C] = { 0x7FF, }; -u32 cck_swing_table_03db_ch1_ch14_8710c[CCK_03DB_TABLE_SIZE_8710C] = { +const u32 cck_swing_table_03db_ch1_ch14_8710c[CCK_03DB_TABLE_SIZE_8710C] = { 0x143, /*0 , -4dB*/ 0x14C, /*1 , -3.75dB*/ 0x156, /*2 , -3.5dB*/ @@ -643,7 +643,7 @@ u32 cck_swing_table_03db_ch1_ch14_8710c[CCK_03DB_TABLE_SIZE_8710C] = { 0xCA3 /*80 , +16dB*/ }; -u32 ofdm_swing_table_03DB_8710c[OFDM_03DB_TABLE_SIZE_8710C] = { +const u32 ofdm_swing_table_03DB_8710c[OFDM_03DB_TABLE_SIZE_8710C] = { 0xE4, /*0 , -7dB*/ 0xEB, /*1 , -6.75dB*/ 0xF2, /*2 , -6.5dB*/ @@ -729,7 +729,7 @@ u32 ofdm_swing_table_03DB_8710c[OFDM_03DB_TABLE_SIZE_8710C] = { -u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE] = { +const u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE] = { 0x081, /* 0, -12.0dB*/ 0x088, /* 1, -11.5dB*/ 0x090, /* 2, -11.0dB*/ @@ -792,6 +792,7 @@ get_swing_index( u32 *swing_table; u32 table_value; +#if (RTL8710C_SUPPORT == 1) if (dm->support_ic_type == ODM_RTL8710C) { bb_swing = odm_get_bb_reg(dm, R_0xcc8, 0x000007ff); @@ -800,10 +801,10 @@ get_swing_index( break; } } - +#elif (RTL8195B_SUPPORT == 1) if (dm->support_ic_type == ODM_RTL8195B) { bb_swing = odm_get_bb_reg(dm, R_0xc1c, 0xFFE00000); - swing_table = tx_scaling_table_jaguar; + swing_table = (u32*)tx_scaling_table_jaguar; swing_table_size = TXSCALE_TABLE_SIZE; for (i = 0; i < swing_table_size; i++) { @@ -814,7 +815,7 @@ get_swing_index( break; } } - +#endif return i; } @@ -828,6 +829,7 @@ get_cck_swing_index( u8 i = 0; u32 bb_cck_swing; +#if (RTL8188E_SUPPORT == 1 || RTL8723B_SUPPORT == 1 || RTL8192E_SUPPORT == 1) if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8723B || dm->support_ic_type == ODM_RTL8192E) { bb_cck_swing = odm_read_1byte(dm, 0xa22); @@ -836,14 +838,18 @@ get_cck_swing_index( if (bb_cck_swing == cck_swing_table_ch1_ch13_new[i][0]) break; } - } else if (dm->support_ic_type == ODM_RTL8703B) { + } +#elif (RTL8703B_SUPPORT == 1) + if (dm->support_ic_type == ODM_RTL8703B) { bb_cck_swing = odm_read_1byte(dm, 0xa22); for (i = 0; i < CCK_TABLE_SIZE_88F; i++) { if (bb_cck_swing == cck_swing_table_ch1_ch14_88f[i][0]) break; } - } else if (dm->support_ic_type == ODM_RTL8710C) { + } +#elif (RTL8710C_SUPPORT == 1) + if (dm->support_ic_type == ODM_RTL8710C) { bb_cck_swing = odm_get_bb_reg(dm, R_0xab4, 0x7ff); RF_DBG(dm, DBG_RF_TX_PWR_TRACK, @@ -854,10 +860,28 @@ get_cck_swing_index( break; } } +#endif return i; } +s8 +get_txagc_default_index( + void *dm_void +) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + s8 tmp; + + if (dm->support_ic_type == ODM_RTL8814B) { + tmp = (s8)(odm_get_bb_reg(dm, R_0x18a0, 0x7f) & 0xff); + if (tmp & BIT(6)) + tmp = tmp | 0x80; + return tmp; + } else + return 0; +} + void odm_txpowertracking_thermal_meter_init( void *dm_void diff --git a/hal/phydm/halrf/halrf_powertracking_iot.h b/hal/phydm/halrf/halrf_powertracking_iot.h index 81ddde2..431890b 100644 --- a/hal/phydm/halrf/halrf_powertracking_iot.h +++ b/hal/phydm/halrf/halrf_powertracking_iot.h @@ -62,26 +62,26 @@ #define IQK_MATRIX_SETTINGS_NUM (14+24+21) /* Channels_2_4G_NUM + Channels_5G_20M_NUM + Channels_5G */ #endif -extern u32 ofdm_swing_table[OFDM_TABLE_SIZE]; -extern u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8]; -extern u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8]; +extern const u32 ofdm_swing_table[OFDM_TABLE_SIZE]; +extern const u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8]; +extern const u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8]; -extern u32 ofdm_swing_table_new[OFDM_TABLE_SIZE]; -extern u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8]; -extern u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8]; -extern u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16]; -extern u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16]; -extern u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16]; -extern u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D]; +extern const u32 ofdm_swing_table_new[OFDM_TABLE_SIZE]; +extern const u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8]; +extern const u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8]; +extern const u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16]; +extern const u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16]; +extern const u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16]; +extern const u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D]; /* JJ ADD 20161014 */ -extern u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B]; -extern u32 cck_swing_table_ch1_ch14_8192f[CCK_TABLE_SIZE_8192F]; -extern u32 cck_swing_table_ch1_ch14_8721d[CCK_TABLE_SIZE_8721D]; -extern u32 cck_swing_table_ch1_ch14_8710c[CCK_TABLE_SIZE_8710C]; -extern u32 cck_swing_table_03db_ch1_ch14_8710c[CCK_03DB_TABLE_SIZE_8710C]; -extern u32 ofdm_swing_table_03DB_8710c[OFDM_03DB_TABLE_SIZE_8710C]; +extern const u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B]; +extern const u32 cck_swing_table_ch1_ch14_8192f[CCK_TABLE_SIZE_8192F]; +extern const u32 cck_swing_table_ch1_ch14_8721d[CCK_TABLE_SIZE_8721D]; +extern const u32 cck_swing_table_ch1_ch14_8710c[CCK_TABLE_SIZE_8710C]; +extern const u32 cck_swing_table_03db_ch1_ch14_8710c[CCK_03DB_TABLE_SIZE_8710C]; +extern const u32 ofdm_swing_table_03DB_8710c[OFDM_03DB_TABLE_SIZE_8710C]; -extern u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE]; +extern const u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE]; /* <20121018, Kordan> In case fail to read TxPowerTrack.txt, we use the table of 88E as the default table. */ #if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211) @@ -221,6 +221,7 @@ struct dm_rf_calibration_struct { u8 bb_swing_idx_cck_base; u8 default_ofdm_index; u8 default_cck_index; + s8 default_txagc_index; boolean bb_swing_flag_cck; s8 absolute_ofdm_swing_idx[MAX_RF_PATH]; diff --git a/hal/phydm/halrf/halrf_powertracking_win.c b/hal/phydm/halrf/halrf_powertracking_win.c index c22e9d8..d53c3a8 100644 --- a/hal/phydm/halrf/halrf_powertracking_win.c +++ b/hal/phydm/halrf/halrf_powertracking_win.c @@ -532,8 +532,7 @@ get_swing_index( if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8723B || dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type == ODM_RTL8188F || dm->support_ic_type == ODM_RTL8703B || dm->support_ic_type == ODM_RTL8723D || - dm->support_ic_type == ODM_RTL8192F || dm->support_ic_type == ODM_RTL8710B || - dm->support_ic_type == ODM_RTL8821) { + dm->support_ic_type == ODM_RTL8192F || dm->support_ic_type == ODM_RTL8710B) { bb_swing = odm_get_bb_reg(dm, REG_OFDM_0_XA_TX_IQ_IMBALANCE, 0xFFC00000); for (i = 0; i < OFDM_TABLE_SIZE; i++) { @@ -588,6 +587,22 @@ get_cck_swing_index( return i; } +s8 +get_txagc_default_index( + void *dm_void +) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + s8 tmp; + + if (dm->support_ic_type == ODM_RTL8814B) { + tmp = (s8)(odm_get_bb_reg(dm, R_0x18a0, 0x7f) & 0xff); + if (tmp & BIT(6)) + tmp = tmp | 0x80; + return tmp; + } else + return 0; +} void odm_txpowertracking_thermal_meter_init( @@ -662,8 +677,9 @@ odm_txpowertracking_thermal_meter_init( cali_info->thermal_value_iqk = hal_data->eeprom_thermal_meter; cali_info->thermal_value_lck = hal_data->eeprom_thermal_meter; -#if (RTL8822C_SUPPORT == 1 || RTL8814B_SUPPORT == 1) - if (dm->support_ic_type == ODM_RTL8822C) { +#if (RTL8822C_SUPPORT == 1 || RTL8814B_SUPPORT == 1 || RTL8723F_SUPPORT == 1) + if (dm->support_ic_type == ODM_RTL8822C || + dm->support_ic_type == ODM_RTL8723F) { cali_info->thermal_value_path[RF_PATH_A] = tssi->thermal[RF_PATH_A]; cali_info->thermal_value_path[RF_PATH_B] = tssi->thermal[RF_PATH_B]; cali_info->thermal_value_iqk = tssi->thermal[RF_PATH_A]; @@ -683,8 +699,7 @@ odm_txpowertracking_thermal_meter_init( if (cali_info->default_bb_swing_index_flag != true) { /*The index of "0 dB" in SwingTable.*/ if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8723B || - dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type == ODM_RTL8703B || - dm->support_ic_type == ODM_RTL8821) { + dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type == ODM_RTL8703B) { cali_info->default_ofdm_index = (default_swing_index >= OFDM_TABLE_SIZE) ? 30 : default_swing_index; cali_info->default_cck_index = (default_cck_swing_index >= CCK_TABLE_SIZE) ? 20 : default_cck_swing_index; } else if (dm->support_ic_type == ODM_RTL8188F) { /*add by Mingzhi.Guo 2015-03-23*/ @@ -704,6 +719,7 @@ odm_txpowertracking_thermal_meter_init( } else { cali_info->default_ofdm_index = (default_swing_index >= TXSCALE_TABLE_SIZE) ? 24 : default_swing_index; cali_info->default_cck_index = 24; + cali_info->default_txagc_index = get_txagc_default_index(dm); } cali_info->default_bb_swing_index_flag = true; } @@ -838,6 +854,12 @@ odm_txpowertracking_direct_call( HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter)); struct dm_struct *dm = &hal_data->DM_OutSrc; + if (dm->support_ic_type & ODM_RTL8723F) { +#if (RTL8723F_SUPPORT == 1) + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "[RF]===>%s 8723F TSSI, return!\n", __func__); + return; +#endif + } if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B)) { #if (RTL8822C_SUPPORT == 1 || RTL8814B_SUPPORT == 1) odm_txpowertracking_new_callback_thermal_meter(dm); @@ -882,7 +904,12 @@ odm_txpowertracking_thermal_meter_check( odm_set_rf_reg(dm, RF_PATH_B, 0x42, BIT(17), 0x1); odm_set_rf_reg(dm, RF_PATH_C, 0x42, BIT(17), 0x1); odm_set_rf_reg(dm, RF_PATH_D, 0x42, BIT(17), 0x1); - } else + } else if (IS_HARDWARE_TYPE_8723F(adapter)) { + odm_set_rf_reg(dm, RF_PATH_A, R_0x42, BIT(16), 0x01); + odm_set_rf_reg(dm, RF_PATH_A, R_0x42, BIT(16), 0x00); + odm_set_rf_reg(dm, RF_PATH_A, R_0x42, BIT(16), 0x01); + } + else PHY_SetRFReg(adapter, RF_PATH_A, RF_T_METER, RFREGOFFSETMASK, 0x60); if (dm->support_ic_type & ODM_RTL8814B) { diff --git a/hal/phydm/halrf/halrf_powertracking_win.h b/hal/phydm/halrf/halrf_powertracking_win.h index 2402548..f84d440 100644 --- a/hal/phydm/halrf/halrf_powertracking_win.h +++ b/hal/phydm/halrf/halrf_powertracking_win.h @@ -216,6 +216,7 @@ struct dm_rf_calibration_struct { u8 bb_swing_idx_cck_base; u8 default_ofdm_index; u8 default_cck_index; + s8 default_txagc_index; boolean bb_swing_flag_cck; s8 absolute_ofdm_swing_idx[MAX_RF_PATH]; diff --git a/hal/phydm/halrf/halrf_psd.c b/hal/phydm/halrf/halrf_psd.c index bab7d09..445c910 100644 --- a/hal/phydm/halrf/halrf_psd.c +++ b/hal/phydm/halrf/halrf_psd.c @@ -260,19 +260,93 @@ void _halrf_psd_iqk_init(struct dm_struct *dm) odm_set_bb_reg(dm, 0x1bcc, 0x3f, 0x3f); } - -u32 halrf_get_iqk_psd_data( - struct dm_struct *dm, - u32 point) +void _halrf_iqk_psd_init_8723f(void *dm_void, boolean onoff) { + struct dm_struct *dm = (struct dm_struct *)dm_void; + u8 s; + + s = (u8)odm_get_bb_reg(dm, 0x1884, BIT(20)); + + if (onoff) { + /*01_8723F_AFE_ON_BB_settings.txt*/ + odm_set_bb_reg(dm, 0x1c38, MASKDWORD, 0x0); + odm_set_bb_reg(dm, R_0x1830, BIT(30), 0x0); + odm_set_bb_reg(dm, R_0x1860, 0xF0000000, 0xf); + odm_set_bb_reg(dm, R_0x1860, 0x0FFFF000, 0x0041); + odm_set_bb_reg(dm, 0x09f0, 0x0000FFFF, 0xbbbb); + odm_set_bb_reg(dm, 0x1d40, BIT(3), 0x1); + odm_set_bb_reg(dm, 0x1d40, 0x00000007, 0x3); + odm_set_bb_reg(dm, 0x09b4, 0x00000700, 0x3); + odm_set_bb_reg(dm, 0x09b4, 0x00003800, 0x3); + odm_set_bb_reg(dm, 0x09b4, 0x0001C000, 0x3); + odm_set_bb_reg(dm, 0x09b4, 0x000E0000, 0x3); + odm_set_bb_reg(dm, R_0x1c20, BIT(5), 0x1); + odm_set_bb_reg(dm, R_0x1e24, BIT(31), 0x0); + odm_set_bb_reg(dm, R_0x1e28, 0x0000000F, 0x1); + odm_set_bb_reg(dm, R_0x824, 0x000F0000, 0x1); + odm_set_bb_reg(dm, R_0x1cd0, 0xF0000000, 0x7); + odm_set_bb_reg(dm, R_0x2a24, BIT(13), 0x1); + odm_set_bb_reg(dm, R_0x1c68, BIT(24), 0x1); + odm_set_bb_reg(dm, R_0x1864, BIT(31), 0x1); + odm_set_bb_reg(dm, R_0x180c, BIT(27), 0x1); + odm_set_bb_reg(dm, R_0x180c, BIT(30), 0x1); + odm_set_bb_reg(dm, R_0x1e24, BIT(17), 0x1); + odm_set_bb_reg(dm, R_0x1880, BIT(21), 0x0); + odm_set_bb_reg(dm, R_0x1c38, MASKDWORD, 0xffffffff); + /*02_IQK_Preset.txt*/ + //odm_set_rf_reg(dm, RF_PATH_A, 0x05, BIT(0), 0x0); + //odm_set_rf_reg(dm, RF_PATH_B, 0x05, BIT(0), 0x0); + odm_set_bb_reg(dm, R_0x1b08, MASKDWORD, 0x00000080); + //odm_set_bb_reg(dm, R_0x1bd8, MASKDWORD, 0x00000002); + //switch path 10 od 0x1b38 0x1/0x3 [1:0] + if (s == 0) + odm_set_bb_reg(dm, R_0x1b00, MASKDWORD, 0x00000008); + else + odm_set_bb_reg(dm, R_0x1b00, MASKDWORD, 0x0000000a); + + odm_set_bb_reg(dm, R_0x1b18, MASKDWORD, 0x40010101); + odm_set_bb_reg(dm, R_0x1b14, MASKDWORD, 0x40010100); + //odm_set_bb_reg(dm, R_0x1b1c, MASKDWORD, 0xA2103C00); + odm_set_bb_reg(dm, R_0x1b0c, 0x00000C00, 0x2); + odm_set_bb_reg(dm, R_0x1bcc, 0x0000003F, 0x3f); + //DbgPrint("[PSD][8723F]iqkpsd init!\n"); + } else { + /*10_IQK_Reg_PSD_Restore.txt*/ + //odm_set_bb_reg(dm, R_0x1b1c, MASKDWORD, 0xA2103C00); + odm_set_bb_reg(dm, R_0x1b08, MASKDWORD, 0x00000000); + odm_set_bb_reg(dm, R_0x1b38, BIT(0), 0x0); + odm_set_bb_reg(dm, R_0x1bcc, 0x0000003F, 0x0); + //odm_set_rf_reg(dm, RF_PATH_A, 0x05, BIT(0), 0x1); + //odm_set_rf_reg(dm, RF_PATH_B, 0x05, BIT(0), 0x1); + /*11_8723F_restore_AFE_BB_settings.txt*/ + odm_set_bb_reg(dm, 0x1c38, MASKDWORD, 0x0); + odm_set_bb_reg(dm, R_0x1830, BIT(30), 0x1); + odm_set_bb_reg(dm, R_0x1e24, BIT(31), 0x1); + odm_set_bb_reg(dm, R_0x2a24, BIT(13), 0x0); + odm_set_bb_reg(dm, R_0x1c68, BIT(24), 0x0); + odm_set_bb_reg(dm, R_0x1864, BIT(31), 0x0); + odm_set_bb_reg(dm, R_0x180c, BIT(27), 0x0); + odm_set_bb_reg(dm, R_0x180c, BIT(30), 0x0); + odm_set_bb_reg(dm, R_0x1880, BIT(21), 0x0); + odm_set_bb_reg(dm, R_0x1c38, MASKDWORD, 0xffa1005e); + //DbgPrint("[PSD][8723F]iqkpsd resotre!\n"); + } +} + +u64 halrf_get_iqk_psd_data(void *dm_void, u32 point) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; struct _hal_rf_ *rf = &(dm->rf_table); struct _halrf_psd_data *psd = &(rf->halrf_psd_data); - u32 psd_val, psd_val1, psd_val2, psd_point, i, delay_time = 0; + u64 psd_val, psd_val1, psd_val2; + u32 psd_point, i, delay_time = 0; #if (DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE) if (dm->support_interface == ODM_ITRF_USB || dm->support_interface == ODM_ITRF_SDIO) { if (dm->support_ic_type & ODM_RTL8822C) delay_time = 1000; + else if (dm->support_ic_type & ODM_RTL8723F) + delay_time = 1000; else delay_time = 0; } @@ -320,6 +394,14 @@ u32 halrf_get_iqk_psd_data( psd_val2 = odm_get_bb_reg(dm, R_0x1bfc, MASKDWORD); psd_val = (psd_val1 << 27) + (psd_val2 >> 5); + } else if (dm->support_ic_type & ODM_RTL8723F) { + odm_set_bb_reg(dm, R_0x1bd4, MASKDWORD, 0x00210001); + psd_val1 = odm_get_bb_reg(dm, R_0x1bfc, MASKDWORD); + psd_val1 = (psd_val1 & 0x00FF0000) >> 16; + odm_set_bb_reg(dm, R_0x1bd4, MASKDWORD, 0x00220001); + psd_val2 = odm_get_bb_reg(dm, R_0x1bfc, MASKDWORD); + //psd_val = (psd_val1 << 27) + (psd_val2 >> 5); + psd_val = (psd_val1 << 32) + psd_val2; } else { odm_set_bb_reg(dm, R_0x1bd4, MASKDWORD, 0x00250001); @@ -357,8 +439,8 @@ void halrf_iqk_psd( mode = average >> 16; if (mode == 2) { - if (dm->support_ic_type & ODM_RTL8822C) - average_tmp = 1; + if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8723F)) + average_tmp = 1; //HW average else { reg_tmp = odm_get_bb_reg(dm, R_0x1b1c, 0x000e0000); if (reg_tmp == 0) @@ -381,18 +463,22 @@ void halrf_iqk_psd( average_tmp = 16; else if (reg_tmp == 5) average_tmp = 32; +#ifndef RTL8723F_SUPPORT odm_set_bb_reg(dm, R_0x1b1c, 0x000e0000, 0x0); +#endif } #if 0 DbgPrint("[PSD]point=%d, start_point=%d, stop_point=%d, average=0x%x, average_tmp=%d, buf_size=%d, mode=%d\n", - point, start_point, stop_point, average, average_tmp, psd->buf_size, mode); + point, start_point, stop_point, average, average_tmp, psd->buf_size, mode); #endif for (i = 0; i < psd->buf_size; i++) psd->psd_data[i] = 0; i = start_point; + +#ifndef RTL8723F_SUPPORT while (i < stop_point) { data_tatal = 0; @@ -431,13 +517,32 @@ void halrf_iqk_psd( if (dm->support_ic_type & (ODM_RTL8814B | ODM_RTL8198F | ODM_RTL8197G)) odm_set_bb_reg(dm, R_0x1b1c, 0x000e0000, reg_tmp); +#else + while (i < stop_point) { + data_tatal = 0; + if (i >= point) + point_temp = i - point; + else + point_temp = i + 0xB00; + //-640:0xD80,640:0x280,0x280+0xB00 =0xD80 + //point_temp = i + 0xC00; + //-512:0xE00,512:0x200,0x200+0xC00 = 0xE00 + + data_temp[k] = halrf_get_iqk_psd_data(dm, point_temp); + data_tatal = data_temp[k]; + psd->psd_data[j] = (u32)data_tatal; + i++; + j++; + } + +#endif #if 0 DbgPrint("\n [iqk psd]psd result:\n"); for (i = 0; i < psd->buf_size; i++) { if ((i % 20) == 0) - DbgPrint("\n "); + DbgPrint("\n "); DbgPrint("0x%x ", psd->psd_data[i]); } @@ -454,19 +559,30 @@ halrf_psd_init( struct dm_struct *dm = (struct dm_struct *)dm_void; struct _hal_rf_ *rf = &(dm->rf_table); struct _halrf_psd_data *psd = &(rf->halrf_psd_data); - +#ifndef RTL8723F_SUPPORT #if 0 u32 bb_backup[12]; u32 backup_bb_reg[12] = {0x1b04, 0x1b08, 0x1b0c, 0x1b14, 0x1b18, 0x1b1c, 0x1b28, 0x1bcc, 0x1b2c, 0x1b34, 0x1bd4, 0x1bfc}; #endif - +#else + u32 bb_backup[11]; + u32 backup_bb_reg[11] = {0x09f0, 0x09b4, 0x1c38, 0x1860, 0x1cd0, + 0x824, 0x2a24, 0x1d40, 0x1c20, 0x1880, 0x180c}; +#endif if (psd->psd_progress) { ret_status = RT_STATUS_PENDING; } else { psd->psd_progress = 1; - if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | ODM_RTL8198F | ODM_RTL8197G)) { + if (dm->support_ic_type & ODM_RTL8723F) { + backup_bb_register(dm, bb_backup, backup_bb_reg, 11); + _halrf_iqk_psd_init_8723f(dm, true); + halrf_iqk_psd(dm, psd->point, psd->start_point, psd->stop_point, psd->average); + _halrf_iqk_psd_init_8723f(dm, false); + restore_bb_register(dm, bb_backup, backup_bb_reg, 11); + } else if (dm->support_ic_type & + (ODM_RTL8822C | ODM_RTL8814B | ODM_RTL8198F | ODM_RTL8197G)) { /*backup_bb_register(dm, bb_backup, backup_bb_reg, 12);*/ _halrf_psd_iqk_init(dm); halrf_iqk_psd(dm, psd->point, psd->start_point, psd->stop_point, psd->average); diff --git a/hal/phydm/halrf/halrf_psd.h b/hal/phydm/halrf/halrf_psd.h index f4a7674..d714a56 100644 --- a/hal/phydm/halrf/halrf_psd.h +++ b/hal/phydm/halrf/halrf_psd.h @@ -31,6 +31,16 @@ u32 halrf_psd_init( void *dm_void); +void +_halrf_iqk_psd_init_8723f( + void *dm_void, + boolean onoff); + +u64 +halrf_get_iqk_psd_data( + void *dm_void, + u32 point); + u32 halrf_psd_query( void *dm_void, diff --git a/hal/phydm/halrf/rtl8822b/halhwimg8822b_rf.c b/hal/phydm/halrf/rtl8822b/halhwimg8822b_rf.c index 3949896..b7585ea 100644 --- a/hal/phydm/halrf/rtl8822b/halhwimg8822b_rf.c +++ b/hal/phydm/halrf/rtl8822b/halhwimg8822b_rf.c @@ -23,11 +23,9 @@ * *****************************************************************************/ -/*Image2HeaderVersion: R3 1.5.10*/ +/*Image2HeaderVersion: R3 1.5.8*/ #include "mp_precomp.h" -#define ODM_WIN 0x08 - #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) #if RT_PLATFORM == PLATFORM_MACOSX #include "phydm_precomp.h" diff --git a/hal/phydm/halrf/rtl8822b/halhwimg8822b_rf.h b/hal/phydm/halrf/rtl8822b/halhwimg8822b_rf.h index 3cd1406..3f4a31d 100644 --- a/hal/phydm/halrf/rtl8822b/halhwimg8822b_rf.h +++ b/hal/phydm/halrf/rtl8822b/halhwimg8822b_rf.h @@ -23,7 +23,7 @@ * *****************************************************************************/ -/*Image2HeaderVersion: R3 1.5.10*/ +/*Image2HeaderVersion: R3 1.5.8*/ #if (RTL8822B_SUPPORT == 1) #ifndef __INC_MP_RF_HW_IMG_8822B_H #define __INC_MP_RF_HW_IMG_8822B_H diff --git a/hal/phydm/halrf/rtl8822b/halrf_8822b.c b/hal/phydm/halrf/rtl8822b/halrf_8822b.c index 6fb16b2..2c9f14e 100644 --- a/hal/phydm/halrf/rtl8822b/halrf_8822b.c +++ b/hal/phydm/halrf/rtl8822b/halrf_8822b.c @@ -458,11 +458,13 @@ void _phy_lc_calibrate_8822b(struct dm_struct *dm) odm_set_rf_reg(dm, RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK, lc_cal | 0x08000); ODM_delay_ms(100); - for (cnt = 0; cnt < 100; cnt++) { + for (cnt = 0; cnt < 5; cnt++) { if (odm_get_rf_reg(dm, RF_PATH_A, RF_CHNLBW, 0x8000) != 0x1) break; ODM_delay_ms(10); } + if (cnt == 5) + RF_DBG(dm, DBG_RF_LCK, "LCK time out\n"); /*Recover channel number*/ odm_set_rf_reg(dm, RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK, lc_cal); /*enable RTK*/ diff --git a/hal/phydm/halrf/rtl8822b/halrf_iqk_8822b.c b/hal/phydm/halrf/rtl8822b/halrf_iqk_8822b.c index 91cea79..d73faf1 100644 --- a/hal/phydm/halrf/rtl8822b/halrf_iqk_8822b.c +++ b/hal/phydm/halrf/rtl8822b/halrf_iqk_8822b.c @@ -44,10 +44,10 @@ void phydm_get_read_counter_8822b(struct dm_struct *dm) while (1) { rf_reg = odm_get_rf_reg(dm, RF_PATH_A, RF_0x8, MASK20BITS); - if (rf_reg == 0xabcde || counter > 300) + if (rf_reg == 0xabcde || counter > 20000) break; counter++; - ODM_delay_ms(1); + ODM_delay_us(10); } odm_set_rf_reg(dm, RF_PATH_A, RF_0x8, MASK20BITS, 0x0); @@ -184,11 +184,8 @@ void _iqk_fill_iqk_report_8822b(void *dm_void, u8 ch) odm_write_4byte(dm, 0x1b00, 0xf8000008); odm_set_bb_reg(dm, R_0x1bf0, 0x0000ffff, tmp1 | tmp2 | tmp3); - for (i = 0; i < 2; i++) { - data = ((iqk->rxiqk_agc[ch][(i * 2) + 1] << 16) | - iqk->rxiqk_agc[ch][i * 2]); - odm_write_4byte(dm, 0x1be8 + (i * 4), data); - } + data = (iqk->rxiqk_agc[ch][1] << 16) | iqk->rxiqk_agc[ch][0]; + odm_write_4byte(dm, 0x1be8, data); } void _iqk_fail_count_8822b(void *dm_void) @@ -298,11 +295,11 @@ void _iqk_bb_reset_8822b(struct dm_struct *dm) odm_set_bb_reg(dm, R_0x198c, 0x7, 0x7); cca_ing = (boolean)odm_get_bb_reg(dm, R_0xfa0, BIT(3)); - if (count > 30) + if (count > 20000) cca_ing = false; if (cca_ing) { - ODM_delay_ms(1); + ODM_delay_us(10); count++; } else { /*RX ant off*/ @@ -404,7 +401,7 @@ void _iqk_backup_iqk_8822b_subfunction(struct dm_struct *dm) u8 i, j, k; iqk->iqk_channel[1] = iqk->iqk_channel[0]; - for (i = 0; i < 2; i++) { + for (i = 0; i < SS_8822B; i++) { iqk->lok_idac[1][i] = iqk->lok_idac[0][i]; iqk->rxiqk_agc[1][i] = iqk->rxiqk_agc[0][i]; iqk->bypass_iqk[1][i] = iqk->bypass_iqk[0][i]; @@ -431,7 +428,7 @@ void _iqk_backup_iqk_8822b(struct dm_struct *dm, u8 step, u8 path) case 0: _iqk_backup_iqk_8822b_subfunction(dm); - for (i = 0; i < 4; i++) { + for (i = 0; i < SS_8822B; i++) { iqk->rxiqk_fail_code[0][i] = 0x0; iqk->rxiqk_agc[0][i] = 0x0; for (j = 0; j < 2; j++) { @@ -467,7 +464,7 @@ void _iqk_reload_iqk_setting_8822b(struct dm_struct *dm, u8 ch, u32 bmask20_16 = (BIT(20) | BIT(19) | BIT(18) | BIT(17) | BIT(16)); boolean report; - for (path = 0; path < 2; path++) { + for (path = 0; path < SS_8822B; path++) { if (reload_idx == 2) { #if 0 /*odm_set_rf_reg(dm, (enum rf_path)path, RF_0xdf, BIT(4), 0x1);*/ @@ -584,7 +581,7 @@ void _iqk_rf_setting_8822b(struct dm_struct *dm) odm_write_4byte(dm, 0x1b00, 0xf8000008); odm_write_4byte(dm, 0x1bb8, 0x00000000); - for (path = 0; path < 2; path++) { + for (path = 0; path < SS_8822B; path++) { /*0xdf:B11 = 1,B4 = 0, B1 = 1*/ tmp = odm_get_rf_reg(dm, (enum rf_path)path, RF_0xdf, MASK20BITS); @@ -830,11 +827,11 @@ _iqk_check_cal_8822b(struct dm_struct *dm, u8 path, u8 cmd) odm_get_bb_reg(dm, R_0x1b08, BIT(26)); notready = false; } else { - ODM_delay_ms(1); + ODM_delay_us(10); delay_count++; } - if (delay_count >= 50) { + if (delay_count >= 20000) { fail = true; RF_DBG(dm, DBG_RF_IQK, "[IQK]IQK timeout!!!\n"); break; @@ -864,7 +861,7 @@ _iqk_rxk_gsearch_fail_8822b(struct dm_struct *dm, u8 path, u8 step) _iqk_ltec_write_8822b(dm, 0x38, 0xffff,0x7700); odm_write_4byte(dm, 0x1b00, IQK_CMD); odm_write_4byte(dm, 0x1b00, IQK_CMD + 0x1); - ODM_delay_ms(GS_delay_8822B); + ODM_delay_us(10); fail = _iqk_check_cal_8822b(dm, path, 0x1); _iqk_ltec_write_8822b(dm, 0x38, MASKDWORD, iqk->tmp_gntwl); } else if (step == RXIQK2) { @@ -872,6 +869,10 @@ _iqk_rxk_gsearch_fail_8822b(struct dm_struct *dm, u8 path, u8 step) if (iqk->tmp1bcc == IQMUX[idx]) break; } + if (idx == 4) { + RF_DBG(dm, DBG_RF_IQK, "[IQK] rx_gs overflow\n"); + return fail; + } odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); odm_write_4byte(dm, 0x1bcc, iqk->tmp1bcc); @@ -882,7 +883,7 @@ _iqk_rxk_gsearch_fail_8822b(struct dm_struct *dm, u8 path, u8 step) _iqk_ltec_write_8822b(dm, 0x38, 0xffff,0x7700); odm_write_4byte(dm, 0x1b00, IQK_CMD); odm_write_4byte(dm, 0x1b00, IQK_CMD + 0x1); - ODM_delay_ms(GS_delay_8822B); + ODM_delay_us(10); fail = _iqk_check_cal_8822b(dm, path, 0x1); _iqk_ltec_write_8822b(dm, 0x38, MASKDWORD, iqk->tmp_gntwl); @@ -950,7 +951,7 @@ _lok_one_shot_8822b(void *dm_void, u8 path) odm_write_4byte(dm, 0x1b00, IQK_CMD + 1); /*LOK: CMD ID = 0 {0xf8000018, 0xf8000028}*/ /*LOK: CMD ID = 0 {0xf8000019, 0xf8000029}*/ - ODM_delay_ms(LOK_delay_8822B); + ODM_delay_us(10); LOK_notready = _iqk_check_cal_8822b(dm, path, 0x0); _iqk_ltec_write_8822b(dm, 0x38, MASKDWORD, iqk->tmp_gntwl); @@ -1023,7 +1024,7 @@ _iqk_one_shot_8822b(void *dm_void, u8 path, u8 idx) _iqk_ltec_write_8822b(dm, 0x38, 0xffff,0x7700); odm_write_4byte(dm, 0x1b00, IQK_CMD); odm_write_4byte(dm, 0x1b00, IQK_CMD + 0x1); - ODM_delay_ms(WBIQK_delay_8822B); + ODM_delay_us(10); fail = _iqk_check_cal_8822b(dm, path, 0x1); _iqk_ltec_write_8822b(dm, 0x38, MASKDWORD, iqk->tmp_gntwl); @@ -1297,7 +1298,7 @@ void _iqk_iqk_by_path_8822b(void *dm_void, boolean segment_iqk) "[IQK]B_GS1_retry = %d B_GS2_retry = %d\n", iqk->gs_retry_count[0][RF_PATH_B][0], iqk->gs_retry_count[0][RF_PATH_B][1]); - for (i = 0; i < 2; i++) { + for (i = 0; i < SS_8822B; i++) { odm_write_4byte(dm, 0x1b00, 0xf8000008 | i << 1); odm_write_4byte(dm, 0x1b2c, 0x7); @@ -1425,7 +1426,7 @@ u32 _iqk_tximr_selfcheck_8822b(void *dm_void, u8 tone_index, u8 path) odm_write_4byte(dm, 0x1b38, 0x20000000); odm_write_4byte(dm, 0x1b3c, 0x20000000); /* ======derive pwr1========*/ - for (i = 0; i < 2; i++) { + for (i = 0; i < SS_8822B; i++) { odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); if (i == 0) odm_write_4byte(dm, 0x1bcc, 0x0f); @@ -1463,7 +1464,7 @@ void _iqk_start_tximr_test_8822b(struct dm_struct *dm, u8 imr_limit) u8 path, i, tone_index; u32 imr_result; - for (path = 0; path < 2; path++) { + for (path = 0; path < SS_8822B; path++) { _iqk_txk_setting_8822b(dm, path); KFAIL = _iqk_one_shot_8822b(dm, path, TXIQK); for (i = 0x0; i < imr_limit; i++) { @@ -1765,7 +1766,7 @@ void _iqk_start_rximr_test_8822b(struct dm_struct *dm, u8 imr_limit) { u8 path; - for (path = 0; path < 2; path++) + for (path = 0; path < SS_8822B; path++) _iqk_rximr_test_8822b(dm, path, imr_limit); } @@ -1800,6 +1801,7 @@ void _phy_iq_calibrate_8822b(struct dm_struct *dm, boolean reset, 0xc5c, 0xc6c, 0xe58, 0xe5c, 0xe6c}; u32 backup_rf_reg[RF_REG_NUM_8822B] = {0xdf, 0x8f, 0x65, 0x0, 0x1}; + u32 i; boolean is_mp = false; struct dm_iqk_info *iqk = &dm->IQK_info; @@ -1817,7 +1819,7 @@ void _phy_iq_calibrate_8822b(struct dm_struct *dm, boolean reset, "[IQK]band_type=%s band_width=%d ExtPA2G=%d ext_pa_5g=%d\n", (*dm->band_type == ODM_BAND_5G) ? "5G" : "2G", *dm->band_width, dm->ext_pa, dm->ext_pa_5g); - RF_DBG(dm, DBG_RF_IQK, "[IQK]Interface = %d, cut_version = %x\n", + RF_DBG(dm, DBG_RF_IQK, "[IQK]Interface = %d, Cv = %x\n", dm->support_interface, dm->cut_version); iqk->iqk_times++; @@ -1853,7 +1855,8 @@ void _phy_iq_calibrate_8822b(struct dm_struct *dm, boolean reset, break; iqk->kcount = 0; RF_DBG(dm, DBG_RF_IQK, "[IQK]delay 50ms!!!\n"); - ODM_delay_ms(50); + for (i = 0; i < 5000; i++) + ODM_delay_us(10); }; if (segment_iqk) _iqk_reload_iqk_setting_8822b(dm, 0x0, 0x1); @@ -1889,17 +1892,17 @@ void _phy_iq_calibrate_by_fw_8822b(void *dm_void, u8 clear, u8 segment_iqk) RF_DBG(dm, DBG_RF_IQK, "[IQK]FWIQK fail!!!\n"); } -/*IQK_version:0x2f, NCTL:0x8*/ -/*1.disable CCK block and OFDM CCA block while IQKing*/ void phy_iq_calibrate_8822b(void *dm_void, boolean clear, boolean segment_iqk) { struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 i; if (*dm->mp_mode) halrf_iqk_hwtx_check(dm, true); - /*FW IQK*/ if (dm->fw_offload_ability & PHYDM_RF_IQK_OFFLOAD) { _phy_iq_calibrate_by_fw_8822b(dm, clear, (u8)(segment_iqk)); + for (i = 0; i < 100; i++) + ODM_delay_us(10); phydm_get_read_counter_8822b(dm); halrf_iqk_check_if_reload(dm); } else { @@ -1982,8 +1985,8 @@ void phy_get_iqk_cfir_8822b(void *dm_void, u8 idx, u8 path, boolean debug) odm_set_bb_reg(dm, R_0x1bd8, MASKDWORD, 0xe0000001 + (i * 4)); tmp = odm_get_bb_reg(dm, R_0x1bfc, MASKDWORD); iqk_info->iqk_cfir_real[ch][path][idx][i] = - (tmp & 0x0fff0000) >> 16; - iqk_info->iqk_cfir_imag[ch][path][idx][i] = tmp & 0xfff; + (u16)((tmp & 0x0fff0000) >> 16); + iqk_info->iqk_cfir_imag[ch][path][idx][i] = (u16)tmp & 0xfff; } odm_set_bb_reg(dm, R_0x1bd8, MASKDWORD, 0x0); odm_set_bb_reg(dm, R_0x1b0c, BIT(13) | BIT(12), 0x0); @@ -1997,11 +2000,11 @@ void phy_iqk_dbg_cfir_backup_8822b(void *dm_void) RF_DBG(dm, DBG_RF_IQK, "[IQK]%-20s\n", "backup TX/RX CFIR"); - for (path = 0; path < 2; path++) + for (path = 0; path < SS_8822B; path++) for (idx = 0; idx < 2; idx++) phydm_get_iqk_cfir(dm, idx, path, true); - for (path = 0; path < 2; path++) { + for (path = 0; path < SS_8822B; path++) { for (idx = 0; idx < 2; idx++) { for (i = 0; i < 8; i++) { RF_DBG(dm, DBG_RF_IQK, @@ -2036,7 +2039,7 @@ void phy_iqk_dbg_cfir_backup_update_8822b(void *dm_void) RF_DBG(dm, DBG_RF_IQK, "[IQK]%-20s\n", "CFIR is invalid"); return; } - for (path = 0; path < 2; path++) { + for (path = 0; path < SS_8822B; path++) { for (idx = 0; idx < 2; idx++) { odm_set_bb_reg(dm, R_0x1b00, MASKDWORD, 0xf8000008 | path << 1); @@ -2083,7 +2086,7 @@ void phy_iqk_dbg_cfir_reload_8822b(void *dm_void) RF_DBG(dm, DBG_RF_IQK, "[IQK]%-20s\n", "CFIR is invalid"); return; } - for (path = 0; path < 2; path++) { + for (path = 0; path < SS_8822B; path++) { for (idx = 0; idx < 2; idx++) { odm_set_bb_reg(dm, R_0x1b00, MASKDWORD, 0xf8000008 | path << 1); @@ -2137,7 +2140,7 @@ void phy_iqk_dbg_cfir_backup_show_8822b(void *dm_void) RF_DBG(dm, DBG_RF_IQK, "[IQK]%-20s\n", "backup TX/RX CFIR"); - for (path = 0; path < 2; path++) { + for (path = 0; path < SS_8822B; path++) { for (idx = 0; idx < 2; idx++) { for (i = 0; i < 8; i++) { RF_DBG(dm, DBG_RF_IQK, diff --git a/hal/phydm/phydm.c b/hal/phydm/phydm.c index c7ef7ae..a26ec97 100644 --- a/hal/phydm/phydm.c +++ b/hal/phydm/phydm.c @@ -136,6 +136,10 @@ void phydm_cck_new_agc_chk(struct dm_struct *dm) /*@1: new agc 0: old agc*/ dm->cck_new_agc = (boolean)odm_get_bb_reg(dm, new_agc_addr, BIT(17)); #endif +#if (RTL8723F_SUPPORT) + if (dm->support_ic_type & (ODM_RTL8723F)) + dm->cck_new_agc = true; +#endif } /*select 3 or 4 bit LNA */ @@ -224,9 +228,9 @@ void phydm_init_hw_info_by_rfe(struct dm_struct *dm) if (dm->support_ic_type & ODM_RTL8197F) phydm_init_hw_info_by_rfe_type_8197f(dm); #endif - #if (RTL8814B_SUPPORT) - if (dm->support_ic_type & ODM_RTL8814B) - phydm_init_hw_info_by_rfe_type_8814b(dm); + #if (RTL8197G_SUPPORT) + if (dm->support_ic_type & ODM_RTL8197G) + phydm_init_hw_info_by_rfe_type_8197g(dm); #endif } #endif @@ -310,17 +314,64 @@ void phydm_common_info_self_init(struct dm_struct *dm) dm->u8_dummy = 0xf; dm->u16_dummy = 0xffff; dm->u32_dummy = 0xffffffff; - - dm->pause_lv_table.lv_cckpd = PHYDM_PAUSE_RELEASE; - dm->pause_lv_table.lv_dig = PHYDM_PAUSE_RELEASE; +#if (RTL8814B_SUPPORT) +/*@------------For spur detection Default Mode------------@*/ + dm->dsde_sel = DET_CSI; + dm->csi_wgt = 4; +/*@-------------------------------------------------------@*/ +#endif dm->pre_is_linked = false; dm->is_linked = false; +/*dym bw thre and it can config by registry*/ + if (dm->en_auto_bw_th == 0) + dm->en_auto_bw_th = 20; + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) if (!(dm->is_fcs_mode_enable)) { dm->is_fcs_mode_enable = &dm->boolean_dummy; pr_debug("[Warning] is_fcs_mode_enable=NULL\n"); } #endif + /*init IOT table*/ + odm_memory_set(dm, &dm->iot_table, 0, sizeof(struct phydm_iot_center)); +} + +void phydm_iot_patch_id_update(void *dm_void, u32 iot_idx, boolean en) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_iot_center *iot_table = &dm->iot_table; + + PHYDM_DBG(dm, DBG_CMN, "[IOT] 0x%x = %d\n", iot_idx, en); + switch (iot_idx) { + case 0x100f0401: + iot_table->patch_id_100f0401 = en; + PHYDM_DBG(dm, DBG_CMN, "[IOT] patch_id_100f0401 = %d\n", + iot_table->patch_id_100f0401); + break; + case 0x10120200: + iot_table->patch_id_10120200 = en; + PHYDM_DBG(dm, DBG_CMN, "[IOT] patch_id_10120200 = %d\n", + iot_table->patch_id_10120200); + break; + case 0x40010700: + iot_table->patch_id_40010700 = en; + PHYDM_DBG(dm, DBG_CMN, "[IOT] patch_id_40010700 = %d\n", + iot_table->patch_id_40010700); + break; + case 0x021f0800: + iot_table->patch_id_021f0800 = en; + PHYDM_DBG(dm, DBG_CMN, "[IOT] patch_id_021f0800 = %d\n", + iot_table->patch_id_021f0800); + break; + case 0x011f0500: + iot_table->patch_id_011f0500 = en; + PHYDM_DBG(dm, DBG_CMN, "[IOT] patch_id_011f0500 = %d\n", + iot_table->patch_id_011f0500); + break; + default: + pr_debug("[%s] warning!\n", __func__); + break; + } } void phydm_cmn_sta_info_update(void *dm_void, u8 macid) @@ -364,24 +415,6 @@ void phydm_common_info_self_update(struct dm_struct *dm) sta = dm->phydm_sta_info[0]; - #if 0 - if (mgnt_info->mAssoc) { - sta->dm_ctrl |= STA_DM_CTRL_ACTIVE; - for (i = 0; i < 6; i++) - sta->mac_addr[i] = mgnt_info->Bssid[i]; - } else if (GetFirstClientPort(adapter)) { - struct _ADAPTER *client_adapter = GetFirstClientPort(adapter); - - sta->dm_ctrl |= STA_DM_CTRL_ACTIVE; - for (i = 0; i < 6; i++) - sta->mac_addr[i] = client_adapter->MgntInfo.Bssid[i]; - } else { - sta->dm_ctrl = sta->dm_ctrl & (~STA_DM_CTRL_ACTIVE); - for (i = 0; i < 6; i++) - sta->mac_addr[i] = 0; - } - #endif - /* STA mode is linked to AP */ if (is_sta_active(sta) && !ACTING_AS_AP(adapter)) dm->bsta_state = true; @@ -491,11 +524,11 @@ phydm_get_structure(struct dm_struct *dm, u8 structure_type) case PHYDM_ADAPTIVITY: structure = &dm->adaptivity; break; - +#ifdef CONFIG_PHYDM_DFS_MASTER case PHYDM_DFS: structure = &dm->dfs; break; - +#endif default: break; } @@ -548,11 +581,85 @@ void phydm_hw_setting(struct dm_struct *dm) phydm_hwsetting_8822c(dm); #endif +#if (RTL8197G_SUPPORT) + if (dm->support_ic_type & ODM_RTL8197G) + phydm_hwsetting_8197g(dm); +#endif + +#if (RTL8723F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8723F) + phydm_hwsetting_8723f(dm); +#endif + +#if (RTL8821C_SUPPORT) + if (dm->support_ic_type & ODM_RTL8821C) + phydm_hwsetting_8821c(dm); +#endif + +#if (RTL8812F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8812F) + phydm_hwsetting_8812f(dm); +#endif + #ifdef PHYDM_CCK_RX_PATHDIV_SUPPORT phydm_cck_rx_pathdiv_watchdog(dm); #endif } +__odm_func__ +boolean phydm_chk_bb_rf_pkg_set_valid(struct dm_struct *dm) +{ + boolean valid = true; + + if (dm->support_ic_type == ODM_RTL8822C) { + #if (RTL8822C_SUPPORT) + valid = phydm_chk_pkg_set_valid_8822c(dm, + RELEASE_VERSION_8822C, + RF_RELEASE_VERSION_8822C); + #else + valid = true; /*@Just for preventing compile warnings*/ + #endif + #if (RTL8812F_SUPPORT) + } else if (dm->support_ic_type == ODM_RTL8812F) { + valid = phydm_chk_pkg_set_valid_8812f(dm, + RELEASE_VERSION_8812F, + RF_RELEASE_VERSION_8812F); + #endif + #if (RTL8197G_SUPPORT) + } else if (dm->support_ic_type == ODM_RTL8197G) { + valid = phydm_chk_pkg_set_valid_8197g(dm, + RELEASE_VERSION_8197G, + RF_RELEASE_VERSION_8197G); + #endif + #if (RTL8812F_SUPPORT) + } else if (dm->support_ic_type == ODM_RTL8812F) { + valid = phydm_chk_pkg_set_valid_8812f(dm, + RELEASE_VERSION_8812F, + RF_RELEASE_VERSION_8812F); + #endif + #if (RTL8198F_SUPPORT) + } else if (dm->support_ic_type == ODM_RTL8198F) { + valid = phydm_chk_pkg_set_valid_8198f(dm, + RELEASE_VERSION_8198F, + RF_RELEASE_VERSION_8198F); + #endif + #if (RTL8814B_SUPPORT) + } else if (dm->support_ic_type == ODM_RTL8814B) { + valid = phydm_chk_pkg_set_valid_8814b(dm, + RELEASE_VERSION_8814B, + RF_RELEASE_VERSION_8814B); + #endif + #if (RTL8723F_SUPPORT) + } else if (dm->support_ic_type == ODM_RTL8723F) { + valid = phydm_chk_pkg_set_valid_8723f(dm, + RELEASE_VERSION_8723F, + RF_RELEASE_VERSION_8723F); + #endif + } + + return valid; +} + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) u64 phydm_supportability_init_win( void *dm_void) @@ -785,7 +892,7 @@ u64 phydm_supportability_init_win( support_ability |= ODM_BB_DIG | ODM_BB_RA_MASK | - /* ODM_BB_DYNAMIC_TXPWR |*/ + ODM_BB_DYNAMIC_TXPWR | ODM_BB_FA_CNT | ODM_BB_RSSI_MONITOR | ODM_BB_CCK_PD | @@ -814,6 +921,22 @@ u64 phydm_supportability_init_win( break; #endif +#if (RTL8723F_SUPPORT) + case ODM_RTL8723F: + support_ability |= + ODM_BB_DIG | + ODM_BB_RA_MASK | + /* ODM_BB_DYNAMIC_TXPWR |*/ + ODM_BB_FA_CNT | + ODM_BB_RSSI_MONITOR | + ODM_BB_CCK_PD | + /*ODM_BB_PWR_TRAIN |*/ + ODM_BB_RATE_ADAPTIVE | + ODM_BB_ADAPTIVITY | + ODM_BB_CFO_TRACKING | + ODM_BB_ENV_MONITOR; + break; +#endif default: support_ability |= ODM_BB_DIG | @@ -1045,7 +1168,7 @@ u64 phydm_supportability_init_ce(void *dm_void) support_ability |= ODM_BB_DIG | ODM_BB_RA_MASK | - /*@ODM_BB_DYNAMIC_TXPWR |*/ + ODM_BB_DYNAMIC_TXPWR | ODM_BB_FA_CNT | ODM_BB_RSSI_MONITOR | ODM_BB_CCK_PD | @@ -1064,12 +1187,12 @@ u64 phydm_supportability_init_ce(void *dm_void) support_ability |= ODM_BB_DIG | ODM_BB_RA_MASK | - /* ODM_BB_DYNAMIC_TXPWR |*/ + ODM_BB_DYNAMIC_TXPWR | ODM_BB_FA_CNT | ODM_BB_RSSI_MONITOR | ODM_BB_CCK_PD | ODM_BB_RATE_ADAPTIVE | - ODM_BB_PATH_DIV | + /* ODM_BB_PATH_DIV | */ ODM_BB_ADAPTIVITY | ODM_BB_CFO_TRACKING | ODM_BB_ENV_MONITOR; @@ -1087,12 +1210,27 @@ u64 phydm_supportability_init_ce(void *dm_void) ODM_BB_CCK_PD | /*@ODM_BB_PWR_TRAIN |*/ /*ODM_BB_RATE_ADAPTIVE |*/ - ODM_BB_ADAPTIVITY; - /*ODM_BB_CFO_TRACKING |*/ + ODM_BB_ADAPTIVITY | + ODM_BB_CFO_TRACKING; /*ODM_BB_ENV_MONITOR;*/ break; #endif - +#if (RTL8723F_SUPPORT) + case ODM_RTL8723F: + support_ability |= + ODM_BB_DIG | + ODM_BB_RA_MASK | + ODM_BB_DYNAMIC_TXPWR | + ODM_BB_FA_CNT | + ODM_BB_RSSI_MONITOR | + ODM_BB_CCK_PD | + ODM_BB_RATE_ADAPTIVE | + /* ODM_BB_PATH_DIV | */ + ODM_BB_ADAPTIVITY | + ODM_BB_CFO_TRACKING | + ODM_BB_ENV_MONITOR; + break; +#endif default: support_ability |= ODM_BB_DIG | @@ -1177,15 +1315,15 @@ u64 phydm_supportability_init_ap( #if (RTL8198F_SUPPORT || RTL8197F_SUPPORT) case ODM_RTL8198F: support_ability |= - /*ODM_BB_DIG |*/ + ODM_BB_DIG | ODM_BB_RA_MASK | ODM_BB_FA_CNT | ODM_BB_RSSI_MONITOR | ODM_BB_CCK_PD | /*ODM_BB_PWR_TRAIN |*/ /*ODM_BB_RATE_ADAPTIVE |*/ - ODM_BB_ADAPTIVITY; - /*ODM_BB_CFO_TRACKING |*/ + ODM_BB_ADAPTIVITY | + ODM_BB_CFO_TRACKING; /*ODM_BB_ADAPTIVE_SOML |*/ /*ODM_BB_ENV_MONITOR |*/ /*ODM_BB_LNA_SAT_CHK |*/ @@ -1310,9 +1448,9 @@ u64 phydm_supportability_init_ap( ODM_BB_CCK_PD | /*ODM_BB_PWR_TRAIN |*/ /*ODM_BB_RATE_ADAPTIVE |*/ - ODM_BB_ADAPTIVITY; - /*ODM_BB_CFO_TRACKING |*/ - /*ODM_BB_ENV_MONITOR;*/ + ODM_BB_ADAPTIVITY | + ODM_BB_CFO_TRACKING | + ODM_BB_ENV_MONITOR; break; #endif @@ -1337,6 +1475,7 @@ u64 phydm_supportability_init_ap( support_ability |= ODM_BB_DIG | ODM_BB_RA_MASK | + ODM_BB_DYNAMIC_TXPWR | ODM_BB_FA_CNT | ODM_BB_RSSI_MONITOR | /*ODM_BB_CCK_PD |*/ @@ -1348,6 +1487,21 @@ u64 phydm_supportability_init_ap( break; #endif +#if (RTL8723F_SUPPORT) + case ODM_RTL8723F: + support_ability |= + ODM_BB_DIG | + ODM_BB_RA_MASK | + ODM_BB_FA_CNT | + ODM_BB_RSSI_MONITOR | + ODM_BB_CCK_PD | + /*ODM_BB_PWR_TRAIN |*/ + ODM_BB_RATE_ADAPTIVE | + ODM_BB_ADAPTIVITY | + ODM_BB_CFO_TRACKING | + ODM_BB_ENV_MONITOR; + break; +#endif default: support_ability |= ODM_BB_DIG | @@ -1365,16 +1519,6 @@ u64 phydm_supportability_init_ap( break; } -#if 0 - /*@[Config Antenna Diveristy]*/ - if (*dm->enable_antdiv) - support_ability |= ODM_BB_ANT_DIV; - - /*@[Config Adaptivity]*/ - if (*dm->edcca_mode) - support_ability |= ODM_BB_ADAPTIVITY; -#endif - return support_ability; } #endif @@ -1431,8 +1575,8 @@ u64 phydm_supportability_init_iot( /*ODM_BB_PWR_TRAIN |*/ ODM_BB_RATE_ADAPTIVE | ODM_BB_ADAPTIVITY | - ODM_BB_CFO_TRACKING; - /*ODM_BB_ENV_MONITOR*/ + ODM_BB_CFO_TRACKING | + ODM_BB_ENV_MONITOR; break; #endif @@ -1495,8 +1639,7 @@ void phydm_fwoffload_ability_init(struct dm_struct *dm, { switch (offload_ability) { case PHYDM_PHY_PARAM_OFFLOAD: - if (dm->support_ic_type & - (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8821C)) + if (dm->support_ic_type & PHYDM_IC_SUPPORT_FW_PARAM_OFFLOAD) dm->fw_offload_ability |= PHYDM_PHY_PARAM_OFFLOAD; break; @@ -1504,6 +1647,10 @@ void phydm_fwoffload_ability_init(struct dm_struct *dm, dm->fw_offload_ability |= PHYDM_RF_IQK_OFFLOAD; break; + case PHYDM_RF_DPK_OFFLOAD: + dm->fw_offload_ability |= PHYDM_RF_DPK_OFFLOAD; + break; + default: PHYDM_DBG(dm, ODM_COMP_INIT, "fwofflad, wrong init type!!\n"); break; @@ -1518,8 +1665,7 @@ void phydm_fwoffload_ability_clear(struct dm_struct *dm, { switch (offload_ability) { case PHYDM_PHY_PARAM_OFFLOAD: - if (dm->support_ic_type & - (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8821C)) + if (dm->support_ic_type & PHYDM_IC_SUPPORT_FW_PARAM_OFFLOAD) dm->fw_offload_ability &= (~PHYDM_PHY_PARAM_OFFLOAD); break; @@ -1527,6 +1673,10 @@ void phydm_fwoffload_ability_clear(struct dm_struct *dm, dm->fw_offload_ability &= (~PHYDM_RF_IQK_OFFLOAD); break; + case PHYDM_RF_DPK_OFFLOAD: + dm->fw_offload_ability &= (~PHYDM_RF_DPK_OFFLOAD); + break; + default: PHYDM_DBG(dm, ODM_COMP_INIT, "fwofflad, wrong init type!!\n"); break; @@ -1569,6 +1719,14 @@ void phydm_supportability_init(void *dm_void) if (IS_FUNC_EN(dm->en_adap_soml)) support_ability |= ODM_BB_ADAPTIVE_SOML; + /*@[DYNAMIC_TXPWR and TSSI cannot coexist]*/ + if(IS_FUNC_EN(&dm->en_tssi_mode) && + (dm->support_ic_type & ODM_RTL8822C)) + support_ability &= ~ODM_BB_DYNAMIC_TXPWR; + /*@[DYNAMIC_TXPWR and TSSI cannot coexist]*/ + if(IS_FUNC_EN(&dm->en_tssi_mode) && + (dm->support_ic_type & ODM_RTL8723F)) + support_ability &= ~ODM_BB_DYNAMIC_TXPWR; } dm->support_ability = support_ability; PHYDM_DBG(dm, ODM_COMP_INIT, "IC=0x%x, mp=%d, Supportability=0x%llx\n", @@ -1586,6 +1744,41 @@ void phydm_rfe_init(void *dm_void) #endif } +#ifdef CONFIG_DYNAMIC_TXCOLLISION_TH +void phydm_tx_collsion_th_init(void *dm_void) +{ + +struct dm_struct *dm = (struct dm_struct *)dm_void; + +#if (RTL8197G_SUPPORT) + if (dm->support_ic_type & ODM_RTL8197G) + phydm_tx_collsion_th_init_8197g(dm); +#endif + +#if (RTL8812F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8812F) + phydm_tx_collsion_th_init_8812f(dm); +#endif + +} + +void phydm_tx_collsion_th_set(void *dm_void, u8 val_r2t, u8 val_t2r) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + +#if (RTL8197G_SUPPORT) + if (dm->support_ic_type & ODM_RTL8197G) + phydm_tx_collsion_th_set_8197g(dm, val_r2t, val_t2r); +#endif + +#if (RTL8812F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8812F) + phydm_tx_collsion_th_set_8812f(dm, val_r2t, val_t2r); +#endif + +} +#endif + void phydm_dm_early_init(struct dm_struct *dm) { #if (DM_ODM_SUPPORT_TYPE == ODM_CE) @@ -1593,10 +1786,18 @@ void phydm_dm_early_init(struct dm_struct *dm) #endif } -void odm_dm_init(struct dm_struct *dm) +enum phydm_init_result odm_dm_init(struct dm_struct *dm) { + enum phydm_init_result result = PHYDM_INIT_SUCCESS; + + if (!phydm_chk_bb_rf_pkg_set_valid(dm)) { + pr_debug("[Warning][%s] Init fail\n", __func__); + return PHYDM_INIT_FAIL_BBRF_REG_INVALID; + } + halrf_init(dm); phydm_supportability_init(dm); + phydm_pause_func_init(dm); phydm_rfe_init(dm); phydm_common_info_self_init(dm); phydm_rx_phy_status_init(dm); @@ -1605,6 +1806,9 @@ void odm_dm_init(struct dm_struct *dm) #endif phydm_dig_init(dm); #ifdef PHYDM_SUPPORT_CCKPD +#ifdef PHYDM_DCC_ENHANCE + phydm_dig_cckpd_coex_init(dm); +#endif phydm_cck_pd_init(dm); #endif phydm_env_monitor_init(dm); @@ -1665,6 +1869,12 @@ void odm_dm_init(struct dm_struct *dm) #ifdef CONFIG_MU_RSOML phydm_mu_rsoml_init(dm); #endif + +#ifdef CONFIG_DYNAMIC_TXCOLLISION_TH + phydm_tx_collsion_th_init(dm); +#endif + + return result; } void odm_dm_reset(struct dm_struct *dm) @@ -1687,8 +1897,7 @@ void phydm_supportability_en(void *dm_void, char input[][16], u32 *_used, u8 i; for (i = 0; i < 5; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &dm_value[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &dm_value[i]); } pre_support_ability = dm->support_ability; @@ -1759,7 +1968,6 @@ void phydm_supportability_en(void *dm_void, char input[][16], u32 *_used, PDM_SNPF(out_len, used, output + used, out_len - used, "18. (( %s ))LNA_SAT_CHK\n", ((comp & ODM_BB_LNA_SAT_CHK) ? ("V") : ("."))); - PDM_SNPF(out_len, used, output + used, out_len - used, "================================\n"); PDM_SNPF(out_len, used, output + used, out_len - used, @@ -1828,6 +2036,9 @@ void phydm_watchdog_lps(struct dm_struct *dm) phydm_cck_pd_th(dm); #endif phydm_adaptivity(dm); + #ifdef CONFIG_BW_INDICATION + phydm_dyn_bw_indication(dm); + #endif #if (DM_ODM_SUPPORT_TYPE & (ODM_CE)) #ifdef CONFIG_PHYDM_ANTENNA_DIVERSITY /*@enable AntDiv in PS mode, request from SD4 Jeff*/ @@ -1855,6 +2066,18 @@ void phydm_pause_dm_watchdog(void *dm_void, enum phydm_pause_type pause_type) } } +void phydm_pause_func_init(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + dm->pause_lv_table.lv_cckpd = PHYDM_PAUSE_RELEASE; + dm->pause_lv_table.lv_dig = PHYDM_PAUSE_RELEASE; + dm->pause_lv_table.lv_antdiv = PHYDM_PAUSE_RELEASE; + dm->pause_lv_table.lv_dig = PHYDM_PAUSE_RELEASE; + dm->pause_lv_table.lv_adapt = PHYDM_PAUSE_RELEASE; + dm->pause_lv_table.lv_adsl = PHYDM_PAUSE_RELEASE; +} + u8 phydm_pause_func(void *dm_void, enum phydm_func_idx pause_func, enum phydm_pause_type pause_type, enum phydm_pause_level pause_lv, u8 val_lehgth, @@ -2061,8 +2284,7 @@ void phydm_pause_func_console(void *dm_void, char input[][16], u32 *_used, } for (i = 0; i < 10; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); } func = (enum phydm_func_idx)var1[0]; @@ -2178,20 +2400,34 @@ void phydm_watchdog(struct dm_struct *dm) phydm_hw_setting(dm); - #ifdef PHYDM_TDMA_DIG_SUPPORT - if (dm->original_dig_restore == 0) + phydm_env_mntr_result_watchdog(dm); + +#ifdef PHYDM_TDMA_DIG_SUPPORT + if (dm->original_dig_restore == 0) { phydm_tdma_dig_timer_check(dm); - else - #endif + } else +#endif { phydm_false_alarm_counter_statistics(dm); - phydm_noisy_detection(dm); + #if (ODM_IC_11N_SERIES_SUPPORT || ODM_IC_11AC_SERIES_SUPPORT) + if (dm->support_ic_type & (ODM_IC_11N_SERIES | + ODM_IC_11AC_SERIES)) + phydm_noisy_detection(dm); + #endif + + #if defined(PHYDM_DCC_ENHANCE) && defined(PHYDM_SUPPORT_CCKPD) + phydm_dig_cckpd_coex(dm); + #else phydm_dig(dm); #ifdef PHYDM_SUPPORT_CCKPD phydm_cck_pd_th(dm); #endif + #endif } +#ifdef PHYDM_HW_IGI + phydm_hwigi(dm); +#endif #ifdef PHYDM_POWER_TRAINING_SUPPORT phydm_update_power_training_state(dm); #endif @@ -2219,11 +2455,14 @@ void phydm_watchdog(struct dm_struct *dm) #ifdef PHYDM_PRIMARY_CCA phydm_primary_cca(dm); #endif +#ifdef CONFIG_BW_INDICATION + phydm_dyn_bw_indication(dm); +#endif #if (DM_ODM_SUPPORT_TYPE == ODM_CE) odm_dtc(dm); #endif - phydm_env_mntr_watchdog(dm); + phydm_env_mntr_set_watchdog(dm); #ifdef PHYDM_LNA_SAT_CHK_SUPPORT phydm_lna_sat_chk_watchdog(dm); @@ -2240,6 +2479,46 @@ void phydm_watchdog(struct dm_struct *dm) phydm_common_info_self_reset(dm); } +void phydm_fw_dm_ctrl_en(void *dm_void, enum phydm_func_idx fun_idx, + boolean enable) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u8 h2c_val[H2C_MAX_LENGTH] = {0}; + u8 para4[4]; /*4 bit*/ + u8 para8[4]; /*8 bit*/ + u8 i = 0; + + for (i = 0; i < 4; i++) { + para4[i] = 0; + para8[i] = 0; + } + + switch (fun_idx) { + case F00_DIG: + phydm_fill_fw_dig_info(dm, &enable, para4, para8); + break; + default: + pr_debug("[Warning] %s\n", __func__); + return; + } + + h2c_val[0] = (u8)((fun_idx & 0x3f) | (enable << 6)); + h2c_val[1] = para8[0]; + h2c_val[2] = para8[1]; + h2c_val[3] = para8[2]; + h2c_val[4] = para8[3]; + h2c_val[5] = (para4[0] & 0xf) | ((para4[1] & 0xf) << 3); + h2c_val[6] = (para4[2] & 0xf) | ((para4[3] & 0xf) << 3); + + PHYDM_DBG(dm, DBG_FW_DM, + "H2C[0x59] fun_idx=%d,en=%d,para8={%x %x %x %x},para4={%x %x %x %x}\n", + fun_idx, enable, + para8[0], para8[1], para8[2], para8[3], + para4[0], para4[1], para4[2], para4[3]); + + odm_fill_h2c_cmd(dm, PHYDM_H2C_FW_DM_CTRL, H2C_MAX_LENGTH, h2c_val); +} + /*@ * Init /.. Fixed HW value. Only init time. */ @@ -2439,10 +2718,19 @@ void odm_cmn_info_init(struct dm_struct *dm, enum odm_cmninfo cmn_info, case ODM_CMNINFO_DIS_DPD: dm->en_dis_dpd = (boolean)value; break; + case ODM_CMNINFO_EN_AUTO_BW_TH: + dm->en_auto_bw_th = (u8)value; + break; #if (RTL8721D_SUPPORT) case ODM_CMNINFO_POWER_VOLTAGE: dm->power_voltage = (u8)value; break; + case ODM_CMNINFO_ANTDIV_GPIO: + dm->antdiv_gpio = (u8)value; + break; + case ODM_CMNINFO_PEAK_DETECT_MODE: + dm->peak_detect_mode = (u8)value; + break; #endif default: break; @@ -2594,6 +2882,8 @@ void odm_cmn_info_hook(struct dm_struct *dm, enum odm_cmninfo cmn_info, case ODM_CMNINFO_MANUAL_SUPPORTABILITY: dm->manual_supportability = (u32 *)value; break; + case ODM_CMNINFO_EN_DYM_BW_INDICATION: + dm->dis_dym_bw_indication = (u8 *)value; default: /*do nothing*/ break; @@ -2640,7 +2930,9 @@ void odm_cmn_info_update(struct dm_struct *dm, u32 cmn_info, u64 value) break; case ODM_CMNINFO_RSSI_MIN: +#if 0 dm->rssi_min = (u8)value; +#endif break; case ODM_CMNINFO_RSSI_MIN_BY_PATH: @@ -2699,6 +2991,12 @@ void odm_cmn_info_update(struct dm_struct *dm, u32 cmn_info, u64 value) case ODM_CMNINFO_LINKED_BF_SUPPORT: dm->linked_bf_support = (u8)value; break; + case ODM_CMNINFO_FLATNESS_TYPE: + dm->flatness_type = (u8)value; + break; + case ODM_CMNINFO_TSSI_ENABLE: + dm->en_tssi_mode = (u8)value; + break; default: break; } @@ -2789,7 +3087,15 @@ u32 phydm_cmn_info_query(struct dm_struct *dm, enum phydm_info_query info_type) case PHYDM_INFO_NHM_RATIO: return (u32)ccx_info->nhm_ratio; case PHYDM_INFO_NHM_NOISE_PWR: - return (u32)ccx_info->nhm_noise_pwr; + return (u32)ccx_info->nhm_level; + case PHYDM_INFO_NHM_PWR: + return (u32)ccx_info->nhm_pwr; + case PHYDM_INFO_NHM_ENV_RATIO: + return (u32)ccx_info->nhm_env_ratio; + case PHYDM_INFO_TXEN_CCK: + return (u32)fa_t->cnt_cck_txen; + case PHYDM_INFO_TXEN_OFDM: + return (u32)fa_t->cnt_ofdm_txen; default: return 0xffffffff; } @@ -3146,12 +3452,6 @@ void odm_dtc(struct dm_struct *dm) u8 sign; u8 resp_txagc = 0; -#if 0 - /* @As DIG is disabled, DTC is also disable */ - if (!(dm->support_ability & ODM_XXXXXX)) - return; -#endif - if (dm->rssi_min > DTC_BASE) { /* need to decade the CTS TX power */ sign = 1; @@ -3223,7 +3523,7 @@ void phydm_dc_cancellation(struct dm_struct *dm) if (path > RF_PATH_A && dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8188F | ODM_RTL8710B | ODM_RTL8721D | - ODM_RTL8710C)) + ODM_RTL8710C | ODM_RTL8723D)) break; else if (path > RF_PATH_B && dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8192F)) @@ -3234,11 +3534,13 @@ void phydm_dc_cancellation(struct dm_struct *dm) } odm_write_dig(dm, 0x7e); /*@Disable LNA*/ - if (dm->support_ic_type & ODM_RTL8821C) + if (dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8721D | + ODM_RTL8710C)) halrf_rf_lna_setting(dm, HALRF_LNA_DISABLE); /*Turn off 3-wire*/ phydm_stop_3_wire(dm, PHYDM_SET); - if (dm->support_ic_type & (ODM_RTL8188F | ODM_RTL8710B)) { + if (dm->support_ic_type & (ODM_RTL8188F | ODM_RTL8723D | + ODM_RTL8710B)) { /*set debug port to 0x235*/ if (!phydm_set_bb_dbg_port(dm, DBGPORT_PRI_1, 0x235)) { PHYDM_DBG(dm, ODM_COMP_API, @@ -3310,7 +3612,8 @@ void phydm_dc_cancellation(struct dm_struct *dm) /* @Turn on 3-wire*/ phydm_stop_3_wire(dm, PHYDM_REVERT); /* @Enable LNA*/ - if (dm->support_ic_type & ODM_RTL8821C) + if (dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8721D | + ODM_RTL8710C)) halrf_rf_lna_setting(dm, HALRF_LNA_ENABLE); odm_write_dig(dm, 0x20); @@ -3323,7 +3626,8 @@ void phydm_dc_cancellation(struct dm_struct *dm) /*@DC_Cancellation*/ /*@DC compensation to CCK data path*/ odm_set_bb_reg(dm, R_0xa9c, BIT(20), 0x1); - if (dm->support_ic_type & (ODM_RTL8188F | ODM_RTL8710B)) { + if (dm->support_ic_type & (ODM_RTL8188F | ODM_RTL8723D | + ODM_RTL8710B)) { offset_i_hex[0] = (reg_value32[0] & 0xffc0000) >> 18; offset_q_hex[0] = (reg_value32[0] & 0x3ff00) >> 8; @@ -3419,12 +3723,18 @@ void phydm_dc_cancellation(struct dm_struct *dm) offset_i_hex[0] = (reg_value32[0] & 0xff80000) >> 19; offset_q_hex[0] = (reg_value32[0] & 0x3fe00) >> 9; - /*@Before filling into registers, - *offset should be multiplexed (-1) - */ - offset_i_hex[0] = 0x200 - offset_i_hex[0]; - offset_q_hex[0] = 0x200 - offset_q_hex[0]; - + if ((offset_i_hex[0] > 0xF && offset_i_hex[0] < 0x1F1) + || (offset_q_hex[0] > 0xF && offset_q_hex[0] < 0x1F1)) { + /*@Discard outliers*/ + offset_i_hex[0] = 0x0; + offset_q_hex[0] = 0x0; + } else { + /*@Before filling into registers, + *offset should be multiplexed (-1) + */ + offset_i_hex[0] = 0x200 - offset_i_hex[0]; + offset_q_hex[0] = 0x200 - offset_q_hex[0]; + } odm_set_bb_reg(dm, R_0x950, 0x1ff, offset_i_hex[0]); odm_set_bb_reg(dm, R_0x950, 0x1ff0000, offset_q_hex[0]); } @@ -3488,3 +3798,29 @@ end: } #endif } + +void phydm_dyn_bw_indication(void *dm_void) +{ +#ifdef CONFIG_BW_INDICATION + struct dm_struct *dm = (struct dm_struct *)dm_void; + u8 en_auto_bw_th = dm->en_auto_bw_th; + + if (!(dm->support_ic_type & ODM_DYM_BW_INDICATION_SUPPORT)) + return; + + /*driver decide bw cobime timing*/ + if (dm->dis_dym_bw_indication) { + if (*dm->dis_dym_bw_indication) + return; + } + + /*check for auto bw*/ + if (dm->rssi_min <= en_auto_bw_th && dm->is_linked) { + phydm_bw_fixed_enable(dm, FUNC_DISABLE); + return; + } + + phydm_bw_fixed_setting(dm); +#endif +} + diff --git a/hal/phydm/phydm.h b/hal/phydm/phydm.h index 4981551..2f96186 100644 --- a/hal/phydm/phydm.h +++ b/hal/phydm/phydm.h @@ -204,6 +204,8 @@ extern const u16 phy_rate_table[84]; #define PHY_HIST_SIZE 12 #define PHY_HIST_TH_SIZE (PHY_HIST_SIZE - 1) +#define S_TO_US 1000000 + /*@============================================================*/ /*structure and define*/ /*@============================================================*/ @@ -211,6 +213,8 @@ extern const u16 phy_rate_table[84]; #define dm_type_by_fw 0 #define dm_type_by_driver 1 +#define HW_IGI_TXINFO_TABLE_SIZE 64 + #ifdef BB_RAM_SUPPORT struct phydm_bb_ram_per_sta { @@ -230,7 +234,7 @@ struct phydm_bb_ram_per_sta { struct phydm_bb_ram_ctrl { /*@ For 98F/14B/22C/12F, each tx_pwr_ofst step will be 1dB*/ - struct phydm_bb_ram_per_sta pram_sta_ctrl[ODM_ASSOCIATE_ENTRY_NUM]; + struct phydm_bb_ram_per_sta pram_sta_ctrl[HW_IGI_TXINFO_TABLE_SIZE]; /*------------ For table2 do not set power offset by macid --------*/ /* For type == 2'b10, 0x1e70[22:16] = tx_pwr_offset_reg0, 0x1e70[23] = enable */ boolean tx_pwr_ofst_reg0_en; @@ -238,6 +242,9 @@ struct phydm_bb_ram_ctrl { /* For type == 2'b11, 0x1e70[30:24] = tx_pwr_offset_reg1, 0x1e70[31] = enable */ boolean tx_pwr_ofst_reg1_en; u8 tx_pwr_ofst_reg1; + boolean hwigi_watchdog_en; + u64 macid_is_linked; + u64 hwigi_macid_is_linked; }; #endif @@ -372,14 +379,14 @@ struct odm_phy_dbg_info { #endif u16 snr_hist_th[PHY_HIST_TH_SIZE]; u16 evm_hist_th[PHY_HIST_TH_SIZE]; - #ifdef PHYDM_PHYSTAUS_AUTO_SWITCH + #ifdef PHYSTS_3RD_TYPE_SUPPORT u16 cn_hist_th[PHY_HIST_TH_SIZE]; /*U(16,1)*/ - #endif - #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT - s16 cfo_tail[4]; /* per-path's cfo_tail */ + u8 condition_num_seg0; + u8 eigen_val[4]; + s16 cfo_tail[4]; /*per-path's cfo_tail */ #endif struct phydm_phystatus_statistic physts_statistic_info; - struct phydm_phystatus_avg phystatus_statistic_avg; + struct phydm_phystatus_avg phystatus_statistic_avg; }; enum odm_cmninfo { @@ -431,9 +438,12 @@ enum odm_cmninfo { ODM_CMNINFO_X_CAP_SETTING, ODM_CMNINFO_ADVANCE_OTA, ODM_CMNINFO_HP_HWID, - ODM_CMNINFO_TSSI_ENABLE, + ODM_CMNINFO_TSSI_ENABLE, /*also for cmn_info_update*/ ODM_CMNINFO_DIS_DPD, ODM_CMNINFO_POWER_VOLTAGE, + ODM_CMNINFO_ANTDIV_GPIO, + ODM_CMNINFO_EN_AUTO_BW_TH, + ODM_CMNINFO_PEAK_DETECT_MODE, /*@-----------HOOK BEFORE REG INIT-----------*/ /*@Dynamic value:*/ @@ -472,6 +482,7 @@ enum odm_cmninfo { ODM_CMNINFO_BB_OPERATION_MODE, ODM_CMNINFO_BF_ANTDIV_DECISION, ODM_CMNINFO_MANUAL_SUPPORTABILITY, + ODM_CMNINFO_EN_DYM_BW_INDICATION, /*@--------- POINTER REFERENCE-----------*/ /*@------------CALL BY VALUE-------------*/ @@ -502,6 +513,7 @@ enum odm_cmninfo { ODM_CMNINFO_PHYDM_PATCH_ID, ODM_CMNINFO_RRSR_VAL, ODM_CMNINFO_LINKED_BF_SUPPORT, + ODM_CMNINFO_FLATNESS_TYPE, /*@------------CALL BY VALUE-------------*/ /*@Dynamic ptr array hook itms.*/ @@ -556,6 +568,11 @@ enum phydm_info_query { PHYDM_INFO_CLM_RATIO, PHYDM_INFO_NHM_RATIO, PHYDM_INFO_NHM_NOISE_PWR, + PHYDM_INFO_NHM_PWR, + PHYDM_INFO_NHM_ENV_RATIO, + PHYDM_INFO_TXEN_CCK, + PHYDM_INFO_TXEN_OFDM, + }; enum phydm_api { @@ -631,7 +648,6 @@ enum phydm_dbg_comp { DBG_PRI_CCA = BIT(F16_PRI_CCA), DBG_ADPTV_SOML = BIT(F17_ADPTV_SOML), DBG_LNA_SAT_CHK = BIT(F18_LNA_SAT_CHK), - /*BIT(19)*/ /*Neet to re-arrange*/ DBG_PHY_STATUS = BIT(20), DBG_TMP = BIT(21), @@ -639,7 +655,7 @@ enum phydm_dbg_comp { DBG_TXBF = BIT(23), DBG_COMMON_FLOW = BIT(24), DBG_COMP_MCC = BIT(25), - /*BIT(26)*/ + DBG_FW_DM = BIT(26), DBG_DM_SUMMARY = BIT(27), ODM_PHY_CONFIG = BIT(28), ODM_COMP_INIT = BIT(29), @@ -667,6 +683,11 @@ enum phydm_offload_ability { PHYDM_RF_DPK_OFFLOAD = BIT(2), }; +enum phydm_init_result { + PHYDM_INIT_SUCCESS = 0, + PHYDM_INIT_FAIL_BBRF_REG_INVALID = 1 +}; + struct phydm_pause_lv { s8 lv_dig; s8 lv_cckpd; @@ -687,6 +708,9 @@ struct pkt_process_info { u8 phy_ppdu_cnt; /*change with phy cca cnt*/ u8 page_bitmap_target; u8 page_bitmap_record; + u8 ppdu_phy_rate; + u8 ppdu_macid; + boolean is_1st_mpdu; #endif u8 lna_idx; u8 vga_idx; @@ -704,9 +728,13 @@ struct phydm_bt_info { struct phydm_iot_center { boolean is_linked_cmw500; - u8 win_patch_id; /*@Customer ID*/ - u32 phydm_patch_id; - + u8 win_patch_id; /*Customer ID*/ + boolean patch_id_100f0401; + boolean patch_id_10120200; + boolean patch_id_40010700; + boolean patch_id_021f0800; + boolean patch_id_011f0500; + u32 phydm_patch_id; /*temp for CCX IOT */ }; #if (RTL8822B_SUPPORT) @@ -736,7 +764,7 @@ struct _phydm_mcc_dm_ { }; #endif -#if (RTL8822C_SUPPORT || RTL8812F_SUPPORT || RTL8197G_SUPPORT) +#if (RTL8822C_SUPPORT || RTL8812F_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) struct phydm_physts { u8 cck_gi_u_bnd; u8 cck_gi_l_bnd; @@ -839,9 +867,23 @@ struct dm_struct { boolean is_download_fw; boolean en_dis_dpd; u16 dis_dpd_rate; + u8 en_auto_bw_th; + boolean is_pause_dig; #if (RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8197G_SUPPORT) u8 txagc_buff[RF_PATH_MEM_SIZE][PHY_NUM_RATE_IDX]; u32 bp_0x9b0; + #elif (RTL8723F_SUPPORT) + u8 txagc_buff[2][PHY_NUM_RATE_IDX]; + u32 bp_0x9b0; + #endif + #if (RTL8822C_SUPPORT || RTL8723F_SUPPORT) + u8 ofdm_rxagc_l_bnd[16]; + boolean l_bnd_detect[16]; + u16 agc_rf_gain_ori[16][64];/*[table][mp_gain_idx]*/ + u16 agc_rf_gain[16][64];/*[table][mp_gain_idx]*/ + u8 agc_table_cnt; + boolean is_agc_tab_pos_shift; + u8 agc_table_shift; #endif /*@-----------HOOK BEFORE REG INIT-----------*/ /*@===========================================================*/ @@ -882,6 +924,7 @@ struct dm_struct { u32 *interrupt_mask; u8 *bb_op_mode; u32 *manual_supportability; + u8 *dis_dym_bw_indication; /*@===========================================================*/ /*@====[ CALL BY VALUE ]===========================================*/ /*@===========================================================*/ @@ -949,6 +992,7 @@ struct dm_struct { u32 txagc_offset_value_b; boolean is_txagc_offset_positive_b; u8 ap_total_num; + boolean flatness_type; /*@[traffic]*/ u8 traffic_load; u8 pre_traffic_load; @@ -971,7 +1015,7 @@ struct dm_struct { u8 force_igi; /*@for debug*/ /*@[TDMA-DIG]*/ - u16 tdma_dig_timer_ms; + u8 tdma_dig_timer_ms; u8 tdma_dig_state_number; u8 tdma_dig_low_upper_bond; u8 force_tdma_low_igi; @@ -1039,13 +1083,17 @@ struct dm_struct { boolean en_reg_mntr_mac; boolean en_reg_mntr_byte; /*@--------------------------------------------------------------*/ -#if (RTL8814B_SUPPORT) - /*@--- for spur detection ---------------------------------------*/ +#if (RTL8814B_SUPPORT || RTL8812F_SUPPORT || RTL8198F_SUPPORT) u8 dsde_sel; u8 nbi_path_sel; u8 csi_wgt; - /*@------------------------------------------*/ #endif +#if (RTL8814B_SUPPORT || RTL8198F_SUPPORT) + u8 csi_wgt_th_db[5]; /*@wgt 4,3,2,1,0 */ + /* ^ ^ ^ ^ ^ */ +#endif + /*@------------------------------------------*/ + /*@--- for noise detection ---------------------------------------*/ boolean is_noisy_state; boolean noisy_decision; /*@b_noisy*/ @@ -1084,6 +1132,9 @@ struct dm_struct { /*@-----------------------------------------------------------*/ boolean bsomlenabled; /* @D-SoML control */ + u8 no_ndp_cnts; + u16 ndp_cnt_pre; + boolean is_beamformed; u8 linked_bf_support; boolean bhtstfdisabled; /* @dynamic HTSTF gain control*/ u32 n_iqk_cnt; @@ -1144,6 +1195,8 @@ struct dm_struct { u8 power_voltage; u8 cca_cbw20_lev; u8 cca_cbw40_lev; + u8 antdiv_gpio; + u8 peak_detect_mode; #endif /*@=== PHYDM Timer ========================================== (start)*/ @@ -1182,10 +1235,14 @@ struct dm_struct { struct pkt_process_info pkt_proc_struct; struct phydm_adaptivity_struct adaptivity; +#ifdef CONFIG_PHYDM_DFS_MASTER struct _DFS_STATISTICS dfs; +#endif struct odm_noise_monitor noise_level; struct odm_phy_dbg_info phy_dbg_info; - +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + struct odm_phy_dbg_info phy_dbg_info_win_bkp; +#endif #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT struct phydm_bf_rate_info_jgr3 bf_rate_info_jgr3; #endif @@ -1213,12 +1270,20 @@ struct dm_struct { struct dm_iqk_info IQK_info; struct dm_dpk_info dpk_info; struct dm_dack_info dack_info; - #ifdef CONFIG_PHYDM_ANTENNA_DIVERSITY struct phydm_fat_struct dm_fat_table; struct sw_antenna_switch dm_swat_table; #endif struct phydm_dig_struct dm_dig_table; + +#ifdef PHYDM_SUPPORT_CCKPD + struct phydm_cckpd_struct dm_cckpd_table; + + #ifdef PHYDM_DCC_ENHANCE + struct phydm_dcc_struct dm_dcc_info; /*dig cckpd coex*/ + #endif +#endif + #ifdef PHYDM_LNA_SAT_CHK_SUPPORT struct phydm_lna_sat_t dm_lna_sat_info; #endif @@ -1227,10 +1292,6 @@ struct dm_struct { struct _phydm_mcc_dm_ mcc_dm; #endif -#ifdef PHYDM_SUPPORT_CCKPD - struct phydm_cckpd_struct dm_cckpd_table; -#endif - #ifdef PHYDM_PRIMARY_CCA struct phydm_pricca_struct dm_pri_cca; #endif @@ -1295,7 +1356,7 @@ struct dm_struct { #endif /*@==========================================================*/ -#if (RTL8822C_SUPPORT || RTL8812F_SUPPORT || RTL8197G_SUPPORT) +#if (RTL8822C_SUPPORT || RTL8812F_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) /*@-------------------phydm_phystatus report --------------------*/ struct phydm_physts dm_physts_table; #endif @@ -1392,7 +1453,7 @@ phydm_txcurrentcalibration(struct dm_struct *dm); void phydm_dm_early_init(struct dm_struct *dm); -void +enum phydm_init_result odm_dm_init(struct dm_struct *dm); void @@ -1419,6 +1480,9 @@ phydm_watchdog(struct dm_struct *dm); void phydm_watchdog_mp(struct dm_struct *dm); +void +phydm_pause_func_init(void *dm_void); + u8 phydm_pause_func(void *dm_void, enum phydm_func_idx pause_func, enum phydm_pause_type pause_type, @@ -1431,6 +1495,9 @@ phydm_pause_func_console(void *dm_void, char input[][16], u32 *_used, void phydm_pause_dm_by_asso_pkt(struct dm_struct *dm, enum phydm_pause_type pause_type, u8 rssi); +void phydm_fw_dm_ctrl_en(void *dm_void, enum phydm_func_idx fun_idx, + boolean enable); + void odm_cmn_info_init(struct dm_struct *dm, enum odm_cmninfo cmn_info, u64 value); @@ -1461,6 +1528,21 @@ phydm_dc_cancellation(struct dm_struct *dm); void phydm_receiver_blocking(void *dm_void); +void +phydm_dyn_bw_indication(void *dm_void); + +void +phydm_iot_patch_id_update(void *dm_void, u32 iot_idx, boolean en); + + +#ifdef CONFIG_DYNAMIC_TXCOLLISION_TH +void +phydm_tx_collsion_th_init(void *dm_void); + +void +phydm_tx_collsion_th_set(void *dm_void, u8 val_r2t, u8 val_t2r); +#endif + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) void odm_init_all_work_items( diff --git a/hal/phydm/phydm.mk b/hal/phydm/phydm.mk index 686350c..c5d0ce9 100644 --- a/hal/phydm/phydm.mk +++ b/hal/phydm/phydm.mk @@ -180,6 +180,7 @@ _PHYDM_FILES += hal/phydm/$(RTL871X)/halhwimg8821c_bb.o \ hal/phydm/$(RTL871X)/halhwimg8821c_mac.o \ hal/phydm/$(RTL871X)/phydm_hal_api8821c.o \ hal/phydm/$(RTL871X)/phydm_regconfig8821c.o\ + hal/phydm/$(RTL871X)/phydm_rtl8821c.o\ hal/phydm/halrf/$(RTL871X)/halhwimg8821c_rf.o \ hal/phydm/halrf/$(RTL871X)/halrf_8821c.o\ hal/phydm/halrf/$(RTL871X)/halrf_iqk_8821c.o @@ -214,6 +215,7 @@ _PHYDM_FILES += hal/phydm/$(RTL871X)/halhwimg8822c_bb.o\ hal/phydm/halrf/$(RTL871X)/halrf_iqk_8822c.o\ hal/phydm/halrf/$(RTL871X)/halrf_tssi_8822c.o\ hal/phydm/halrf/$(RTL871X)/halrf_dpk_8822c.o\ + hal/phydm/halrf/$(RTL871X)/halrf_txgapk_8822c.o\ hal/phydm/halrf/$(RTL871X)/halrf_rfk_init_8822c.o\ hal/phydm/halrf/$(RTL871X)/halhwimg8822c_rf.o endif @@ -223,9 +225,25 @@ RTL871X = rtl8814b _PHYDM_FILES += hal/phydm/$(RTL871X)/halhwimg8814b_bb.o\ hal/phydm/$(RTL871X)/phydm_hal_api8814b.o\ hal/phydm/$(RTL871X)/phydm_regconfig8814b.o\ + hal/phydm/$(RTL871X)/phydm_extraagc8814b.o\ hal/phydm/halrf/$(RTL871X)/halhwimg8814b_rf.o\ hal/phydm/halrf/$(RTL871X)/halrf_8814b.o \ hal/phydm/halrf/$(RTL871X)/halrf_iqk_8814b.o \ hal/phydm/halrf/$(RTL871X)/halrf_dpk_8814b.o\ - hal/phydm/halrf/$(RTL871X)/halrf_rfk_init_8814b.o + hal/phydm/halrf/$(RTL871X)/halrf_rfk_init_8814b.o\ + hal/phydm/halrf/$(RTL871X)/halrf_txgapk_8814b.o +endif +ifeq ($(CONFIG_RTL8723F), y) +RTL871X = rtl8723f +_PHYDM_FILES += hal/phydm/$(RTL871X)/halhwimg8723f_bb.o\ + hal/phydm/$(RTL871X)/phydm_hal_api8723f.o\ + hal/phydm/$(RTL871X)/phydm_regconfig8723f.o\ + hal/phydm/$(RTL871X)/phydm_rtl8723f.o\ + hal/phydm/halrf/$(RTL871X)/halrf_8723f.o\ + hal/phydm/halrf/$(RTL871X)/halrf_iqk_8723f.o\ + hal/phydm/halrf/$(RTL871X)/halrf_tssi_8723f.o\ + hal/phydm/halrf/$(RTL871X)/halrf_dpk_8723f.o\ + hal/phydm/halrf/$(RTL871X)/halrf_txgapk_8723f.o\ + hal/phydm/halrf/$(RTL871X)/halrf_rfk_init_8723f.o\ + hal/phydm/halrf/$(RTL871X)/halhwimg8723f_rf.o endif \ No newline at end of file diff --git a/hal/phydm/phydm_adaptivity.c b/hal/phydm/phydm_adaptivity.c index 8746689..34622f9 100644 --- a/hal/phydm/phydm_adaptivity.c +++ b/hal/phydm/phydm_adaptivity.c @@ -146,6 +146,30 @@ void phydm_check_adaptivity(void *dm_void) *dm->edcca_mode = PHYDM_EDCCA_ADAPT_MODE; } +void phydm_set_l2h_th_ini_win(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + /*@ [New Format: JGR3]IGI-idx:45 = RSSI:35 = -65dBm*/ + if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8723F)) + dm->th_l2h_ini = 45; + else if (dm->support_ic_type & ODM_RTL8814B) + dm->th_l2h_ini = 49; + } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + /*@ [Old Format] -11+base(50) = IGI_idx:39 = RSSI:29 = -71dBm*/ + if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8812)) { + dm->th_l2h_ini = -17; + } else { + if (*dm->band_type == ODM_BAND_5G) + dm->th_l2h_ini = -14; + else if (*dm->band_type == ODM_BAND_2_4G) + dm->th_l2h_ini = -9; + } + } else { /*ODM_IC_11N_SERIES*/ + dm->th_l2h_ini = -9; + } +} #endif void phydm_dig_up_bound_lmt_en(void *dm_void) @@ -305,7 +329,7 @@ void phydm_set_l2h_th_ini(void *dm_void) /*@ [New Format: JGR3]IGI-idx:45 = RSSI:35 = -65dBm*/ if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - if (dm->support_ic_type & ODM_RTL8822C) + if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8723F)) dm->th_l2h_ini = 45; else if (dm->support_ic_type & ODM_RTL8814B) dm->th_l2h_ini = 49; @@ -374,10 +398,8 @@ void phydm_adaptivity_debug(void *dm_void, char input[][16], u32 *_used, s8 h2l_diff = 0; for (i = 0; i < 5; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &dm_value[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &dm_value[i]); + input_idx++; } if (strcmp(input[1], help) == 0) { PDM_SNPF(out_len, used, output + used, out_len - used, @@ -614,6 +636,9 @@ void phydm_adaptivity_info_init(void *dm_void, enum phydm_adapinfo cmn_info, case PHYDM_ADAPINFO_AP_NUM_TH: adaptivity->ap_num_th = (u8)value; break; + case PHYDM_ADAPINFO_SWITCH_TH_L2H_INI_IN_BAND: + adaptivity->switch_th_l2h_ini_in_band = (u8)value; + break; default: break; } @@ -654,7 +679,8 @@ void phydm_adaptivity_init(void *dm_void) #if (DM_ODM_SUPPORT_TYPE & ODM_WIN) if (!dm->carrier_sense_enable) { - if (dm->th_l2h_ini == 0) + if (dm->th_l2h_ini == 0 && + !adaptivity->switch_th_l2h_ini_in_band) phydm_set_l2h_th_ini(dm); } else { phydm_set_l2h_th_ini_carrier_sense(dm); @@ -777,6 +803,11 @@ void phydm_adaptivity(void *dm_void) #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) phydm_check_adaptivity(dm); /*@Check adaptivity enable*/ + + if (!dm->carrier_sense_enable && + !adapt->debug_mode && + adapt->switch_th_l2h_ini_in_band) + phydm_set_l2h_th_ini_win(dm); #endif PHYDM_DBG(dm, DBG_ADPTVTY, "%s ====>\n", __func__); diff --git a/hal/phydm/phydm_adaptivity.h b/hal/phydm/phydm_adaptivity.h index 45f7e8a..f125fb1 100644 --- a/hal/phydm/phydm_adaptivity.h +++ b/hal/phydm/phydm_adaptivity.h @@ -66,7 +66,8 @@ enum phydm_adapinfo { PHYDM_ADAPINFO_TH_EDCCA_HL_DIFF, PHYDM_ADAPINFO_AP_NUM_TH, PHYDM_ADAPINFO_DOMAIN_CODE_2G, - PHYDM_ADAPINFO_DOMAIN_CODE_5G + PHYDM_ADAPINFO_DOMAIN_CODE_5G, + PHYDM_ADAPINFO_SWITCH_TH_L2H_INI_IN_BAND }; enum phydm_mac_edcca_type { @@ -100,6 +101,7 @@ struct phydm_adaptivity_struct { s8 th_h2l; u8 regulation_2g; u8 regulation_5g; + u8 switch_th_l2h_ini_in_band; }; #ifdef PHYDM_SUPPORT_ADAPTIVITY diff --git a/hal/phydm/phydm_adc_sampling.c b/hal/phydm/phydm_adc_sampling.c index 2edd244..ace8a9d 100644 --- a/hal/phydm/phydm_adc_sampling.c +++ b/hal/phydm/phydm_adc_sampling.c @@ -135,6 +135,23 @@ phydm_la_clk_en(void *dm_void, boolean enable) } #endif +#if (RTL8723F_SUPPORT) +void +phydm_la_mac_clk_en(void *dm_void, boolean enable) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u8 val = (enable) ? 1 : 0; + + if (!(dm->support_ic_type & ODM_RTL8723F)) + return; + + odm_set_mac_reg(dm, R_0x1008, BIT(1), val); + /*Set IRAM2/3*/ + odm_set_mac_reg(dm, R_0x1000, 0xc0, 0x0); + odm_set_mac_reg(dm, R_0x1000, 0x3000, 0x3); +} +#endif + #if (RTL8197F_SUPPORT) void phydm_la_stop_dma_8197f(void *dm_void, enum phydm_backup_type opt) @@ -190,6 +207,70 @@ phydm_la_mv_data_2_tx_buffer(void *dm_void) } #endif + +#if(RTL8723F_SUPPORT) +void +phydm_la_mv_data_2_tx_buffer_rtl8723f(void *dm_void, u32 source, u32 dest, u32 length) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct rt_adcsmp *smp = &dm->adcsmp; + struct rt_adcsmp_string *buf = &smp->adc_smp_buf; + //u32 ch0ctrl = (BIT(29)|BIT(31)); + u32 ch0ctrl = BIT(31); + u32 cnt=25000; + + pr_debug("GetTxPktBuf from iMEM\n"); + /*Disable LA mode HW block*/ + odm_set_mac_reg(dm, R_0x7c0, BIT(0), 0x0); + + /* @move LA mode content from IMEM to TxPktBuffer + * Source : OCPBASE_IMEM 0x14040000 + * Destination : OCPBASE_TXBUF 0x18780000 + * Length : 32K + */ + /* + OCPBASE_IMEM = 0x18600000; + OCPBASE_TXBUF = 0x18780000; + GET_HAL_INTERFACE(dm->priv)->init_ddma_handler(dm->priv, + OCPBASE_IMEM, + OCPBASE_TXBUF + + buf->start_pos, + 0x8000); + */ + + // TODO: Replace all register define & bit define + + + //check if ddma ch0 is idle + while(odm_get_mac_reg(dm, R_0x1208 , BIT(31))){ + ODM_delay_ms(10); + cnt--; + if(cnt==0){ + pr_debug("1 InitDDMA88XX polling fail \n"); + return; + } + } + + ch0ctrl |= length & 0x3FFFF; + + //check if chksum continuous + //ch0ctrl |= BIT(24); + + odm_set_mac_reg(dm, R_0x1200, MASKDWORD, source); /*0x1200[31:0]:Source Address*/ + odm_set_mac_reg(dm, R_0x1204, MASKDWORD, dest); /*0x1204[31:0]:Destination Address*/ + odm_set_mac_reg(dm, R_0x1208, MASKDWORD, ch0ctrl); /*0x1208[17:0]:DMA Length*/ +//check if ddma ch0 is idle + while(odm_get_mac_reg(dm, R_0x1208 , BIT(31))){ + ODM_delay_ms(10); + cnt--; + if(cnt==0){ + pr_debug("2 InitDDMA88XX polling fail \n"); + return ; + } + } +} +#endif + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT void phydm_la_bb_adv_reset_jgr3(void *dm_void) @@ -822,6 +903,15 @@ void phydm_la_get_tx_pkt_buf(void *dm_void) boolean is_round_up = false; u32 addr_8byte = 0; u32 round_up_point = 0; + u32 index = 0; + u32 imem_base; + u32 txbuf_base; + u32 dma_len; + u32 imem_start_addr; + u32 imem_start_addr_offset; + u32 txbuff_start_addr; + u32 tx_buff_addr; + #if (RTL8814B_SUPPORT) boolean recover_success = true; #endif @@ -872,6 +962,69 @@ void phydm_la_get_tx_pkt_buf(void *dm_void) /*@==== [Get LA Patterns in TXFF] ====================================*/ pr_debug("Dump_Start\n"); +#if(RTL8723F_SUPPORT) + imem_base = 0x14040000; + txbuf_base = 0x18780000; + dma_len = 0x8000; + txbuff_start_addr = txbuf_base; + imem_start_addr_offset = addr; + if (is_round_up) { + for(index = 0;index < 4;index++) { + dma_len = 0x8000; + imem_start_addr= imem_base + (imem_start_addr_offset&0x1FFFF); + + if((imem_start_addr_offset + 0x8000) >= buf->end_pos) { + dma_len = buf->end_pos-imem_start_addr_offset; + + phydm_la_mv_data_2_tx_buffer_rtl8723f(dm, imem_start_addr, txbuff_start_addr, dma_len); + + tx_buff_addr = 0; + for (i = 0; i < (dma_len >> 3); i++) { + phydm_la_access_tx_pkt_buf(dm, tx_buff_addr, i << 1); + tx_buff_addr += 8; + } + imem_start_addr = imem_base; + dma_len = 0x8000-dma_len; + phydm_la_mv_data_2_tx_buffer_rtl8723f(dm, imem_start_addr, txbuff_start_addr, dma_len); + + tx_buff_addr = 0; + for (i = 0; i < (dma_len >> 3); i++) { + phydm_la_access_tx_pkt_buf(dm, tx_buff_addr, i << 1); + tx_buff_addr += 8; + } + imem_start_addr_offset = dma_len; + } + else { + dma_len = 0x8000; + phydm_la_mv_data_2_tx_buffer_rtl8723f(dm, imem_start_addr, txbuff_start_addr, dma_len); + + tx_buff_addr = 0; + for (i = 0; i <4096; i++) { + phydm_la_access_tx_pkt_buf(dm, tx_buff_addr, i << 1); + tx_buff_addr += 8; + } + imem_start_addr_offset += 0x8000; + } + } + } else { + for(index = 0; index < 4;index++) { + imem_start_addr = imem_base + (imem_start_addr_offset & 0x1FFFF); + if ((imem_start_addr_offset + 0x8000) > (finish_addr << 3)) + dma_len = (finish_addr << 3) - imem_start_addr_offset; /*0x1208[17:0]:DMA Length*/ + phydm_la_mv_data_2_tx_buffer_rtl8723f(dm,imem_start_addr, txbuff_start_addr, dma_len); + tx_buff_addr = 0; + for (i = 0; i < (dma_len >> 3); i++) { + phydm_la_access_tx_pkt_buf(dm, tx_buff_addr, i << 1); + tx_buff_addr += 8; + } + dma_len = 0x8000; + imem_start_addr_offset += 0x8000; + if (imem_start_addr_offset > (finish_addr << 3)) + break; + } + } +#else + #ifdef PHYDM_COMPILE_LA_STORE_IN_IMEM phydm_la_mv_data_2_tx_buffer(dm); #endif @@ -894,6 +1047,7 @@ void phydm_la_get_tx_pkt_buf(void *dm_void) #if (RTL8197F_SUPPORT) phydm_la_stop_dma_8197f(dm, PHYDM_RESTORE); #endif +#endif pr_debug("Dump_End\n"); } @@ -929,6 +1083,11 @@ void phydm_la_set_mac_iq_dump(void *dm_void, boolean impossible_trig_condi) /*@Enable LA mode HW block*/ odm_set_mac_reg(dm, reg1, BIT(0), 1); + #if (RTL8723F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8723F) + phydm_la_mac_clk_en(dm, true); + #endif + if (smp->la_trig_mode == PHYDM_MAC_TRIG) { smp->la_dump_mode = LA_MAC_DBG_DUMP; /*polling bit for MAC mode*/ @@ -1130,6 +1289,9 @@ void phydm_la_set_mac_trigger_time(void *dm_void, u32 trigger_time_mu_sec) unit = 5; /*unit: 32mu sec*/ else if (trigger_time_mu_sec < 8192) unit = 6; /*unit: 64mu sec*/ + else if (trigger_time_mu_sec < 16384) + if (dm->support_ic_type & ODM_RTL8723F) + unit = 7; /*unit: 128mu sec*/ time_unit_num = (u8)(trigger_time_mu_sec >> unit); @@ -1145,6 +1307,9 @@ void phydm_la_set_mac_trigger_time(void *dm_void, u32 trigger_time_mu_sec) odm_set_mac_reg(dm, R_0x7fc, BIT(2) | BIT(1) | BIT(0), unit); odm_set_mac_reg(dm, R_0x7f0, 0x7f00, (time_unit_num & 0x7f)); #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT + } else if (dm->support_ic_type & ODM_RTL8814B) { + odm_set_mac_reg(dm, R_0x7cc, BIT(20) | BIT(19) | BIT(18), unit); + odm_set_mac_reg(dm, R_0x7c0, 0x7f00, (time_unit_num & 0x7f)); } else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { odm_set_mac_reg(dm, R_0x7cc, BIT(18) | BIT(17) | BIT(16), unit); odm_set_mac_reg(dm, R_0x7c0, 0x7f00, (time_unit_num & 0x7f)); @@ -1203,6 +1368,10 @@ void phydm_la_set_buff_mode(void *dm_void, enum la_buff_mode mode) buff_size_base = 0x4000; end_pos_tmp = 0x8000; break; + case ODM_RTL8723F: + buff_size_base = 0x20000; + end_pos_tmp = 0x20000; + break; default: pr_debug("[%s] Warning!", __func__); break; @@ -1210,7 +1379,14 @@ void phydm_la_set_buff_mode(void *dm_void, enum la_buff_mode mode) buf->buffer_size = buff_size_base; - if (dm->support_ic_type & FULL_BUFF_MODE_SUPPORT) { + if (dm->support_ic_type & ODM_RTL8814B) { + if (mode == ADCSMP_BUFF_HALF) { + odm_set_mac_reg(dm, R_0x7cc, BIT(21), 0); + } else { + buf->buffer_size = buf->buffer_size << 1; + odm_set_mac_reg(dm, R_0x7cc, BIT(21), 1); + } + } else if (dm->support_ic_type & FULL_BUFF_MODE_SUPPORT) { if (mode == ADCSMP_BUFF_HALF) { odm_set_mac_reg(dm, R_0x7cc, BIT(30), 0); } else { @@ -1235,6 +1411,7 @@ void phydm_la_adc_smp_start(void *dm_void) u8 tmp_u1b = 0; u8 i = 0; u8 polling_bit = 0; + u8 bkp_val = 0; boolean polling_ok = false; boolean impossible_trig_condi = (smp->en_fake_trig) ? true : false; @@ -1248,6 +1425,9 @@ void phydm_la_adc_smp_start(void *dm_void) smp->la_trig_mode, smp->la_dbg_port, smp->la_trigger_edge, smp->la_smp_rate, smp->la_trig_sig_sel, smp->la_dma_type); + if(dm->support_ic_type & ODM_RTL8723F) + bkp_val = (u8)odm_get_mac_reg(dm, R_0x1008, BIT(1)); + phydm_la_set_mac_trigger_time(dm, smp->la_trigger_time); phydm_la_set_bb(dm); phydm_la_set_bb_dbg_port(dm, impossible_trig_condi); @@ -1323,6 +1503,10 @@ void phydm_la_adc_smp_start(void *dm_void) #if (RTL8821C_SUPPORT || RTL8195B_SUPPORT) phydm_la_clk_en(dm, false); #endif + #if (RTL8723F_SUPPORT) + if(dm->support_ic_type & ODM_RTL8723F) + phydm_la_mac_clk_en(dm, (bkp_val == 1) ? true : false); + #endif } else { smp->la_count--; pr_debug("LA Dump more ---------->\n\n\n"); @@ -1563,6 +1747,9 @@ void phydm_la_init(void *dm_void) struct rt_adcsmp *smp = &dm->adcsmp; struct rt_adcsmp_string *buf = &smp->adc_smp_buf; + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_LA_MODE)) + return; + smp->adc_smp_state = ADCSMP_STATE_IDLE; smp->is_la_print = true; smp->en_fake_trig = false; @@ -1578,6 +1765,9 @@ void adc_smp_de_init(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_LA_MODE)) + return; + phydm_la_stop(dm); phydm_la_buffer_release(dm); } @@ -1594,98 +1784,4 @@ void adc_smp_work_item_callback(void *context) phydm_la_adc_smp_start(dm); } #endif - -#if 0 -#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) -enum rt_status -adc_smp_query(void *dm_void, ULONG info_buf_length, void *info_buf, - PULONG bytes_written) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct rt_adcsmp *smp = &dm->adcsmp; - enum rt_status ret_status = RT_STATUS_SUCCESS; - struct rt_adcsmp_string *buf = &smp->adc_smp_buf; - - pr_debug("[%s] LA_State=((%d))", __func__, smp->adc_smp_state); - - if (info_buf_length != buf->buffer_size) { - *bytes_written = 0; - ret_status = RT_STATUS_RESOURCE; - } else if (buf->length != buf->buffer_size) { - *bytes_written = 0; - ret_status = RT_STATUS_RESOURCE; - } else if (smp->adc_smp_state != ADCSMP_STATE_QUERY) { - *bytes_written = 0; - ret_status = RT_STATUS_PENDING; - } else { - odm_move_memory(dm, info_buf, buf->octet, buf->buffer_size); - *bytes_written = buf->buffer_size; - - smp->adc_smp_state = ADCSMP_STATE_IDLE; - } - - pr_debug("Return status %d\n", ret_status); - - return ret_status; -} -#elif (DM_ODM_SUPPORT_TYPE & ODM_CE) - -void adc_smp_query(void *dm_void, void *output, u32 out_len, u32 *pused) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct rt_adcsmp *smp = &dm->adcsmp; - struct rt_adcsmp_string *buf = &smp->adc_smp_buf; - u32 used = *pused; - u32 i = 0; -#if 0 - /* struct timespec t; */ - /* rtw_get_current_timespec(&t); */ -#endif - - pr_debug("%s adc_smp_state %d", __func__, smp->adc_smp_state); - - for (i = 0; i < (buf->length >> 2) - 2; i += 2) { - PDM_SNPF(out_len, used, output + used, out_len - used, - "%08x%08x\n", buf->octet[i], buf->octet[i + 1]); - } - - PDM_SNPF(out_len, used, output + used, out_len - used, "\n"); - /* PDM_SNPF(output + used, out_len - used, "\n[%lu.%06lu]\n", */ - /* t.tv_sec, t.tv_nsec); */ - *pused = used; -} - -s32 adc_smp_get_sample_counts(void *dm_void) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct rt_adcsmp *smp = &dm->adcsmp; - struct rt_adcsmp_string *buf = &smp->adc_smp_buf; - - return (buf->length >> 2) - 2; -} - -s32 adc_smp_query_single_data(void *dm_void, void *output, u32 out_len, u32 idx) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct rt_adcsmp *smp = &dm->adcsmp; - struct rt_adcsmp_string *buf = &smp->adc_smp_buf; - u32 used = 0; - - /* @dbg_print("%s adc_smp_state %d\n", __func__,*/ - /* smp->adc_smp_state);*/ - if (smp->adc_smp_state != ADCSMP_STATE_QUERY) { - PDM_SNPF(out_len, used, output + used, out_len - used, - "Error: la data is not ready yet ...\n"); - return -1; - } - - if (idx < ((buf->length >> 2) - 2)) { - PDM_SNPF(out_len, used, output + used, out_len - used, - "%08x%08x\n", buf->octet[idx], buf->octet[idx + 1]); - } - return 0; -} -#endif -#endif - #endif /*@endif PHYDM_LA_MODE_SUPPORT*/ diff --git a/hal/phydm/phydm_adc_sampling.h b/hal/phydm/phydm_adc_sampling.h index cab4016..0e00e27 100644 --- a/hal/phydm/phydm_adc_sampling.h +++ b/hal/phydm/phydm_adc_sampling.h @@ -28,8 +28,8 @@ #if (PHYDM_LA_MODE_SUPPORT) -/* fix compile time flag*/ -#define DYNAMIC_LA_MODE "4.1" +/* 2020.07.03 [8723F] Fix SD4 compile error*/ +#define DYNAMIC_LA_MODE "4.2" /* @1 ============================================================ * 1 Definition @@ -168,22 +168,5 @@ void adc_smp_de_init(void *dm_void); #if (DM_ODM_SUPPORT_TYPE & ODM_WIN) void adc_smp_work_item_callback(void *context); #endif - -#if 0 -#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) -enum rt_status adc_smp_query(void *dm_void, ULONG info_buf_length, - void *info_buf, PULONG bytes_written); - -#elif (DM_ODM_SUPPORT_TYPE & ODM_CE) - -void adc_smp_query(void *dm_void, void *output, u32 out_len, u32 *pused); - -s32 adc_smp_get_sample_counts(void *dm_void); - -s32 adc_smp_query_single_data(void *dm_void, void *output, u32 out_len, - u32 idx); -#endif -#endif - #endif #endif diff --git a/hal/phydm/phydm_antdect.c b/hal/phydm/phydm_antdect.c index 5a44a05..a321389 100644 --- a/hal/phydm/phydm_antdect.c +++ b/hal/phydm/phydm_antdect.c @@ -190,9 +190,6 @@ odm_single_dual_antenna_detection( /* @change to Antenna B */ if (dm->support_ic_type & ODM_RTL8723B) { -#if 0 - /* odm_set_bb_reg(dm, REG_DPDT_CONTROL, 0x3, 0x2); */ -#endif odm_set_bb_reg(dm, REG_S0_S1_PATH_SWITCH, 0xfff, 0x280); odm_set_bb_reg(dm, REG_AGC_TABLE_SELECT, BIT(31), 0x1); } diff --git a/hal/phydm/phydm_antdiv.c b/hal/phydm/phydm_antdiv.c index 6325a61..3c2cc58 100644 --- a/hal/phydm/phydm_antdiv.c +++ b/hal/phydm/phydm_antdiv.c @@ -37,6 +37,114 @@ ***************************************************** */ #ifdef CONFIG_PHYDM_ANTENNA_DIVERSITY +#if (RTL8710C_SUPPORT == 1) +void odm_s0s1_sw_ant_div_init_8710c(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct sw_antenna_switch *swat_tab = &dm->dm_swat_table; + struct phydm_fat_struct *fat_tab = &dm->dm_fat_table; + + PHYDM_DBG(dm, DBG_ANT_DIV, + "***8710C AntDiv_Init => ant_div_type=[ S0S1_SW_AntDiv]\n"); + /*MAC setting*/ + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0xdc, HAL_READ32(SYSTEM_CTRL_BASE, R_0xdc) | BIT18 | BIT17 | BIT16); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0xac, HAL_READ32(SYSTEM_CTRL_BASE, R_0xac) | BIT24 | BIT6); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0x10, 0x307); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0x08, 0x80000111); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0x1208, 0x800000); + + /* Status init */ + fat_tab->is_become_linked = false; + swat_tab->try_flag = SWAW_STEP_INIT; + swat_tab->double_chk_flag = 0; + swat_tab->cur_antenna = MAIN_ANT; + swat_tab->pre_ant = MAIN_ANT; + dm->antdiv_counter = CONFIG_ANTDIV_PERIOD; +} + +void odm_trx_hw_ant_div_init_8710c(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + PHYDM_DBG(dm, DBG_ANT_DIV, + "[8710C] AntDiv_Init => ant_div_type=[CG_TRX_HW_ANTDIV]\n"); + odm_set_mac_reg(dm, R_0x74, BIT(13) | BIT(12), 1); + odm_set_mac_reg(dm, R_0x74, BIT(4), 1); + + /*@BT Coexistence*/ + /*@keep antsel_map when GNT_BT = 1*/ + odm_set_bb_reg(dm, R_0x864, BIT(12), 1); + + /* @Disable hw antsw & fast_train.antsw when GNT_BT=1 */ + odm_set_bb_reg(dm, R_0x874, BIT(23), 1); + odm_set_bb_reg(dm, R_0x930, 0xF00, 8); /* RFE CTRL_2 ANTSEL0 */ + + odm_set_bb_reg(dm, R_0x870, BIT(8), 0); + odm_set_bb_reg(dm, R_0x804, BIT(8), 0); /* r_keep_rfpin */ + + /*@Mapping Table*/ + //odm_set_bb_reg(dm, R_0x864, BIT2|BIT1|BIT0, 2); + odm_set_bb_reg(dm, R_0x944, 0xFFFF, 0xffff); + odm_set_bb_reg(dm, R_0x914, MASKBYTE0, 0); + odm_set_bb_reg(dm, R_0x914, MASKBYTE1, 1); + /*@antenna training */ + odm_set_bb_reg(dm, R_0xe08, BIT(16), 0); + + //need to check!!!!!!!!!! + /* Set WLBB_SEL_RF_ON 1 if RXFIR_PWDB > 0xCcc[3:0] */ + odm_set_bb_reg(dm, R_0xccc, BIT(12), 0); + /* @Low-to-High threshold for WLBB_SEL_RF_ON when OFDM enable */ + odm_set_bb_reg(dm, R_0xccc, 0x0F, 0x01); + /* @High-to-Low threshold for WLBB_SEL_RF_ON when OFDM enable */ + odm_set_bb_reg(dm, R_0xccc, 0xF0, 0x0); + /* @b Low-to-High threshold for WLBB_SEL_RF_ON when OFDM disable (CCK)*/ + odm_set_bb_reg(dm, R_0xabc, 0xFF, 0x06); + /* @High-to-Low threshold for WLBB_SEL_RF_ON when OFDM disable (CCK) */ + odm_set_bb_reg(dm, R_0xabc, 0xFF00, 0x00); + + /*OFDM HW AntDiv Parameters*/ + odm_set_bb_reg(dm, R_0xca4, 0x7FF, 0x80); + odm_set_bb_reg(dm, R_0xca4, 0x7FF000, 0x00); + odm_set_bb_reg(dm, R_0xc5c, BIT(20) | BIT(19) | BIT(18), 0x04); + + /*@CCK HW AntDiv Parameters*/ + odm_set_bb_reg(dm, R_0xa74, BIT(7), 1); + odm_set_bb_reg(dm, R_0xa0c, BIT(4), 1); + odm_set_bb_reg(dm, R_0xaa8, BIT(8), 0); + + odm_set_bb_reg(dm, R_0xa0c, 0x0F, 0xf); + odm_set_bb_reg(dm, R_0xa14, 0x1F, 0xf); + odm_set_bb_reg(dm, R_0xa10, BIT(13), 0x1); + odm_set_bb_reg(dm, R_0xa74, BIT(8), 0x0); + odm_set_bb_reg(dm, R_0xb34, BIT(30), 0x1); +} +void odm_update_rx_idle_ant_8710c(void *dm_void, u8 ant, u32 default_ant, + u32 optional_ant) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_fat_struct *fat_tab = &dm->dm_fat_table; + void *adapter = dm->adapter; + + PHYDM_DBG(dm, DBG_ANT_DIV, + "***odm_update_rx_idle_ant_8710c!!!\n"); + if (dm->ant_div_type == S0S1_SW_ANTDIV) { + if (default_ant == 0x0) + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0x1210,0x800000); + else + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0x1214,0x800000); + + fat_tab->rx_idle_ant = ant; + }else if (dm->ant_div_type == CG_TRX_HW_ANTDIV) { + odm_set_bb_reg(dm, R_0x864, BIT(5) | BIT(4) | BIT(3), default_ant); + /*@Default RX*/ + odm_set_bb_reg(dm, R_0x864, BIT(8) | BIT(7) | BIT(6), optional_ant); + /*@Optional RX*/ + odm_set_bb_reg(dm, R_0x860, BIT(14) | BIT(13) | BIT(12), default_ant); + /*@Default TX*/ + fat_tab->rx_idle_ant = ant; + } +} +#endif #if (RTL8721D_SUPPORT == 1) @@ -70,17 +178,94 @@ void odm_trx_hw_ant_div_init_8721d(void *dm_void) /* @Disable hw antsw & fast_train.antsw when BT TX/RX */ odm_set_bb_reg(dm, R_0xe64, 0xFFFF0000, 0x000c); - u32 sysreg408 = HAL_READ32(SYSTEM_CTRL_BASE_LP, 0x0408); + switch (dm->antdiv_gpio) { + case ANTDIV_GPIO_PA2PA4: { + PAD_CMD(_PA_2, ENABLE); + Pinmux_Config(_PA_2, PINMUX_FUNCTION_RFE); + PAD_CMD(_PA_4, ENABLE); + Pinmux_Config(_PA_4, PINMUX_FUNCTION_RFE); + break; + } + case ANTDIV_GPIO_PA5PA6: { + PAD_CMD(_PA_5, ENABLE); + Pinmux_Config(_PA_5, PINMUX_FUNCTION_RFE); + PAD_CMD(_PA_6, ENABLE); + Pinmux_Config(_PA_6, PINMUX_FUNCTION_RFE); + break; + } + case ANTDIV_GPIO_PA12PA13: { + PAD_CMD(_PA_12, ENABLE); + Pinmux_Config(_PA_12, PINMUX_FUNCTION_RFE); + PAD_CMD(_PA_13, ENABLE); + Pinmux_Config(_PA_13, PINMUX_FUNCTION_RFE); + break; + } + case ANTDIV_GPIO_PA14PA15: { + PAD_CMD(_PA_14, ENABLE); + Pinmux_Config(_PA_14, PINMUX_FUNCTION_RFE); + PAD_CMD(_PA_15, ENABLE); + Pinmux_Config(_PA_15, PINMUX_FUNCTION_RFE); + break; + } + case ANTDIV_GPIO_PA16PA17: { + PAD_CMD(_PA_16, ENABLE); + Pinmux_Config(_PA_16, PINMUX_FUNCTION_RFE); + PAD_CMD(_PA_17, ENABLE); + Pinmux_Config(_PA_17, PINMUX_FUNCTION_RFE); + break; + } + case ANTDIV_GPIO_PB1PB2: { + PAD_CMD(_PB_1, ENABLE); + Pinmux_Config(_PB_1, PINMUX_FUNCTION_RFE); + PAD_CMD(_PB_2, ENABLE); + Pinmux_Config(_PB_2, PINMUX_FUNCTION_RFE); + break; + } + case ANTDIV_GPIO_PB26PB29: { + PAD_CMD(_PB_26, ENABLE); + Pinmux_Config(_PB_26, PINMUX_FUNCTION_RFE); + PAD_CMD(_PB_29, ENABLE); + Pinmux_Config(_PB_29, PINMUX_FUNCTION_RFE); + break; + } + case ANTDIV_GPIO_PB1PB2PB26:{ + PAD_CMD(_PB_1, ENABLE); + Pinmux_Config(_PB_1, PINMUX_FUNCTION_RFE); + PAD_CMD(_PB_2, ENABLE); + Pinmux_Config(_PB_2, PINMUX_FUNCTION_RFE); + PAD_CMD(_PB_26, ENABLE); + Pinmux_Config(_PB_26, PINMUX_FUNCTION_RFE); + break; + } + default: { + } + } - sysreg408 &= ~0x0000001F; - sysreg408 |= 0x12; - HAL_WRITE32(SYSTEM_CTRL_BASE_LP, 0x0408, sysreg408); - - u32 sysreg410 = HAL_READ32(SYSTEM_CTRL_BASE_LP, 0x0410); - - sysreg410 &= ~0x0000001F; - sysreg410 |= 0x12; - HAL_WRITE32(SYSTEM_CTRL_BASE_LP, 0x0410, sysreg410); + if (dm->antdiv_gpio == ANTDIV_GPIO_PA12PA13 || + dm->antdiv_gpio == ANTDIV_GPIO_PA14PA15 || + dm->antdiv_gpio == ANTDIV_GPIO_PA16PA17 || + dm->antdiv_gpio == ANTDIV_GPIO_PB1PB2) { + /* ANT_SEL_P, ANT_SEL_N */ + odm_set_bb_reg(dm, R_0x930, 0xF, 8); + odm_set_bb_reg(dm, R_0x930, 0xF0, 8); + odm_set_bb_reg(dm, R_0x92c, BIT(1) | BIT(0), 2); + odm_set_bb_reg(dm, R_0x944, 0x00000003, 0x3); + } else if (dm->antdiv_gpio == ANTDIV_GPIO_PA2PA4 || + dm->antdiv_gpio == ANTDIV_GPIO_PA5PA6 || + dm->antdiv_gpio == ANTDIV_GPIO_PB26PB29) { + /* TRSW_P, TRSW_N */ + odm_set_bb_reg(dm, R_0x930, 0xF00, 8); + odm_set_bb_reg(dm, R_0x930, 0xF000, 8); + odm_set_bb_reg(dm, R_0x92c, BIT(3) | BIT(2), 2); + odm_set_bb_reg(dm, R_0x944, 0x0000000C, 0x3); + } + else if(dm->antdiv_gpio == ANTDIV_GPIO_PB1PB2PB26){ + /* 3 antenna diversity for AmebaD only */ + odm_set_bb_reg(dm, R_0x930, 0xF, 8); + odm_set_bb_reg(dm, R_0x930, 0xF0, 9); + odm_set_bb_reg(dm, R_0x930, 0xF00,0xa); /* set the RFE control table to select antenna*/ + odm_set_bb_reg(dm, R_0x944, 0x00000007, 0x7); + } u32 sysreg208 = HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_LP_FUNC_EN0); @@ -104,13 +289,8 @@ void odm_trx_hw_ant_div_init_8721d(void *dm_void) sysreg344 |= BIT(0); HAL_WRITE32(SYSTEM_CTRL_BASE_LP, REG_AUDIO_SHARE_PAD_CTRL, sysreg344); - odm_set_bb_reg(dm, R_0x930, 0xF00, 8); /* RFE CTRL_2 ANTSEL0 */ - odm_set_bb_reg(dm, R_0x930, 0xF000, 8); /* RFE CTRL_3 ANTSEL0 */ - odm_set_bb_reg(dm, R_0x92c, BIT(3) | BIT(2), 2); - odm_set_bb_reg(dm, R_0x870, BIT(9) | BIT(8), 0); odm_set_bb_reg(dm, R_0x804, 0xF00, 1); /* r_keep_rfpin */ - odm_set_bb_reg(dm, R_0x944, 0x0000000C, 0x3); /* PAD in/output CTRL */ /*PTA setting: WL_BB_SEL_BTG_TRXG_anta, (1: HW CTRL 0: SW CTRL)*/ /*odm_set_bb_reg(dm, R_0x948, BIT6, 0);*/ @@ -121,6 +301,11 @@ void odm_trx_hw_ant_div_init_8721d(void *dm_void) /*@Mapping Table*/ odm_set_bb_reg(dm, R_0x914, MASKBYTE0, 0); odm_set_bb_reg(dm, R_0x914, MASKBYTE1, 1); + if (dm->antdiv_gpio == ANTDIV_GPIO_PB1PB2PB26) { + odm_set_bb_reg(dm, R_0x914, 0x00000F, 0x1); + odm_set_bb_reg(dm, R_0x914, 0x000F00, 0x2); + odm_set_bb_reg(dm, R_0x914, 0x0F0000, 0x4); + } /* odm_set_bb_reg(dm, R_0x864, BIT5|BIT4|BIT3, 0); */ /* odm_set_bb_reg(dm, R_0x864, BIT8|BIT7|BIT6, 1); */ @@ -146,7 +331,7 @@ void odm_trx_hw_ant_div_init_8721d(void *dm_void) /*@CCK HW AntDiv Parameters*/ odm_set_bb_reg(dm, R_0xa74, BIT(7), 1); - odm_set_bb_reg(dm, R_0xa0c, BIT(4), 1); + odm_set_bb_reg(dm, R_0xa0c, BIT(4), 0); odm_set_bb_reg(dm, R_0xaa8, BIT(8), 0); odm_set_bb_reg(dm, R_0xa0c, 0x0F, 0xf); @@ -167,6 +352,9 @@ void odm_stop_antenna_switch_dm(void *dm_void) struct phydm_fat_struct *fat_tab = &dm->dm_fat_table; /* @disable ODM antenna diversity */ dm->support_ability &= ~ODM_BB_ANT_DIV; +#if (RTL8710C_SUPPORT == 1) + dm->support_ability |= ODM_BB_ANT_DIV; +#endif if (fat_tab->div_path_type == ANT_PATH_A) odm_ant_div_on_off(dm, ANTDIV_OFF, ANT_PATH_A); else if (fat_tab->div_path_type == ANT_PATH_B) @@ -290,7 +478,7 @@ void phydm_ac_on_off(void *dm_void, u8 swch, u8 path) odm_set_bb_reg(dm, R_0x800, BIT(25), swch); odm_set_bb_reg(dm, R_0xa00, BIT(15), swch); /* @CCK AntDiv function block enable */ - } else if (dm->support_ic_type == ODM_RTL8821C) { + } else { PHYDM_DBG(dm, DBG_ANT_DIV, "(Turn %s) CCK HW-AntDiv\n", (swch == ANTDIV_ON) ? "ON" : "OFF"); odm_set_bb_reg(dm, R_0x800, BIT(25), swch); @@ -300,6 +488,25 @@ void phydm_ac_on_off(void *dm_void, u8 swch, u8 path) } } +void phydm_jgr3_on_off(void *dm_void, u8 swch, u8 path) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_fat_struct *fat_tab = &dm->dm_fat_table; + + odm_set_bb_reg(dm, R_0x8a0, BIT(17), swch); + /* OFDM AntDiv function block enable */ + if (dm->support_ic_type & ODM_RTL8723F) { + odm_set_bb_reg(dm, R_0x1a48, BIT(16), swch); + /* @CCK AntDiv function block enable */ + } + else{ + odm_set_bb_reg(dm, R_0xa00, BIT(15), swch); + /* @CCK AntDiv function block enable */ + } + PHYDM_DBG(dm, DBG_ANT_DIV, + "[8723F] AntDiv_on\n"); +} + void odm_ant_div_on_off(void *dm_void, u8 swch, u8 path) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -320,6 +527,11 @@ void odm_ant_div_on_off(void *dm_void, u8 swch, u8 path) "(( Turn %s )) AC-Series HW-AntDiv block\n", (swch == ANTDIV_ON) ? "ON" : "OFF"); phydm_ac_on_off(dm, swch, path); + } else if (dm->support_ic_type & ODM_JGR3_ANTDIV_SUPPORT) { + PHYDM_DBG(dm, DBG_ANT_DIV, + "(( Turn %s )) JGR3 HW-AntDiv block\n", + (swch == ANTDIV_ON) ? "ON" : "OFF"); + phydm_jgr3_on_off(dm, swch, path); } } fat_tab->ant_div_on_off = swch; @@ -341,6 +553,8 @@ void odm_tx_by_tx_desc_or_reg(void *dm_void, u8 swch) odm_set_bb_reg(dm, R_0x80c, BIT(21), enable); else if (dm->support_ic_type & ODM_AC_ANTDIV_SUPPORT) odm_set_bb_reg(dm, R_0x900, BIT(18), enable); + else if (dm->support_ic_type & ODM_JGR3_ANTDIV_SUPPORT) + odm_set_bb_reg(dm, R_0x186c, BIT(1), enable); PHYDM_DBG(dm, DBG_ANT_DIV, "[AntDiv] TX_Ant_BY (( %s ))\n", (enable == TX_BY_DESC) ? "DESC" : "REG"); @@ -399,6 +613,12 @@ void phydm_keep_rx_ack_ant_by_tx_ant_time(void *dm_void, u32 time) odm_set_bb_reg(dm, R_0xe20, 0xf00000, time); else if (dm->support_ic_type & ODM_AC_ANTDIV_SUPPORT) odm_set_bb_reg(dm, R_0x818, 0xf00000, time); + if (dm->support_ic_type & ODM_RTL8723F) { + odm_set_bb_reg(dm, R_0x1c8c, 0xf00, time); + /* keep antenna index after tx */ + } + + } void phydm_update_rx_idle_ac(void *dm_void, u8 ant, u32 default_ant, @@ -462,6 +682,13 @@ void phydm_update_rx_idle_n(void *dm_void, u8 ant, u32 default_ant, odm_update_rx_idle_ant_8721d(dm, ant, default_ant, optional_ant); #endif + +#if (RTL8710C_SUPPORT == 1) + } else if (dm->support_ic_type == ODM_RTL8710C) { + odm_update_rx_idle_ant_8710c(dm, ant, default_ant, + optional_ant); +#endif + } else { /*@8188E & 8188F*/ /*@ if (dm->support_ic_type == ODM_RTL8723D) {*/ @@ -482,12 +709,30 @@ void phydm_update_rx_idle_n(void *dm_void, u8 ant, u32 default_ant, } } +void phydm_update_rx_idle_jgr3(void *dm_void, u8 ant, u32 default_ant, + u32 optional_ant, u32 default_tx_ant) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 value32; + + odm_set_bb_reg(dm, R_0x1884, 0xf0, default_ant);/*@Default RX*/ + odm_set_bb_reg(dm, R_0x1884, 0xf00, optional_ant); + /*Optional RX*/ + odm_set_bb_reg(dm, R_0x1884, 0xf000, default_tx_ant); + /*@Default TX*/ +} void odm_update_rx_idle_ant(void *dm_void, u8 ant) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_fat_struct *fat_tab = &dm->dm_fat_table; u32 default_ant, optional_ant, value32, default_tx_ant; - + if (dm->support_ic_type & ODM_JGR3_ANTDIV_SUPPORT) { + PHYDM_DBG(dm, DBG_ANT_DIV,"JGR3 HW-AntDiv block\n"); + } + else{ + PHYDM_DBG(dm, DBG_ANT_DIV,"not suppoty JGR3 HW-AntDiv block\n"); + PHYDM_DBG(dm, DBG_ANT_DIV,"dm->support_ic_type=%d\n",dm->support_ic_type); +} if (fat_tab->rx_idle_ant != ant) { PHYDM_DBG(dm, DBG_ANT_DIV, "[ Update Rx-Idle-ant ] rx_idle_ant =%s\n", @@ -516,13 +761,18 @@ void odm_update_rx_idle_ant(void *dm_void, u8 ant) } else if (dm->support_ic_type & ODM_AC_ANTDIV_SUPPORT) { phydm_update_rx_idle_ac(dm, ant, default_ant, optional_ant, default_tx_ant); + } else if (dm->support_ic_type & ODM_JGR3_ANTDIV_SUPPORT) { + phydm_update_rx_idle_jgr3(dm, ant, default_ant, + optional_ant, default_tx_ant); } /*PathA Resp Tx*/ if (dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8822B | - ODM_RTL8814A)) + ODM_RTL8814A | ODM_RTL8195B)) odm_set_mac_reg(dm, R_0x6d8, 0x7, default_tx_ant); else if (dm->support_ic_type == ODM_RTL8188E) odm_set_mac_reg(dm, R_0x6d8, 0xc0, default_tx_ant); + else if (dm->support_ic_type & ODM_JGR3_ANTDIV_SUPPORT) + odm_set_mac_reg(dm, R_0x6f8, 0xf, default_tx_ant); else odm_set_mac_reg(dm, R_0x6d8, 0x700, default_tx_ant); @@ -534,6 +784,43 @@ void odm_update_rx_idle_ant(void *dm_void, u8 ant) } } +#if (RTL8721D_SUPPORT) +void odm_update_rx_idle_ant_sp3t(void *dm_void, u8 ant) /* added by Jiao Qi on May.25,2020, for AmebaD SP3T only */ +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_fat_struct *fat_tab = &dm->dm_fat_table; + u32 default_ant, optional_ant, value32, default_tx_ant; + + if (!(dm->support_ic_type & ODM_RTL8723B)) + fat_tab->rx_idle_ant = ant; + + default_ant = fat_tab->ant_idx_vec[0]-1; + optional_ant = fat_tab->ant_idx_vec[1]-1; + + if(fat_tab->b_fix_tx_ant != NO_FIX_TX_ANT) + default_tx_ant = (fat_tab->b_fix_tx_ant == + FIX_TX_AT_MAIN) ? 0 : 1; + else + default_tx_ant = default_ant; + + odm_set_bb_reg(dm, R_0x864, BIT(5) | BIT(4) | BIT(3), default_ant); + /*@Default RX*/ + odm_set_bb_reg(dm, R_0x864, BIT(8) | BIT(7) | BIT(6), optional_ant); + /*@Optional RX*/ + odm_set_bb_reg(dm, R_0x860, BIT(14) | BIT(13) | BIT(12), default_ant); + /*@Default TX*/ + + /*PathA Resp Tx*/ + if (dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8822B | + ODM_RTL8814A)) + odm_set_mac_reg(dm, R_0x6d8, 0x7, default_tx_ant); + else if (dm->support_ic_type == ODM_RTL8188E) + odm_set_mac_reg(dm, R_0x6d8, 0xc0, default_tx_ant); + else + odm_set_mac_reg(dm, R_0x6d8, 0x700, default_tx_ant); + +} +#endif void phydm_update_rx_idle_ant_pathb(void *dm_void, u8 ant) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -580,6 +867,9 @@ void phydm_set_antdiv_val(void *dm_void, u32 *val_buf, u8 val_len) { struct dm_struct *dm = (struct dm_struct *)dm_void; + if (!(dm->support_ability & ODM_BB_ANT_DIV)) + return; + if (val_len != 1) { PHYDM_DBG(dm, ODM_COMP_API, "[Error][antdiv]Need val_len=1\n"); return; @@ -606,7 +896,16 @@ void odm_update_tx_ant(void *dm_void, u8 ant, u32 mac_id) else tx_ant = ANT2_2G; } - +#if (RTL8721D_SUPPORT) + if (dm->antdiv_gpio != ANTDIV_GPIO_PB1PB2PB26) { + if (ant == MAIN_ANT) + tx_ant = ANT1_2G; + else + tx_ant = ANT2_2G; + } + else + tx_ant = fat_tab->ant_idx_vec[0]-1; +#endif fat_tab->antsel_a[mac_id] = tx_ant & BIT(0); fat_tab->antsel_b[mac_id] = (tx_ant & BIT(1)) >> 1; fat_tab->antsel_c[mac_id] = (tx_ant & BIT(2)) >> 2; @@ -1583,6 +1882,82 @@ void phydm_rx_hw_ant_div_init_97f(void *dm_void) } #endif //#if (RTL8197F_SUPPORT == 1) +#if (RTL8197G_SUPPORT == 1) +void phydm_rx_hw_ant_div_init_97g(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_fat_struct *fat_tab = &dm->dm_fat_table; + + PHYDM_DBG(dm, DBG_ANT_DIV, "[%s]=====>\n", __func__); + + /* Pin Settings */ + odm_set_bb_reg(dm, R_0x1884, BIT(23), 0); + /* reg1844[23]=1'b0 *//*"CS/CG switching" is controlled by HWs*/ + odm_set_bb_reg(dm, R_0x1884, BIT(16), 1); + /* reg1844[16]=1'b1 *//*"antsel" is controlled by HWs*/ + + /* @Mapping table */ + odm_set_bb_reg(dm, R_0x1870, 0xFFFF, 0x0100); + /* @antenna mapping table */ + + /* OFDM Settings */ + odm_set_bb_reg(dm, R_0x1938, 0xFFE0, 0xA0); /* thershold */ + odm_set_bb_reg(dm, R_0x1938, 0x7FF0000, 0x0); /* @bias */ + + +#ifdef ODM_EVM_ENHANCE_ANTDIV + phydm_evm_sw_antdiv_init(dm); +#endif +} +#endif //#if (RTL8197F_SUPPORT == 1) + +#if (RTL8723F_SUPPORT == 1) +void phydm_rx_hw_ant_div_init_23f(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_fat_struct *fat_tab = &dm->dm_fat_table; + + PHYDM_DBG(dm, DBG_ANT_DIV, "[%s]=====>\n", __func__); + /* @3 --RFE pin setting--------- */ + /* @[MAC] */ + /* @gpioA_11,gpioA_12*/ + odm_set_mac_reg(dm, R_0x10d8, 0xFF000000, 0x16); + odm_set_mac_reg(dm, R_0x10dc, 0xFF, 0x16); + /* @[BB] */ + odm_set_bb_reg(dm, R_0x1c94, BIT(2) | BIT(3), 0x3); /* output enable */ + odm_set_bb_reg(dm, R_0x1ca0, BIT(2) | BIT(3), 0x0); + odm_set_bb_reg(dm, R_0x1c98, BIT(4) | BIT(5), 0x0); + /* r_rfe_path_sel_ (RFE_CTRL_2) */ + odm_set_bb_reg(dm, R_0x1c98, BIT(6) | BIT(7), 0x0); + /* r_rfe_path_sel_ (RFE_CTRL_3) */ + odm_set_bb_reg(dm, R_0x1838, BIT(28), 0); /* RFE_buffer_en */ + odm_set_bb_reg(dm, R_0x183c, BIT(2), 1); /* rfe_inv (RFE_CTRL_2) */ + odm_set_bb_reg(dm, R_0x183c, BIT(3), 0); /* rfe_inv (RFE_CTRL_3) */ + odm_set_bb_reg(dm, R_0x1840, 0xF00, 0x8); /* path-A, RFE_CTRL_2 */ + odm_set_bb_reg(dm, R_0x1840, 0xF000, 0x8); /* path-A, RFE_CTRL_3 */ + /* @3 ------------------------- */ + + /* Pin Settings */ + odm_set_bb_reg(dm, R_0x1884, BIT(23), 0); + odm_set_bb_reg(dm, R_0x1884, BIT(25), 0); + /* reg1844[23]=1'b0 *//*"CG switching" is controlled by HWs*/ + /* reg1844[25]=1'b0 *//*"CG switching" is controlled by HWs*/ + odm_set_bb_reg(dm, R_0x1884, BIT(16), 1); + /* reg1844[16]=1'b1 *//*"antsel" is controlled by HWs*/ + + /* @Mapping table */ + odm_set_bb_reg(dm, R_0x1870, 0xFFFF, 0x0100); + /* @antenna mapping table */ + + /* OFDM Settings */ + odm_set_bb_reg(dm, R_0x1938, 0xFFE0, 0xA0); /* thershold */ + odm_set_bb_reg(dm, R_0x1938, 0x7FF0000, 0x0); /* @bias */ +#ifdef ODM_EVM_ENHANCE_ANTDIV + phydm_evm_sw_antdiv_init(dm); +#endif +} +#endif //#if (RTL8723F_SUPPORT == 1) + #if (RTL8723D_SUPPORT == 1) void odm_trx_hw_ant_div_init_8723d(void *dm_void) { @@ -2192,6 +2567,55 @@ void phydm_s0s1_sw_ant_div_init_8821c(void *dm_void) } #endif /* @#if (RTL8821C_SUPPORT == 1) */ +#if (RTL8195B_SUPPORT == 1) +void odm_trx_hw_ant_div_init_8195b(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + PHYDM_DBG(dm, DBG_ANT_DIV, "[%s]=====>\n", __func__); + + odm_set_bb_reg(dm, R_0xcb8, BIT(16), 0); + /*RFE control pin 0,1*/ + odm_set_bb_reg(dm, R_0xcb0, 0xF, 8); /* @DPDT_P = ANTSEL[0] */ + odm_set_bb_reg(dm, R_0xcb0, 0xF0, 8); /* @DPDT_N = ANTSEL[0] */ + odm_set_bb_reg(dm, R_0xcb4, BIT(20), 0); /* @DPDT_P non-inverse */ + odm_set_bb_reg(dm, R_0xcb4, BIT(21), 1); /* @DPDT_N inverse */ + + /* @Mapping Table */ + odm_set_bb_reg(dm, R_0xca4, MASKBYTE0, 0); + odm_set_bb_reg(dm, R_0xca4, MASKBYTE1, 1); + + /* OFDM HW AntDiv Parameters */ + odm_set_bb_reg(dm, R_0x8d4, 0x7FF, 0xA0); /* thershold */ + odm_set_bb_reg(dm, R_0x8d4, 0x7FF000, 0x10); /* @bias */ + + /* @CCK HW AntDiv Parameters */ + odm_set_bb_reg(dm, R_0xa74, BIT(7), 1); + /* patch for clk from 88M to 80M */ + odm_set_bb_reg(dm, R_0xa0c, BIT(4), 1); /* @do 64 samples */ + + odm_set_bb_reg(dm, R_0x800, BIT(25), 0); + /* @ANTSEL_CCK sent to the smart_antenna circuit */ + odm_set_bb_reg(dm, R_0xa00, BIT(15), 0); + /* @CCK AntDiv function block enable */ + + /* @BT Coexistence */ + odm_set_bb_reg(dm, R_0xcac, BIT(9), 1); + /* @keep antsel_map when GNT_BT = 1 */ + odm_set_bb_reg(dm, R_0x804, BIT(4), 1); + /* @Disable hw antsw & fast_train.antsw when GNT_BT=1 */ + + /* Timming issue */ + odm_set_bb_reg(dm, R_0x818, BIT(23) | BIT(22) | BIT(21) | BIT(20), 0); + /*@keep antidx after tx for ACK ( unit x 3.2 mu sec)*/ + odm_set_bb_reg(dm, R_0x8cc, BIT(20) | BIT(19) | BIT(18), 3); + /* settling time of antdiv by RF LNA = 100ns */ + + /* response TX ant by RX ant */ + odm_set_mac_reg(dm, R_0x668, BIT(3), 1); +} +#endif /* @#if (RTL8195B_SUPPORT == 1) */ + #if (RTL8881A_SUPPORT == 1) void odm_trx_hw_ant_div_init_8881a(void *dm_void) { @@ -2437,7 +2861,8 @@ void phydm_evm_sw_antdiv_init(void *dm_void) dm->antdiv_intvl = 30; dm->antdiv_delay = 20; dm->antdiv_train_num = 4; - odm_set_bb_reg(dm, R_0x910, 0x3f, 0xf); + if (dm->support_ic_type & ODM_RTL8192E) + odm_set_bb_reg(dm, R_0x910, 0x3f, 0xf); dm->antdiv_evm_en = 1; /*@dm->antdiv_period=1;*/ #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) @@ -3089,7 +3514,7 @@ void odm_hw_ant_div(void *dm_void) target_ant = (mian_cnt == aux_cnt) ? fat_tab->rx_idle_ant : ((mian_cnt >= aux_cnt) ? - MAIN_ANT : AUX_ANT); + fat_tab->ant_idx_vec[0]:fat_tab->ant_idx_vec[1]); /*Use counter number for OFDM*/ } else { /*@CCK only case*/ @@ -3102,9 +3527,28 @@ void odm_hw_ant_div(void *dm_void) target_ant = (main_rssi == aux_rssi) ? fat_tab->rx_idle_ant : ((main_rssi >= aux_rssi) ? - MAIN_ANT : AUX_ANT); + fat_tab->ant_idx_vec[0]:fat_tab->ant_idx_vec[1]); /*Use RSSI for CCK only case*/ } +#if (RTL8721D_SUPPORT) + if(dm->antdiv_gpio == ANTDIV_GPIO_PB1PB2PB26) { /* added by Jiao Qi on May.25,2020, only for 3 antenna diversity */ + u8 tmp; + if(target_ant == fat_tab->ant_idx_vec[0]){/* switch the second & third ant index */ + tmp = fat_tab->ant_idx_vec[1]; + fat_tab->ant_idx_vec[1] = fat_tab->ant_idx_vec[2]; + fat_tab->ant_idx_vec[2] = tmp; + }else{ + /* switch the first & second ant index */ + tmp = fat_tab->ant_idx_vec[0]; + fat_tab->ant_idx_vec[0] = fat_tab->ant_idx_vec[1]; + fat_tab->ant_idx_vec[1] = tmp; + /* switch the second & third ant index */ + tmp = fat_tab->ant_idx_vec[1]; + fat_tab->ant_idx_vec[1] = fat_tab->ant_idx_vec[2]; + fat_tab->ant_idx_vec[2] = tmp; + } + } +#endif PHYDM_DBG(dm, DBG_ANT_DIV, "*** Client[ %d ] : Main_Cnt = (( %d )) , CCK_Main_Cnt = (( %d )) , main_rssi= (( %d ))\n", @@ -3244,7 +3688,13 @@ void odm_hw_ant_div(void *dm_void) #endif odm_update_rx_idle_ant(dm, rx_idle_ant); #else - +#if (RTL8721D_SUPPORT) +if (dm->antdiv_gpio == ANTDIV_GPIO_PB1PB2PB26) { + if(odm_get_bb_reg(dm,R_0xc50,0x80) || odm_get_bb_reg(dm, R_0xa00, 0x8000)) + odm_update_rx_idle_ant_sp3t(dm, rx_idle_ant); +} +else +#endif odm_update_rx_idle_ant(dm, rx_idle_ant); #endif /* @#if(DM_ODM_SUPPORT_TYPE == ODM_AP) */ @@ -3408,7 +3858,7 @@ void phydm_sw_antdiv_decision(void *dm_void) (fat_tab->main_sum[i] / main_cnt) : 0; aux_rssi = (aux_cnt != 0) ? (fat_tab->aux_sum[i] / aux_cnt) : 0; - if (dm->support_ic_type == ODM_RTL8723D) { + if (dm->support_ic_type == ODM_RTL8723D || dm->support_ic_type == ODM_RTL8710C) { cond_23d_main = (aux_cnt > main_cnt) && ((main_rssi - aux_rssi < 5) || (aux_rssi > main_rssi)); @@ -3678,6 +4128,24 @@ void odm_s0s1_sw_ant_div(void *dm_void, u8 step) PHYDM_DBG(dm, DBG_ANT_DIV, "8723D: First link! Force antenna to %s\n", (value32 == 0x0 ? "MAIN" : "AUX")); +#endif + } + if (dm->support_ic_type == ODM_RTL8710C) { +#if (RTL8710C_SUPPORT == 1) + value32 = (HAL_READ32(SYSTEM_CTRL_BASE, R_0x121c) & 0x800000); + if (value32 == 0x0) + odm_update_rx_idle_ant_8710c(dm, + MAIN_ANT, + ANT1_2G, + ANT2_2G); + else if (value32 == 0x1) + odm_update_rx_idle_ant_8710c(dm, + AUX_ANT, + ANT2_2G, + ANT1_2G); + PHYDM_DBG(dm, DBG_ANT_DIV, + "8710C: First link! Force antenna to %s\n", + (value32 == 0x0 ? "MAIN" : "AUX")); #endif } fat_tab->is_become_linked = dm->is_linked; @@ -3800,7 +4268,8 @@ void odm_s0s1_sw_ant_div(void *dm_void, u8 step) fat_tab->rx_idle_ant = next_ant; - if (dm->support_ic_type == ODM_RTL8723D) { + if (dm->support_ic_type == ODM_RTL8723D || dm->support_ic_type == ODM_RTL8710C) { + if (fat_tab->rx_idle_ant == MAIN_ANT) { fat_tab->main_sum[0] = 0; fat_tab->main_cnt[0] = 0; @@ -3903,6 +4372,14 @@ void odm_sw_antdiv_callback(void *function_context) #endif } +#elif (DM_ODM_SUPPORT_TYPE == ODM_IOT) +void odm_sw_antdiv_callback(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + PHYDM_DBG(dm, DBG_ANT_DIV, "******AntDiv_Callback******\n"); + odm_s0s1_sw_ant_div(dm, SWAW_STEP_DETERMINE); +} #endif void odm_s0s1_sw_ant_div_by_ctrl_frame(void *dm_void, u8 step) @@ -4298,7 +4775,7 @@ void odm_ant_div_init(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_fat_struct *fat_tab = &dm->dm_fat_table; struct sw_antenna_switch *swat_tab = &dm->dm_swat_table; - + u8 i; if (!(dm->support_ability & ODM_BB_ANT_DIV)) { PHYDM_DBG(dm, DBG_ANT_DIV, "[Return!!!] Not Support Antenna Diversity Function\n"); @@ -4329,6 +4806,10 @@ void odm_ant_div_init(void *dm_void) fat_tab->is_become_linked = false; fat_tab->ant_div_on_off = 0xff; + for(i=0;i<3;i++) + fat_tab->ant_idx_vec[i]=i+1; /* initialize ant_idx_vec for SP3T */ + + /* @3 - AP - */ #if (DM_ODM_SUPPORT_TYPE == ODM_AP) @@ -4342,6 +4823,8 @@ void odm_ant_div_init(void *dm_void) #elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) swat_tab->ant_5g = MAIN_ANT; swat_tab->ant_2g = MAIN_ANT; +//#elif (DM_ODM_SUPPORT_TYPE == ODM_IOT) +// swat_tab->ant_2g = MAIN_ANT; #endif /* @2 [---Set MAIN_ANT as default antenna if Auto-ant enable---] */ @@ -4355,7 +4838,30 @@ void odm_ant_div_init(void *dm_void) dm->ant_type = ODM_AUTO_ANT; fat_tab->rx_idle_ant = 0xff; - /*to make RX-idle-antenna will be updated absolutly*/ + + if (dm->support_ic_type == ODM_RTL8710C) { + /* Soft ware*/ +#if (RTL8710C_SUPPORT == 1) + if (dm->ant_div_type == S0S1_SW_ANTDIV) { + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0xdc, HAL_READ32(SYSTEM_CTRL_BASE, R_0xdc) | BIT18 | BIT17 | BIT16); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0xac, HAL_READ32(SYSTEM_CTRL_BASE, R_0xac) | BIT24 | BIT6); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0x10, 0x307);// 1: enable gpio db32 clock , 1: enable gpio pclock + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0x08, 0x80000111); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0x1208, 0x800000); + } else if (dm->ant_div_type == CG_TRX_HW_ANTDIV) { + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0xdc, HAL_READ32(SYSTEM_CTRL_BASE, R_0xdc) | BIT18 | BIT17); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0xdc, HAL_READ32(SYSTEM_CTRL_BASE, R_0xdc) & (~BIT16)); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0xac, HAL_READ32(SYSTEM_CTRL_BASE, R_0xac) | BIT24 | BIT6); + } else { + PHYDM_DBG(dm, DBG_ANT_DIV, + "[Return!!!] 8710C Not Supprrt This AntDiv type\n"); + dm->support_ability &= ~(ODM_BB_ANT_DIV); + return; + } +#endif + } + + /*to make RX-idle-antenna will be updated absolutly*/ odm_update_rx_idle_ant(dm, MAIN_ANT); phydm_keep_rx_ack_ant_by_tx_ant_time(dm, 0); /* Timming issue: keep Rx ant after tx for ACK(5 x 3.2 mu = 16mu sec)*/ @@ -4462,6 +4968,34 @@ void odm_ant_div_init(void *dm_void) phydm_rx_hw_ant_div_init_97f(dm); } #endif + +#if (RTL8197G_SUPPORT == 1) + else if (dm->support_ic_type == ODM_RTL8197G) { + dm->ant_div_type = CGCS_RX_HW_ANTDIV; + + if (dm->ant_div_type != CGCS_RX_HW_ANTDIV) { + PHYDM_DBG(dm, DBG_ANT_DIV, + "[Return!!!] 8197F Not Supprrt This AntDiv type\n"); + dm->support_ability &= ~(ODM_BB_ANT_DIV); + return; + } + phydm_rx_hw_ant_div_init_97g(dm); + } +#endif + +#if (RTL8723F_SUPPORT == 1) + else if (dm->support_ic_type == ODM_RTL8723F) { + dm->ant_div_type = CG_TRX_HW_ANTDIV; + + if (dm->ant_div_type != CG_TRX_HW_ANTDIV) { + PHYDM_DBG(dm, DBG_ANT_DIV, + "[Return!!!] 8723F Not Supprrt This AntDiv type\n"); + dm->support_ability &= ~(ODM_BB_ANT_DIV); + return; + } + phydm_rx_hw_ant_div_init_23f(dm); + } +#endif /* @2 [--8723B---] */ #if (RTL8723B_SUPPORT == 1) else if (dm->support_ic_type == ODM_RTL8723B) { @@ -4509,6 +5043,25 @@ void odm_ant_div_init(void *dm_void) } } #endif +#if (RTL8710C_SUPPORT == 1) + else if (dm->support_ic_type == ODM_RTL8710C) { + if (dm->ant_div_type == CG_TRX_HW_ANTDIV) + odm_trx_hw_ant_div_init_8710c(dm); + else if(dm->ant_div_type == S0S1_SW_ANTDIV){ + if (fat_tab->p_default_s0_s1 == NULL){ + fat_tab->default_s0_s1 = 1; + fat_tab->p_default_s0_s1 = &fat_tab->default_s0_s1; + } + PHYDM_DBG(dm, DBG_ANT_DIV, "default_s0_s1 = %d\n", + *fat_tab->p_default_s0_s1); + if (*fat_tab->p_default_s0_s1 == true) + odm_update_rx_idle_ant(dm, MAIN_ANT); + else + odm_update_rx_idle_ant(dm, AUX_ANT); + odm_s0s1_sw_ant_div_init_8710c(dm); + } + } +#endif #if (RTL8721D_SUPPORT == 1) else if (dm->support_ic_type == ODM_RTL8721D) { /* @dm->ant_div_type = CG_TRX_HW_ANTDIV; */ @@ -4571,6 +5124,20 @@ void odm_ant_div_init(void *dm_void) } #endif +/* @2 [--8195B---] */ +#if (RTL8195B_SUPPORT == 1) + else if (dm->support_ic_type == ODM_RTL8195B) { + dm->ant_div_type = CG_TRX_HW_ANTDIV; + if (dm->ant_div_type != CG_TRX_HW_ANTDIV) { + PHYDM_DBG(dm, DBG_ANT_DIV, + "[Return!!!] 8821C Not Supprrt This AntDiv type\n"); + dm->support_ability &= ~(ODM_BB_ANT_DIV); + return; + } + odm_trx_hw_ant_div_init_8195b(dm); + } +#endif + /* @2 [--8881A---] */ #if (RTL8881A_SUPPORT == 1) else if (dm->support_ic_type == ODM_RTL8881A) { @@ -4650,6 +5217,9 @@ void odm_ant_div(void *dm_void) struct smt_ant_honbo *sat_tab = &dm->dm_sat_table; #endif + if (!(dm->support_ability & ODM_BB_ANT_DIV)) + return; + #ifdef ODM_EVM_ENHANCE_ANTDIV if (dm->is_linked) { PHYDM_DBG(dm, DBG_ANT_DIV, @@ -4867,6 +5437,22 @@ void odm_ant_div(void *dm_void) } #endif +/*@ [--8197G--] */ +#if (RTL8197G_SUPPORT == 1) + else if (dm->support_ic_type == ODM_RTL8197G) { + if (dm->ant_div_type == CGCS_RX_HW_ANTDIV) + odm_hw_ant_div(dm); + } +#endif + +/*@ [--8723F--] */ +#if (RTL8723F_SUPPORT == 1) + else if (dm->support_ic_type == ODM_RTL8723F) { + if (dm->ant_div_type == CG_TRX_HW_ANTDIV) + odm_hw_ant_div(dm); + } +#endif + #if (RTL8723B_SUPPORT == 1) /*@ [--8723B---] */ else if (dm->support_ic_type == ODM_RTL8723B) { @@ -4917,6 +5503,24 @@ void odm_ant_div(void *dm_void) } } #endif +#if (RTL8710C_SUPPORT == 1) + else if (dm->support_ic_type == ODM_RTL8710C) { + if (dm->ant_div_type == S0S1_SW_ANTDIV) { + #ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY + if (dm->antdiv_counter == CONFIG_ANTDIV_PERIOD) { + odm_s0s1_sw_ant_div(dm, SWAW_STEP_PEEK); + dm->antdiv_counter--; + } else { + dm->antdiv_counter--; + } + if (dm->antdiv_counter == 0) + dm->antdiv_counter = CONFIG_ANTDIV_PERIOD; + #endif + } else if (dm->ant_div_type == CG_TRX_HW_ANTDIV) { + odm_hw_ant_div(dm); + } + } +#endif /*@ [--8821A--] */ #if (RTL8821A_SUPPORT == 1) else if (dm->support_ic_type == ODM_RTL8821) { @@ -5002,6 +5606,15 @@ void odm_ant_div(void *dm_void) } #endif +/* @ [--8195B--] */ +#if (RTL8195B_SUPPORT == 1) + else if (dm->support_ic_type == ODM_RTL8195B) { + if (dm->ant_div_type == CG_TRX_HW_ANTDIV) { + odm_hw_ant_div(dm); + } + } +#endif + /* @ [--8881A--] */ #if (RTL8881A_SUPPORT == 1) else if (dm->support_ic_type == ODM_RTL8881A) @@ -5054,7 +5667,7 @@ void odm_antsel_statistics(void *dm_void, void *phy_info_void, if (method == RSSI_METHOD) { if (is_cck_rate) { - if (antsel_tr_mux == ANT1_2G) { + if (antsel_tr_mux == fat_tab->ant_idx_vec[0]-1) { /*to prevent u16 overflow, max(RSSI)=100, 65435+100 = 65535 (u16)*/ if (fat_tab->main_sum_cck[mac_id] > 65435) return; @@ -5071,7 +5684,7 @@ void odm_antsel_statistics(void *dm_void, void *phy_info_void, } else { /*ofdm rate*/ - if (antsel_tr_mux == ANT1_2G) { + if (antsel_tr_mux == fat_tab->ant_idx_vec[0]-1) { if (fat_tab->main_sum[mac_id] > 65435) return; @@ -5171,7 +5784,7 @@ void odm_process_rssi_normal(void *dm_void, void *phy_info_void, if (dm->ant_div_type == S0S1_SW_ANTDIV) { if (pktinfo->is_cck_rate || - dm->support_ic_type == ODM_RTL8188F) { + dm->support_ic_type == ODM_RTL8188F || dm->support_ic_type == ODM_RTL8710C) { b_main = (fat_tab->rx_idle_ant == MAIN_ANT); fat_tab->antsel_rx_keep_0 = b_main ? ANT1_2G : ANT2_2G; @@ -5195,8 +5808,8 @@ void odm_process_rssi_normal(void *dm_void, void *phy_info_void, pktinfo->station_id, rx_evm0, EVM_METHOD, pktinfo->is_cck_rate); odm_antsel_statistics(dm, phy_info, fat_tab->antsel_rx_keep_0, - pktinfo->station_id, rx_evm0, TP_METHOD, - pktinfo->is_cck_rate); + pktinfo->station_id, pktinfo->data_rate, + TP_METHOD, pktinfo->is_cck_rate); #endif } } @@ -5472,6 +6085,10 @@ void odm_set_tx_ant_by_tx_info(void *dm_void, u8 *desc, u8 mac_id) * mac_id, fat_tab->antsel_c[mac_id], fat_tab->antsel_b[mac_id], * fat_tab->antsel_a[mac_id]); */ +#endif + } else if (dm->support_ic_type == ODM_RTL8195B) { +#if (RTL8195B_SUPPORT == 1) + SET_TX_DESC_ANTSEL_A_8195B(desc, fat_tab->antsel_a[mac_id]); #endif } else if (dm->support_ic_type == ODM_RTL8822B) { #if (RTL8822B_SUPPORT == 1) @@ -5618,6 +6235,12 @@ void odm_ant_div_config(void *dm_void) if (dm->support_ic_type == ODM_RTL8721D) dm->ant_div_type = CG_TRX_HW_ANTDIV; + if (dm->support_ic_type == ODM_RTL8710C){ + if(dm->cut_version > ODM_CUT_C) + dm->ant_div_type = CG_TRX_HW_ANTDIV; + else + dm->ant_div_type = S0S1_SW_ANTDIV; + } #elif (DM_ODM_SUPPORT_TYPE & (ODM_AP)) @@ -5638,45 +6261,45 @@ void odm_ant_div_config(void *dm_void) if (dm->support_ic_type & ODM_ANTDIV_SUPPORT) dm->support_ability |= ODM_BB_ANT_DIV; if (*dm->band_type == ODM_BAND_5G) { -#if (defined(CONFIG_5G_CGCS_RX_DIVERSITY)) + #if (defined(CONFIG_5G_CGCS_RX_DIVERSITY)) dm->ant_div_type = CGCS_RX_HW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 5G] : AntDiv type = CGCS_RX_HW_ANTDIV\n"); panic_printk("[ 5G] : AntDiv type = CGCS_RX_HW_ANTDIV\n"); -#elif (defined(CONFIG_5G_CG_TRX_DIVERSITY) ||\ - defined(CONFIG_2G5G_CG_TRX_DIVERSITY_8881A)) + #elif (defined(CONFIG_5G_CG_TRX_DIVERSITY) ||\ + defined(CONFIG_2G5G_CG_TRX_DIVERSITY_8881A)) dm->ant_div_type = CG_TRX_HW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 5G] : AntDiv type = CG_TRX_HW_ANTDIV\n"); panic_printk("[ 5G] : AntDiv type = CG_TRX_HW_ANTDIV\n"); -#elif (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) + #elif (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) dm->ant_div_type = CG_TRX_SMART_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 5G] : AntDiv type = CG_SMART_ANTDIV\n"); -#elif (defined(CONFIG_5G_S0S1_SW_ANT_DIVERSITY)) + #elif (defined(CONFIG_5G_S0S1_SW_ANT_DIVERSITY)) dm->ant_div_type = S0S1_SW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 5G] : AntDiv type = S0S1_SW_ANTDIV\n"); -#endif + #endif } else if (*dm->band_type == ODM_BAND_2_4G) { -#if (defined(CONFIG_2G_CGCS_RX_DIVERSITY)) + #if (defined(CONFIG_2G_CGCS_RX_DIVERSITY)) dm->ant_div_type = CGCS_RX_HW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 2.4G] : AntDiv type = CGCS_RX_HW_ANTDIV\n"); -#elif (defined(CONFIG_2G_CG_TRX_DIVERSITY) ||\ - defined(CONFIG_2G5G_CG_TRX_DIVERSITY_8881A)) + #elif (defined(CONFIG_2G_CG_TRX_DIVERSITY) ||\ + defined(CONFIG_2G5G_CG_TRX_DIVERSITY_8881A)) dm->ant_div_type = CG_TRX_HW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 2.4G] : AntDiv type = CG_TRX_HW_ANTDIV\n"); -#elif (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY)) + #elif (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY)) dm->ant_div_type = CG_TRX_SMART_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 2.4G] : AntDiv type = CG_SMART_ANTDIV\n"); -#elif (defined(CONFIG_2G_S0S1_SW_ANT_DIVERSITY)) + #elif (defined(CONFIG_2G_S0S1_SW_ANT_DIVERSITY)) dm->ant_div_type = S0S1_SW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 2.4G] : AntDiv type = S0S1_SW_ANTDIV\n"); -#endif + #endif } /* @2 [ 5G_SUPPORT_ANTDIV ] */ @@ -5688,25 +6311,25 @@ void odm_ant_div_config(void *dm_void) if (*dm->band_type == ODM_BAND_5G) { if (dm->support_ic_type & ODM_ANTDIV_5G_SUPPORT_IC) dm->support_ability |= ODM_BB_ANT_DIV; -#if (defined(CONFIG_5G_CGCS_RX_DIVERSITY)) + #if (defined(CONFIG_5G_CGCS_RX_DIVERSITY)) dm->ant_div_type = CGCS_RX_HW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 5G] : AntDiv type = CGCS_RX_HW_ANTDIV\n"); panic_printk("[ 5G] : AntDiv type = CGCS_RX_HW_ANTDIV\n"); -#elif (defined(CONFIG_5G_CG_TRX_DIVERSITY)) + #elif (defined(CONFIG_5G_CG_TRX_DIVERSITY)) dm->ant_div_type = CG_TRX_HW_ANTDIV; panic_printk("[ 5G] : AntDiv type = CG_TRX_HW_ANTDIV\n"); PHYDM_DBG(dm, DBG_ANT_DIV, "[ 5G] : AntDiv type = CG_TRX_HW_ANTDIV\n"); -#elif (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) + #elif (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) dm->ant_div_type = CG_TRX_SMART_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 5G] : AntDiv type = CG_SMART_ANTDIV\n"); -#elif (defined(CONFIG_5G_S0S1_SW_ANT_DIVERSITY)) + #elif (defined(CONFIG_5G_S0S1_SW_ANT_DIVERSITY)) dm->ant_div_type = S0S1_SW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 5G] : AntDiv type = S0S1_SW_ANTDIV\n"); -#endif + #endif } else if (*dm->band_type == ODM_BAND_2_4G) { PHYDM_DBG(dm, DBG_ANT_DIV, "Not Support 2G ant_div_type\n"); dm->support_ability &= ~(ODM_BB_ANT_DIV); @@ -5720,28 +6343,33 @@ void odm_ant_div_config(void *dm_void) if (*dm->band_type == ODM_BAND_2_4G) { if (dm->support_ic_type & ODM_ANTDIV_2G_SUPPORT_IC) dm->support_ability |= ODM_BB_ANT_DIV; -#if (defined(CONFIG_2G_CGCS_RX_DIVERSITY)) + #if (defined(CONFIG_2G_CGCS_RX_DIVERSITY)) dm->ant_div_type = CGCS_RX_HW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 2.4G] : AntDiv type = CGCS_RX_HW_ANTDIV\n"); -#elif (defined(CONFIG_2G_CG_TRX_DIVERSITY)) + #elif (defined(CONFIG_2G_CG_TRX_DIVERSITY)) dm->ant_div_type = CG_TRX_HW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 2.4G] : AntDiv type = CG_TRX_HW_ANTDIV\n"); -#elif (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY)) + #elif (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY)) dm->ant_div_type = CG_TRX_SMART_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 2.4G] : AntDiv type = CG_SMART_ANTDIV\n"); -#elif (defined(CONFIG_2G_S0S1_SW_ANT_DIVERSITY)) + #elif (defined(CONFIG_2G_S0S1_SW_ANT_DIVERSITY)) dm->ant_div_type = S0S1_SW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 2.4G] : AntDiv type = S0S1_SW_ANTDIV\n"); -#endif + #endif } else if (*dm->band_type == ODM_BAND_5G) { PHYDM_DBG(dm, DBG_ANT_DIV, "Not Support 5G ant_div_type\n"); dm->support_ability &= ~(ODM_BB_ANT_DIV); } #endif + + if (!(dm->support_ic_type & ODM_ANTDIV_SUPPORT_IC)) { + fat_tab->ant_div_2g_5g = 0; + dm->support_ability &= ~(ODM_BB_ANT_DIV); + } #endif PHYDM_DBG(dm, DBG_ANT_DIV, @@ -5839,10 +6467,20 @@ void phydm_antdiv_debug(void *dm_void, char input[][16], u32 *_used, "AntDiv: Auto\n"); } else if (dm_value[1] == 1) { dm->ant_type = ODM_FIX_MAIN_ANT; + + #if (RTL8710C_SUPPORT == 1) + dm->antdiv_select = 1; + #endif + PDM_SNPF(out_len, used, output + used, out_len - used, "AntDiv: Fix Main\n"); } else if (dm_value[1] == 2) { dm->ant_type = ODM_FIX_AUX_ANT; + + #if (RTL8710C_SUPPORT == 1) + dm->antdiv_select = 2; + #endif + PDM_SNPF(out_len, used, output + used, out_len - used, "AntDiv: Fix Aux\n"); } @@ -5961,6 +6599,9 @@ void odm_ant_div_reset(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; + if (!(dm->support_ability & ODM_BB_ANT_DIV)) + return; + #ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY if (dm->ant_div_type == S0S1_SW_ANTDIV) odm_s0s1_sw_ant_div_reset(dm); @@ -5997,4 +6638,3 @@ void odm_antenna_diversity(void *dm_void) odm_ant_div(dm); } #endif /*@#ifdef CONFIG_PHYDM_ANTENNA_DIVERSITY*/ - diff --git a/hal/phydm/phydm_antdiv.h b/hal/phydm/phydm_antdiv.h index fe4c94b..0de588d 100644 --- a/hal/phydm/phydm_antdiv.h +++ b/hal/phydm/phydm_antdiv.h @@ -84,20 +84,26 @@ #define ODM_N_ANTDIV_SUPPORT (ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8723B |\ ODM_RTL8188F | ODM_RTL8723D | ODM_RTL8195A |\ - ODM_RTL8197F | ODM_RTL8721D) + ODM_RTL8197F | ODM_RTL8721D | ODM_RTL8710C) #define ODM_AC_ANTDIV_SUPPORT (ODM_RTL8821 | ODM_RTL8881A | ODM_RTL8812 |\ - ODM_RTL8821C | ODM_RTL8822B | ODM_RTL8814B) -#define ODM_ANTDIV_SUPPORT (ODM_N_ANTDIV_SUPPORT | ODM_AC_ANTDIV_SUPPORT) + ODM_RTL8821C | ODM_RTL8822B | ODM_RTL8814B |\ + ODM_RTL8195B) +#define ODM_JGR3_ANTDIV_SUPPORT (ODM_RTL8197G | ODM_RTL8723F) +#define ODM_ANTDIV_SUPPORT (ODM_N_ANTDIV_SUPPORT | ODM_AC_ANTDIV_SUPPORT |\ + ODM_JGR3_ANTDIV_SUPPORT) #define ODM_SMART_ANT_SUPPORT (ODM_RTL8188E | ODM_RTL8192E) #define ODM_HL_SMART_ANT_TYPE1_SUPPORT (ODM_RTL8821 | ODM_RTL8822B) #define ODM_ANTDIV_2G_SUPPORT_IC (ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8723B |\ ODM_RTL8881A | ODM_RTL8188F | ODM_RTL8723D |\ - ODM_RTL8197F) + ODM_RTL8197F | ODM_RTL8197G|ODM_RTL8723F) #define ODM_ANTDIV_5G_SUPPORT_IC (ODM_RTL8821 | ODM_RTL8881A | ODM_RTL8812 |\ - ODM_RTL8821C | ODM_RTL8822B) + ODM_RTL8821C | ODM_RTL8822B | ODM_RTL8195B|ODM_RTL8723F) -#define ODM_EVM_ANTDIV_IC (ODM_RTL8192E | ODM_RTL8197F | ODM_RTL8822B) +#define ODM_ANTDIV_SUPPORT_IC (ODM_ANTDIV_2G_SUPPORT_IC | ODM_ANTDIV_5G_SUPPORT_IC) + +#define ODM_EVM_ANTDIV_IC (ODM_RTL8192E | ODM_RTL8197F | ODM_RTL8822B |\ + ODM_RTL8197G) #define ODM_ANTDIV_2G BIT(0) #define ODM_ANTDIV_5G BIT(1) @@ -168,7 +174,7 @@ /*@Hong Lin Smart antenna*/ #define HL_SMTANT_2WIRE_DATA_LEN 24 -#if (RTL8723D_SUPPORT == 1) +#if (RTL8723D_SUPPORT == 1 || RTL8710C_SUPPORT == 1) #ifndef CONFIG_ANTDIV_PERIOD #define CONFIG_ANTDIV_PERIOD 1 #endif @@ -324,7 +330,7 @@ struct phydm_fat_struct { u8 pre_antdiv_rssi; u8 pre_antdiv_tp; #endif -#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE | ODM_IOT)) u32 cck_ctrl_frame_cnt_main; u32 cck_ctrl_frame_cnt_aux; u32 ofdm_ctrl_frame_cnt_main; @@ -334,6 +340,7 @@ struct phydm_fat_struct { u32 main_ctrl_cnt; u32 aux_ctrl_cnt; #endif + u8 b_fix_tx_ant; boolean fix_ant_bfee; boolean enable_ctrl_frame_antdiv; @@ -347,6 +354,9 @@ struct phydm_fat_struct { /*@A temp value, will hook to driver team's outer parameter later*/ u8 *p_default_s0_s1; u8 default_s0_s1; + u8 ant_idx_vec[3]; /* for SP3T only, added by Jiao Qi on June.6,2020*/ + + }; /* @1 ============================================================ @@ -404,6 +414,8 @@ void phydm_antdiv_reset_statistic(void *dm_void, u32 macid); void odm_update_rx_idle_ant(void *dm_void, u8 ant); +void odm_update_rx_idle_ant_sp3t(void *dm_void, u8 ant); + void phydm_update_rx_idle_ant_pathb(void *dm_void, u8 ant); void phydm_set_antdiv_val(void *dm_void, u32 *val_buf, u8 val_len); @@ -439,6 +451,10 @@ void odm_sw_antdiv_workitem_callback(void *context); void odm_sw_antdiv_callback(void *function_context); +#elif (DM_ODM_SUPPORT_TYPE == ODM_IOT) + +void odm_sw_antdiv_callback(void *dm_void); + #endif void odm_s0s1_sw_ant_div_by_ctrl_frame(void *dm_void, u8 step); diff --git a/hal/phydm/phydm_api.c b/hal/phydm/phydm_api.c index e6ad43c..4daaa5b 100644 --- a/hal/phydm/phydm_api.c +++ b/hal/phydm/phydm_api.c @@ -31,12 +31,36 @@ #include "mp_precomp.h" #include "phydm_precomp.h" +enum channel_width phydm_rxsc_2_bw(void *dm_void, u8 rxsc) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + enum channel_width bw = 0; + + /* @Check RX bandwidth */ + if (rxsc == 0) + bw = *dm->band_width; /*@full bw*/ + else if (rxsc >= 1 && rxsc <= 8) + bw = CHANNEL_WIDTH_20; + else if (rxsc >= 9 && rxsc <= 12) + bw = CHANNEL_WIDTH_40; + else /*if (rxsc >= 13)*/ + bw = CHANNEL_WIDTH_80; + + return bw; +} + void phydm_reset_bb_hw_cnt(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; /*@ Reset all counter when 1 */ if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + #if (RTL8723F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8723F) { + odm_set_bb_reg(dm, R_0x2a44, BIT(21), 0); + odm_set_bb_reg(dm, R_0x2a44, BIT(21), 1); + } + #endif odm_set_bb_reg(dm, R_0x1eb4, BIT(25), 1); odm_set_bb_reg(dm, R_0x1eb4, BIT(25), 0); } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { @@ -83,6 +107,11 @@ void phydm_ant_weight_dbg(void *dm_void, char input[][16], u32 *_used, u32 used = *_used; u32 out_len = *_out_len; + if (!(dm->support_ic_type & + (ODM_RTL8192F | ODM_RTL8822B | ODM_RTL8812 | ODM_RTL8197F))) { + return; + } + if ((strcmp(input[1], help) == 0)) { PDM_SNPF(out_len, used, output + used, out_len - used, "echo dis_dym_ant_weighting {0/1}\n"); @@ -112,9 +141,8 @@ void phydm_trx_antenna_setting_init(void *dm_void, u8 num_rf_path) u8 path_bitmap = 1; path_bitmap = (u8)phydm_gen_bitmask(num_rf_path); -#if 0 + /*PHYDM_DBG(dm, ODM_COMP_INIT, "path_bitmap=0x%x\n", path_bitmap);*/ -#endif dm->tx_ant_status = path_bitmap; dm->rx_ant_status = path_bitmap; @@ -331,7 +359,7 @@ void phydm_config_trx_path_v2(void *dm_void, char input[][16], u32 *_used, { #if (RTL8822B_SUPPORT || RTL8197F_SUPPORT || RTL8192F_SUPPORT ||\ RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8197G_SUPPORT ||\ - RTL8812F_SUPPORT) + RTL8812F_SUPPORT || RTL8198F_SUPPORT) struct dm_struct *dm = (struct dm_struct *)dm_void; u32 used = *_used; u32 out_len = *_out_len; @@ -343,14 +371,12 @@ void phydm_config_trx_path_v2(void *dm_void, char input[][16], u32 *_used, if (!(dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8192F | ODM_RTL8822C | - ODM_RTL8814B | ODM_RTL8812F | ODM_RTL8197G))) + ODM_RTL8814B | ODM_RTL8812F | ODM_RTL8197G | ODM_RTL8198F))) return; for (i = 0; i < 5; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &val[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &val[i]); + input_idx++; } if (input_idx == 0) @@ -476,11 +502,11 @@ void phydm_config_trx_path(void *dm_void, char input[][16], u32 *_used, #endif } else if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8192F | ODM_RTL8822C | ODM_RTL8812F | - ODM_RTL8197G | ODM_RTL8814B)) { + ODM_RTL8197G | ODM_RTL8814B | ODM_RTL8198F)) { #if (RTL8822B_SUPPORT || RTL8197F_SUPPORT ||\ RTL8192F_SUPPORT || RTL8822C_SUPPORT ||\ RTL8814B_SUPPORT || RTL8812F_SUPPORT ||\ - RTL8197G_SUPPORT) + RTL8197G_SUPPORT || RTL8198F_SUPPORT) phydm_config_trx_path_v2(dm, input, _used, output, _out_len); #endif } @@ -581,20 +607,22 @@ u8 phydm_stop_ic_trx(void *dm_void, u8 set_type) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_api_stuc *api = &dm->api_table; - u32 i = 0; - u8 trx_idle_success = false; + u8 i = 0; + boolean trx_idle_success = false; u32 dbg_port_value = 0; if (set_type == PHYDM_SET) { - /*@[Stop TRX]---------------------------------------------------------*/ - /*set debug port to 0x0*/ - if (!phydm_set_bb_dbg_port(dm, DBGPORT_PRI_3, 0x0)) - return PHYDM_SET_FAIL; - - for (i = 0; i < 100; i++) { - dbg_port_value = phydm_get_bb_dbg_port_val(dm); - - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + /*[Stop TRX]---------------------------------------------------------*/ + if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + #if (RTL8723F_SUPPORT) + /*Judy 2020-0515*/ + /*set debug port to 0x0*/ + if (!phydm_set_bb_dbg_port(dm, DBGPORT_PRI_3, 0x0)) + return PHYDM_SET_FAIL; + #endif + for (i = 0; i < 100; i++) { + dbg_port_value = odm_get_bb_reg(dm, R_0x2db4, + MASKDWORD); /* BB idle */ if ((dbg_port_value & 0x1FFEFF3F) == 0 && (dbg_port_value & 0xC0010000) == @@ -606,10 +634,17 @@ u8 phydm_stop_ic_trx(void *dm_void, u8 set_type) trx_idle_success = true; break; } - } else { + } + } else { + /*set debug port to 0x0*/ + if (!phydm_set_bb_dbg_port(dm, DBGPORT_PRI_3, 0x0)) + return PHYDM_SET_FAIL; + for (i = 0; i < 100; i++) { + dbg_port_value = phydm_get_bb_dbg_port_val(dm); /* PHYTXON && CCA_all */ if (dm->support_ic_type & (ODM_RTL8721D | - ODM_RTL8710C)) { + ODM_RTL8710B | ODM_RTL8710C | + ODM_RTL8188F | ODM_RTL8723D)) { if ((dbg_port_value & (BIT(20) | BIT(15))) == 0) { PHYDM_DBG(dm, ODM_COMP_API, @@ -630,10 +665,10 @@ u8 phydm_stop_ic_trx(void *dm_void, u8 set_type) break; } } + ODM_delay_ms(1); } - ODM_delay_ms(1); + phydm_release_bb_dbg_port(dm); } - phydm_release_bb_dbg_port(dm); if (trx_idle_success) { api->tx_queue_bitmap = odm_read_1byte(dm, R_0x522); @@ -642,15 +677,15 @@ u8 phydm_stop_ic_trx(void *dm_void, u8 set_type) odm_set_mac_reg(dm, R_0x520, 0xff0000, 0xff); if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - /*@disable OFDM RX CCA*/ - odm_set_bb_reg(dm, R_0x1c68, BIT(24), 1); + /*disable OFDM RX CCA*/ + odm_set_bb_reg(dm, R_0x1d58, 0xff8, 0x1ff); } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { - /*@disable OFDM RX CCA*/ + /*disable OFDM RX CCA*/ odm_set_bb_reg(dm, R_0x838, BIT(1), 1); } else { api->rxiqc_reg1 = odm_read_4byte(dm, R_0xc14); api->rxiqc_reg2 = odm_read_4byte(dm, R_0xc1c); - /* @[ Set IQK Matrix = 0 ] + /* [ Set IQK Matrix = 0 ] * equivalent to [ Turn off CCA] */ odm_set_bb_reg(dm, R_0xc14, MASKDWORD, 0x0); @@ -669,7 +704,7 @@ u8 phydm_stop_ic_trx(void *dm_void, u8 set_type) if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { /*@enable OFDM RX CCA*/ - odm_set_bb_reg(dm, R_0x1c68, BIT(24), 0); + odm_set_bb_reg(dm, R_0x1d58, 0xff8, 0x0); } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { /*@enable OFDM RX CCA*/ odm_set_bb_reg(dm, R_0x838, BIT(1), 0); @@ -690,12 +725,20 @@ void phydm_dis_cck_trx(void *dm_void, u8 set_type) if (set_type == PHYDM_SET) { if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - api->ccktx_path = (u8)odm_get_bb_reg(dm, R_0x1a04, - 0xf0000000); - /* @CCK RxIQ weighting = [0,0] */ - odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x3); - /* @disable CCK Tx */ - odm_set_bb_reg(dm, R_0x1a04, 0xf0000000, 0x0); + if(dm->support_ic_type & ODM_RTL8723F) { + api->ccktx_path = 1; + /* @disable CCK CCA */ + odm_set_bb_reg(dm, R_0x2a24, BIT(13), 0x1); + /* @disable CCK Tx */ + odm_set_bb_reg(dm, R_0x2a00, BIT(1), 0x1); + } else { + api->ccktx_path = (u8)odm_get_bb_reg(dm, R_0x1a04, + 0xf0000000); + /* @CCK RxIQ weighting = [0,0] */ + odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x3); + /* @disable CCK Tx */ + odm_set_bb_reg(dm, R_0x1a04, 0xf0000000, 0x0); + } } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { api->ccktx_path = (u8)odm_get_bb_reg(dm, R_0xa04, 0xf0000000); @@ -713,11 +756,18 @@ void phydm_dis_cck_trx(void *dm_void, u8 set_type) } } else if (set_type == PHYDM_REVERT) { if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - /* @CCK RxIQ weighting = [1,1] */ - odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x0); - /* @enable CCK Tx */ - odm_set_bb_reg(dm, R_0x1a04, 0xf0000000, - api->ccktx_path); + if(dm->support_ic_type & ODM_RTL8723F) { + /* @enable CCK CCA */ + odm_set_bb_reg(dm, R_0x2a24, BIT(13), 0x0); + /* @enable CCK Tx */ + odm_set_bb_reg(dm, R_0x2a00, BIT(1), 0x0); + } else { + /* @CCK RxIQ weighting = [1,1] */ + odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x0); + /* @enable CCK Tx */ + odm_set_bb_reg(dm, R_0x1a04, 0xf0000000, + api->ccktx_path); + } } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { /* @enable CCK block */ odm_set_bb_reg(dm, R_0x808, BIT(28), 1); @@ -733,6 +783,57 @@ void phydm_dis_cck_trx(void *dm_void, u8 set_type) } } } + +void phydm_bw_fixed_enable(void *dm_void, u8 enable) +{ +#ifdef CONFIG_BW_INDICATION + struct dm_struct *dm = (struct dm_struct *)dm_void; + boolean val = (enable == FUNC_ENABLE) ? 1 : 0; + + if (dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8822B | ODM_RTL8195B)) + odm_set_bb_reg(dm, R_0x840, BIT(4), val); + else if (dm->support_ic_type & ODM_RTL8822C) + odm_set_bb_reg(dm, R_0x878, BIT(28), val); +#endif +} + +void phydm_bw_fixed_setting(void *dm_void) +{ +#ifdef CONFIG_BW_INDICATION + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_api_stuc *api = &dm->api_table; + u8 bw = *dm->band_width; + u32 reg = 0, reg_mask = 0, reg_value = 0; + + if (!(dm->support_ic_type & ODM_DYM_BW_INDICATION_SUPPORT)) + return; + + if (dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8822B | + ODM_RTL8195B)) { + reg = R_0x840; + reg_mask = 0xf; + reg_value = api->pri_ch_idx; + } else if (dm->support_ic_type & ODM_RTL8822C) { + reg = R_0x878; + reg_mask = 0xc0000000; + reg_value = 0x0; + } + + switch (bw) { + case CHANNEL_WIDTH_80: + odm_set_bb_reg(dm, reg, reg_mask, reg_value); + break; + case CHANNEL_WIDTH_40: + odm_set_bb_reg(dm, reg, reg_mask, reg_value); + break; + default: + odm_set_bb_reg(dm, reg, reg_mask, 0x0); + } + + phydm_bw_fixed_enable(dm, FUNC_ENABLE); +#endif +} + void phydm_set_ext_switch(void *dm_void, u32 ext_ant_switch) { #if (RTL8821A_SUPPORT || RTL8881A_SUPPORT) @@ -968,7 +1069,8 @@ void phydm_nbi_enable(void *dm_void, u32 enable) odm_set_bb_reg(dm, R_0xc40, BIT(9), val); } } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { - if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C)) { + if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C | + ODM_RTL8195B)) { odm_set_bb_reg(dm, R_0x87c, BIT(13), val); odm_set_bb_reg(dm, R_0xc20, BIT(28), val); if (dm->rf_type > RF_1T1R) @@ -1135,7 +1237,154 @@ u8 phydm_csi_mask_setting(void *dm_void, u32 enable, u32 ch, u32 bw, return set_result; } +boolean phydm_spur_case_mapping(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u8 channel = *dm->channel, bw = *dm->band_width; + boolean mapping_result = false; +#if (RTL8814B_SUPPORT == 1) + if (channel == 153 && bw == CHANNEL_WIDTH_20) + mapping_result = true; + else if (channel == 151 && bw == CHANNEL_WIDTH_40) + mapping_result = true; + else if (channel == 155 && bw == CHANNEL_WIDTH_80) + mapping_result = true; +#endif + return mapping_result; +} + +enum odm_rf_band phydm_ch_to_rf_band(void *dm_void, u8 central_ch) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + enum odm_rf_band rf_band = ODM_RF_BAND_5G_LOW; + + if (central_ch <= 14) + rf_band = ODM_RF_BAND_2G; + else if (central_ch >= 36 && central_ch <= 64) + rf_band = ODM_RF_BAND_5G_LOW; + else if ((central_ch >= 100) && (central_ch <= 144)) + rf_band = ODM_RF_BAND_5G_MID; + else if (central_ch >= 149) + rf_band = ODM_RF_BAND_5G_HIGH; + else + PHYDM_DBG(dm, ODM_COMP_API, "mapping channel to band fail\n"); + + return rf_band; +} + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT +u32 phydm_rf_psd_jgr3(void *dm_void, u8 path, u32 tone_idx) +{ +#if (RTL8198F_SUPPORT || RTL8814B_SUPPORT) + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 reg_1b04 = 0, reg_1b08 = 0, reg_1b0c_11_10 = 0; + u32 reg_1b14 = 0, reg_1b18 = 0, reg_1b1c = 0; + u32 reg_1b28 = 0; + u32 reg_1bcc_5_0 = 0; + u32 reg_1b2c_27_16 = 0, reg_1b34 = 0, reg_1bd4 = 0; + u32 reg_180c = 0, reg_410c = 0, reg_520c = 0, reg_530c = 0; + u32 igi = 0; + u32 i = 0; + u32 psd_val = 0, psd_val_msb = 0, psd_val_lsb = 0, psd_max = 0; + u32 psd_status_temp = 0; + u16 poll_cnt = 0; + + /*read and record the ori. value*/ + reg_1b04 = odm_get_bb_reg(dm, R_0x1b04, MASKDWORD); + reg_1b08 = odm_get_bb_reg(dm, R_0x1b08, MASKDWORD); + reg_1b0c_11_10 = odm_get_bb_reg(dm, R_0x1b0c, 0xc00); + reg_1b14 = odm_get_bb_reg(dm, R_0x1b14, MASKDWORD); + reg_1b18 = odm_get_bb_reg(dm, R_0x1b18, MASKDWORD); + reg_1b1c = odm_get_bb_reg(dm, R_0x1b1c, MASKDWORD); + reg_1b28 = odm_get_bb_reg(dm, R_0x1b28, MASKDWORD); + reg_1bcc_5_0 = odm_get_bb_reg(dm, R_0x1bcc, 0x3f); + reg_1b2c_27_16 = odm_get_bb_reg(dm, R_0x1b2c, 0xfff0000); + reg_1b34 = odm_get_bb_reg(dm, R_0x1b34, MASKDWORD); + reg_1bd4 = odm_get_bb_reg(dm, R_0x1bd4, MASKDWORD); + igi = odm_get_bb_reg(dm, R_0x1d70, MASKDWORD); + reg_180c = odm_get_bb_reg(dm, R_0x180c, 0x3); + reg_410c = odm_get_bb_reg(dm, R_0x410c, 0x3); + reg_520c = odm_get_bb_reg(dm, R_0x520c, 0x3); + reg_530c = odm_get_bb_reg(dm, R_0x530c, 0x3); + + /*rf psd reg setting*/ + odm_set_bb_reg(dm, R_0x1b00, 0x6, path); /*path is RF_path*/ + odm_set_bb_reg(dm, R_0x1b04, MASKDWORD, 0x0); + odm_set_bb_reg(dm, R_0x1b08, MASKDWORD, 0x80); + odm_set_bb_reg(dm, R_0x1b0c, 0xc00, 0x3); + odm_set_bb_reg(dm, R_0x1b14, MASKDWORD, 0x0); + odm_set_bb_reg(dm, R_0x1b18, MASKDWORD, 0x1); +/*#if (DM_ODM_SUPPORT_TYPE == ODM_AP)*/ + odm_set_bb_reg(dm, R_0x1b1c, MASKDWORD, 0x82103D21); +/*#else*/ + /*odm_set_bb_reg(dm, R_0x1b1c, MASKDWORD, 0x821A3D21);*/ +/*#endif*/ + odm_set_bb_reg(dm, R_0x1b28, MASKDWORD, 0x0); + odm_set_bb_reg(dm, R_0x1bcc, 0x3f, 0x3f); + odm_set_bb_reg(dm, R_0x8a0, 0xf, 0x0); /* AGC off */ + odm_set_bb_reg(dm, R_0x1d70, MASKDWORD, 0x20202020); + + for (i = tone_idx - 1; i <= tone_idx + 1; i++) { + /*set psd tone_idx for detection*/ + odm_set_bb_reg(dm, R_0x1b2c, 0xfff0000, i); + /*one shot for RXIQK psd*/ + odm_set_bb_reg(dm, R_0x1b34, MASKDWORD, 0x1); + odm_set_bb_reg(dm, R_0x1b34, MASKDWORD, 0x0); + + if (dm->support_ic_type & ODM_RTL8814B) + for (poll_cnt = 0; poll_cnt < 20; poll_cnt++) { + odm_set_bb_reg(dm, R_0x1bd4, 0x3f0000, 0x2b); + psd_status_temp = odm_get_bb_reg(dm, R_0x1bfc, + BIT(1)); + if (!psd_status_temp) + ODM_delay_us(10); + else + break; + } + else + ODM_delay_us(250); + + /*read RxIQK power*/ + odm_set_bb_reg(dm, R_0x1bd4, MASKDWORD, 0x00250001); + if (dm->support_ic_type & ODM_RTL8814B) + psd_val_msb = odm_get_bb_reg(dm, R_0x1bfc, 0x7ff0000); + else if (dm->support_ic_type & ODM_RTL8198F) + psd_val_msb = odm_get_bb_reg(dm, R_0x1bfc, 0x1f0000); + + odm_set_bb_reg(dm, R_0x1bd4, MASKDWORD, 0x002e0001); + psd_val_lsb = odm_get_bb_reg(dm, R_0x1bfc, MASKDWORD); + if (dm->support_ic_type & ODM_RTL8814B) + psd_val = (psd_val_msb << 21) + (psd_val_lsb >> 11); + else if (dm->support_ic_type & ODM_RTL8198F) + psd_val = (psd_val_msb << 27) + (psd_val_lsb >> 5); + + if (psd_val > psd_max) + psd_max = psd_val; + } + + /*refill the ori. value*/ + odm_set_bb_reg(dm, R_0x1b00, 0x6, path); + odm_set_bb_reg(dm, R_0x1b04, MASKDWORD, reg_1b04); + odm_set_bb_reg(dm, R_0x1b08, MASKDWORD, reg_1b08); + odm_set_bb_reg(dm, R_0x1b0c, 0xc00, reg_1b0c_11_10); + odm_set_bb_reg(dm, R_0x1b14, MASKDWORD, reg_1b14); + odm_set_bb_reg(dm, R_0x1b18, MASKDWORD, reg_1b18); + odm_set_bb_reg(dm, R_0x1b1c, MASKDWORD, reg_1b1c); + odm_set_bb_reg(dm, R_0x1b28, MASKDWORD, reg_1b28); + odm_set_bb_reg(dm, R_0x1bcc, 0x3f, reg_1bcc_5_0); + odm_set_bb_reg(dm, R_0x1b2c, 0xfff0000, reg_1b2c_27_16); + odm_set_bb_reg(dm, R_0x1b34, MASKDWORD, reg_1b34); + odm_set_bb_reg(dm, R_0x1bd4, MASKDWORD, reg_1bd4); + odm_set_bb_reg(dm, R_0x8a0, 0xf, 0xf); /* AGC on */ + odm_set_bb_reg(dm, R_0x1d70, MASKDWORD, igi); + PHYDM_DBG(dm, ODM_COMP_API, "psd_max %d\n", psd_max); + + return psd_max; +#else + return 0; +#endif +} + u8 phydm_find_intf_distance_jgr3(void *dm_void, u32 bw, u32 fc, u32 f_interference, u32 *tone_idx_tmp_in) { @@ -1144,6 +1393,7 @@ u8 phydm_find_intf_distance_jgr3(void *dm_void, u32 bw, u32 fc, u32 int_distance = 0; u32 tone_idx_tmp = 0; u8 set_result = PHYDM_SET_NO_NEED; + u8 channel = *dm->channel; bw_up = 1000 * (fc + bw / 2); bw_low = 1000 * (fc - bw / 2); @@ -1156,7 +1406,11 @@ u8 phydm_find_intf_distance_jgr3(void *dm_void, u32 bw, u32 fc, if (f_interference >= bw_low && f_interference <= bw_up) { int_distance = DIFF_2(fc, f_interference); /*@10*(int_distance /0.3125)*/ - tone_idx_tmp = ((int_distance + 156) / 312); + if (channel < 15 && + (dm->support_ic_type & (ODM_RTL8814B | ODM_RTL8198F))) + tone_idx_tmp = int_distance / 312; + else + tone_idx_tmp = ((int_distance + 156) / 312); PHYDM_DBG(dm, ODM_COMP_API, "int_distance = ((%d)) , tone_idx_tmp = ((%d))\n", int_distance, tone_idx_tmp); @@ -1166,6 +1420,7 @@ u8 phydm_find_intf_distance_jgr3(void *dm_void, u32 bw, u32 fc, return set_result; } + u8 phydm_csi_mask_setting_jgr3(void *dm_void, u32 enable, u32 ch, u32 bw, u32 f_intf, u32 sec_ch, u8 wgt) { @@ -1220,12 +1475,14 @@ void phydm_set_csi_mask_jgr3(void *dm_void, u32 tone_idx_tmp, u8 tone_direction, u8 wgt) { struct dm_struct *dm = (struct dm_struct *)dm_void; - u32 reg_tmp_value = 0; + u32 multi_tone_idx_tmp = 0; + u32 reg_tmp = 0; u32 tone_num = 64; u32 table_addr = 0; u32 addr = 0; u8 rf_bw = 0; u8 value = 0; + u8 channel = *dm->channel; rf_bw = odm_read_1byte(dm, R_0x9b0); if (((rf_bw & 0xc) >> 2) == 0x2) @@ -1244,23 +1501,160 @@ void phydm_set_csi_mask_jgr3(void *dm_void, u32 tone_idx_tmp, u8 tone_direction, } table_addr = tone_idx_tmp >> 1; - reg_tmp_value = odm_read_4byte(dm, R_0x1d94); + reg_tmp = odm_read_4byte(dm, R_0x1d94); PHYDM_DBG(dm, ODM_COMP_API, "Pre Mask tone idx[%d]: Reg0x1d94 = ((0x%x))\n", - tone_idx_tmp, reg_tmp_value); + tone_idx_tmp, reg_tmp); odm_set_bb_reg(dm, R_0x1ee8, 0x3, 0x3); odm_set_bb_reg(dm, R_0x1d94, BIT(31) | BIT(30), 0x1); - odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, (table_addr & 0xff)); - if (tone_idx_tmp % 2) - value = (BIT(3) | (wgt & 0x7)) << 4; - else - value = BIT(3) | (wgt & 0x7); - odm_set_bb_reg(dm, R_0x1d94, 0xff, value); - reg_tmp_value = odm_read_4byte(dm, R_0x1d94); - PHYDM_DBG(dm, ODM_COMP_API, - "New Mask tone idx[%d]: Reg0x1d94 = ((0x%x))\n", - tone_idx_tmp, reg_tmp_value); + if (channel < 15 && + (dm->support_ic_type & (ODM_RTL8814B | ODM_RTL8198F))) { + if (tone_idx_tmp % 2 == 1) { + if (tone_direction == FREQ_POSITIVE) { + /*===Tone 1===*/ + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, + (table_addr & 0xff)); + value = (BIT(3) | (wgt & 0x7)) << 4; + odm_set_bb_reg(dm, R_0x1d94, 0xff, value); + reg_tmp = odm_read_4byte(dm, R_0x1d94); + PHYDM_DBG(dm, ODM_COMP_API, + "New Mask tone 1 idx[%d]: Reg0x1d94 = ((0x%x))\n", + tone_idx_tmp, reg_tmp); + /*===Tone 2===*/ + value = 0; + multi_tone_idx_tmp = tone_idx_tmp + 1; + table_addr = multi_tone_idx_tmp >> 1; + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, + (table_addr & 0xff)); + value = (BIT(3) | (wgt & 0x7)); + odm_set_bb_reg(dm, R_0x1d94, 0xff, value); + reg_tmp = odm_read_4byte(dm, R_0x1d94); + PHYDM_DBG(dm, ODM_COMP_API, + "New Mask tone 2 idx[%d]: Reg0x1d94 = ((0x%x))\n", + tone_idx_tmp, reg_tmp); + } else { + /*===Tone 1 & 2===*/ + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, + (table_addr & 0xff)); + value = ((BIT(3) | (wgt & 0x7)) << 4) | + (BIT(3) | (wgt & 0x7)); + odm_set_bb_reg(dm, R_0x1d94, 0xff, value); + reg_tmp = odm_read_4byte(dm, R_0x1d94); + PHYDM_DBG(dm, ODM_COMP_API, + "New Mask tone 1 & 2 idx[%d]: Reg0x1d94 = ((0x%x))\n", + tone_idx_tmp, reg_tmp); + } + } else { + if (tone_direction == FREQ_POSITIVE) { + /*===Tone 1 & 2===*/ + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, + (table_addr & 0xff)); + value = ((BIT(3) | (wgt & 0x7)) << 4) | + (BIT(3) | (wgt & 0x7)); + odm_set_bb_reg(dm, R_0x1d94, 0xff, value); + reg_tmp = odm_read_4byte(dm, R_0x1d94); + PHYDM_DBG(dm, ODM_COMP_API, + "New Mask tone 1 & 2 idx[%d]: Reg0x1d94 = ((0x%x))\n", + tone_idx_tmp, reg_tmp); + } else { + /*===Tone 1===*/ + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, + (table_addr & 0xff)); + value = (BIT(3) | (wgt & 0x7)); + odm_set_bb_reg(dm, R_0x1d94, 0xff, value); + reg_tmp = odm_read_4byte(dm, R_0x1d94); + PHYDM_DBG(dm, ODM_COMP_API, + "New Mask tone 1 idx[%d]: Reg0x1d94 = ((0x%x))\n", + tone_idx_tmp, reg_tmp); + + /*===Tone 2===*/ + value = 0; + multi_tone_idx_tmp = tone_idx_tmp - 1; + table_addr = multi_tone_idx_tmp >> 1; + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, + (table_addr & 0xff)); + value = (BIT(3) | (wgt & 0x7)) << 4; + odm_set_bb_reg(dm, R_0x1d94, 0xff, value); + reg_tmp = odm_read_4byte(dm, R_0x1d94); + PHYDM_DBG(dm, ODM_COMP_API, + "New Mask tone 2 idx[%d]: Reg0x1d94 = ((0x%x))\n", + tone_idx_tmp, reg_tmp); + } + } + } else { + if ((dm->support_ic_type & (ODM_RTL8814B)) && + phydm_spur_case_mapping(dm)) { + if (!(tone_idx_tmp % 2)) { + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, + (table_addr & 0xff)); + value = ((BIT(3) | (((wgt + 4) <= 7 ? (wgt + + 4) : 7) & 0x7)) << 4) | (BIT(3) | + (wgt & 0x7)); + odm_set_bb_reg(dm, R_0x1d94, 0xff, value); + reg_tmp = odm_read_4byte(dm, R_0x1d94); + PHYDM_DBG(dm, ODM_COMP_API, + "New Mask tone idx[%d]: Reg0x1d94 = ((0x%x))\n", + tone_idx_tmp, reg_tmp); + if (tone_idx_tmp == 0) + table_addr = tone_num - 1; + else + table_addr = table_addr - 1; + if (tone_idx_tmp != tone_num) { + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, + (table_addr & 0xff)); + value = (BIT(3) | (((wgt + 4) <= 7 ? + (wgt + 4) : 7) & 0x7)) << 4; + odm_set_bb_reg(dm, R_0x1d94, 0xff, + value); + reg_tmp = odm_read_4byte(dm, R_0x1d94); + PHYDM_DBG(dm, ODM_COMP_API, + "New Mask Reg0x1d94 = ((0x%x))\n", + reg_tmp); + } + } else { + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, + (table_addr & 0xff)); + value = ((BIT(3) | (wgt & 0x7)) << 4) | + (BIT(3) | (((wgt + 4) <= 7 ? (wgt + + 4) : 7) & 0x7)); + odm_set_bb_reg(dm, R_0x1d94, 0xff, value); + reg_tmp = odm_read_4byte(dm, R_0x1d94); + PHYDM_DBG(dm, ODM_COMP_API, + "New Mask tone idx[%d]: Reg0x1d94 = ((0x%x))\n", + tone_idx_tmp, reg_tmp); + if (tone_idx_tmp == (tone_num << 1) - 1) + table_addr = 0; + else + table_addr = table_addr + 1; + if (tone_idx_tmp != tone_num - 1) { + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, + (table_addr & 0xff)); + value = (BIT(3) | (((wgt + 4) <= 7 ? + (wgt + 4) : 7) & 0x7)); + odm_set_bb_reg(dm, R_0x1d94, 0xff, + value); + reg_tmp = odm_read_4byte(dm, R_0x1d94); + PHYDM_DBG(dm, ODM_COMP_API, + "New Mask Reg0x1d94 = ((0x%x))\n", + reg_tmp); + } + } + } else { + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, (table_addr & + 0xff)); + if (tone_idx_tmp % 2) + value = (BIT(3) | (wgt & 0x7)) << 4; + else + value = BIT(3) | (wgt & 0x7); + + odm_set_bb_reg(dm, R_0x1d94, 0xff, value); + reg_tmp = odm_read_4byte(dm, R_0x1d94); + PHYDM_DBG(dm, ODM_COMP_API, + "New Mask tone idx[%d]: Reg0x1d94 = ((0x%x))\n", + tone_idx_tmp, reg_tmp); + } + } odm_set_bb_reg(dm, R_0x1ee8, 0x3, 0x0); } @@ -1324,15 +1718,18 @@ u8 phydm_nbi_setting_jgr3(void *dm_void, u32 enable, u32 ch, u32 bw, u32 f_intf, set_result = PHYDM_SET_SUCCESS; } else { set_result = PHYDM_SET_NO_NEED; + } } } - } if (set_result == PHYDM_SET_SUCCESS) phydm_nbi_enable_jgr3(dm, enable, path); else phydm_nbi_enable_jgr3(dm, FUNC_DISABLE, path); + if (dm->support_ic_type & ODM_RTL8814B) + odm_set_bb_reg(dm, R_0x1d3c, BIT(19), 0); + return set_result; } @@ -1364,7 +1761,11 @@ void phydm_set_nbi_reg_jgr3(void *dm_void, u32 tone_idx_tmp, u8 tone_direction, #if RTL8814B_SUPPORT if (dm->support_ic_type & ODM_RTL8814B) { odm_set_bb_reg(dm, R_0xc24, 0xff, 0xff); - odm_set_bb_reg(dm, R_0xc24, 0xff00, tone_idx_tmp); + if ((*dm->channel == 5) && + (*dm->band_width == CHANNEL_WIDTH_40)) + odm_set_bb_reg(dm, R_0xc24, 0xff00, 0x1a); + else + odm_set_bb_reg(dm, R_0xc24, 0xff00, tone_idx_tmp); } #endif switch (path) { @@ -1455,6 +1856,12 @@ void phydm_nbi_enable_jgr3(void *dm_void, u32 enable, u8 path) #if (defined(PHYDM_COMPILE_ABOVE_4SS)) odm_set_bb_reg(dm, R_0x5140, BIT(31), val); #endif + #if RTL8812F_SUPPORT + if (dm->support_ic_type & ODM_RTL8812F) { + odm_set_bb_reg(dm, R_0x818, BIT(3), val); + odm_set_bb_reg(dm, R_0x1d3c, 0x78000000, 0x0); + } + #endif } } @@ -1699,10 +2106,8 @@ void phydm_nbi_debug(void *dm_void, char input[][16], u32 *_used, char *output, else idx_lmt = 5; for (i = 0; i < idx_lmt; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); + input_idx++; } if (input_idx == 0) @@ -1791,10 +2196,8 @@ void phydm_csi_debug(void *dm_void, char input[][16], u32 *_used, char *output, idx_lmt = 5; for (i = 0; i < idx_lmt; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); + input_idx++; } if (input_idx == 0) @@ -1990,6 +2393,7 @@ phydm_api_shift_txagc(void *dm_void, u32 pwr_offset, enum rf_path path, u32 txagc_ofdm = 0; u32 r_txagc_ofdm[4] = {R_0x18e8, R_0x41e8, R_0x52e8, R_0x53e8}; u32 r_txagc_cck[4] = {R_0x18a0, R_0x41a0, R_0x52a0, R_0x53a0}; + u32 r_new_txagc[1] = {R_0x4308}; #if (RTL8822C_SUPPORT || RTL8812F_SUPPORT || RTL8197G_SUPPORT) if (dm->support_ic_type & @@ -2084,6 +2488,43 @@ phydm_api_shift_txagc(void *dm_void, u32 pwr_offset, enum rf_path path, } #endif + #if (RTL8723F_SUPPORT) + if (dm->support_ic_type & (ODM_RTL8723F)) { + if (path > RF_PATH_A) { + PHYDM_DBG(dm, ODM_PHY_CONFIG, "Unsupported path (%d)\n", + path); + return false; + } + txagc_cck = (u8)odm_get_bb_reg(dm, r_new_txagc[path], + 0x0000007f); + txagc_ofdm = (u8)odm_get_bb_reg(dm, r_new_txagc[path], + 0x00007f00); + if (is_positive) { + if (((txagc_cck + pwr_offset) > 127) || + ((txagc_ofdm + pwr_offset) > 127)) + return false; + + txagc_cck += pwr_offset; + txagc_ofdm += pwr_offset; + } else { + if (pwr_offset > txagc_cck || pwr_offset > txagc_ofdm) + return false; + + txagc_cck -= pwr_offset; + txagc_ofdm -= pwr_offset; + } + #if (RTL8723F_SUPPORT) + ret = config_phydm_write_txagc_ref_8723f(dm, (u8)txagc_cck, + path, PDM_CCK); + ret &= config_phydm_write_txagc_ref_8723f(dm, (u8)txagc_ofdm, + path, PDM_OFDM); + #endif + PHYDM_DBG(dm, ODM_PHY_CONFIG, + "%s: path-%d txagc_cck_ref=%x txagc_ofdm_ref=0x%x\n", + __func__, path, txagc_cck, txagc_ofdm); + } + #endif + return ret; } @@ -2094,7 +2535,7 @@ phydm_api_set_txagc(void *dm_void, u32 pwr_idx, enum rf_path path, struct dm_struct *dm = (struct dm_struct *)dm_void; boolean ret = false; #if (RTL8198F_SUPPORT || RTL8822C_SUPPORT || RTL8812F_SUPPORT ||\ - RTL8814B_SUPPORT || RTL8197G_SUPPORT) + RTL8814B_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) u8 base = 0; u8 txagc_tmp = 0; s8 pw_by_rate_tmp = 0; @@ -2288,6 +2729,30 @@ phydm_api_set_txagc(void *dm_void, u32 pwr_idx, enum rf_path path, __func__, path, rate, base, pw_by_rate_new); } #endif +#if (RTL8723F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8723F) { + if (rate < 0x4) + txagc_tmp = config_phydm_read_txagc_8723f(dm, path, + rate, + PDM_CCK); + else + txagc_tmp = config_phydm_read_txagc_8723f(dm, path, + rate, + PDM_OFDM); + + pw_by_rate_tmp = config_phydm_read_txagc_diff_8723f(dm, rate); + base = txagc_tmp - pw_by_rate_tmp; + base = base & 0x7f; + if (DIFF_2((pwr_idx & 0x7f), base) > 63 || pwr_idx > 127) + return false; + + pw_by_rate_new = (s8)(pwr_idx - base); + ret = phydm_write_txagc_1byte_8723f(dm, pw_by_rate_new, rate); + PHYDM_DBG(dm, ODM_PHY_CONFIG, + "%s: path-%d rate_idx=%x base=0x%x new_diff=0x%x\n", + __func__, path, rate, base, pw_by_rate_new); + } +#endif #if (RTL8197F_SUPPORT) if (dm->support_ic_type & ODM_RTL8197F) @@ -2365,6 +2830,18 @@ u8 phydm_api_get_txagc(void *dm_void, enum rf_path path, u8 hw_rate) } #endif +#if (RTL8723F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8723F) { + if (hw_rate < 0x4) { + ret = config_phydm_read_txagc_8723f(dm, path, hw_rate, + PDM_CCK); + } else { + ret = config_phydm_read_txagc_8723f(dm, path, hw_rate, + PDM_OFDM); + } + } +#endif + #if (RTL8814B_SUPPORT) if (dm->support_ic_type & ODM_RTL8814B) { if (hw_rate < 0x4) { @@ -2414,6 +2891,55 @@ u8 phydm_api_get_txagc(void *dm_void, enum rf_path path, u8 hw_rate) return ret; } +#if (RTL8822C_SUPPORT) +void phydm_shift_rxagc_table(void *dm_void, boolean is_pos_shift, u8 sft) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u8 i = 0; + u8 j = 0; + u32 reg = 0; + u16 max_rf_gain = 0; + u16 min_rf_gain = 0; + + dm->is_agc_tab_pos_shift = is_pos_shift; + dm->agc_table_shift = sft; + + for (i = 0; i <= dm->agc_table_cnt; i++) { + max_rf_gain = dm->agc_rf_gain_ori[i][0]; + min_rf_gain = dm->agc_rf_gain_ori[i][63]; + + if (dm->support_ic_type & ODM_RTL8822C) + dm->l_bnd_detect[i] = false; + + for (j = 0; j < 64; j++) { + if (is_pos_shift) { + if (j < sft) + reg = (max_rf_gain & 0x3ff); + else + reg = (dm->agc_rf_gain_ori[i][j - sft] & + 0x3ff); + } else { + if (j > 63 - sft) + reg = (min_rf_gain & 0x3ff); + + else + reg = (dm->agc_rf_gain_ori[i][j + sft] & + 0x3ff); + } + dm->agc_rf_gain[i][j] = (u16)(reg & 0x3ff); + + reg |= (j & 0x3f) << 16;/*mp_gain_idx*/ + reg |= (i & 0xf) << 22;/*table*/ + reg |= BIT(29) | BIT(28);/*write en*/ + odm_set_bb_reg(dm, R_0x1d90, MASKDWORD, reg); + } + } + + if (dm->support_ic_type & ODM_RTL8822C) + odm_set_bb_reg(dm, R_0x828, 0xf8, L_BND_DEFAULT_8822C); +} +#endif + boolean phydm_api_switch_bw_channel(void *dm_void, u8 ch, u8 pri_ch, enum channel_width bw) @@ -2440,6 +2966,12 @@ phydm_api_switch_bw_channel(void *dm_void, u8 ch, u8 pri_ch, break; #endif +#if (RTL8195B_SUPPORT) + case ODM_RTL8195B: + ret = config_phydm_switch_channel_bw_8195b(dm, ch, pri_ch, bw); + break; +#endif + #if (RTL8192F_SUPPORT) case ODM_RTL8192F: ret = config_phydm_switch_channel_bw_8192f(dm, ch, pri_ch, bw); @@ -2458,6 +2990,12 @@ phydm_api_switch_bw_channel(void *dm_void, u8 ch, u8 pri_ch, break; #endif +#if (RTL8723F_SUPPORT) + case ODM_RTL8723F: + ret = config_phydm_switch_channel_bw_8723f(dm, ch, pri_ch, bw); + break; +#endif + #if (RTL8814B_SUPPORT) case ODM_RTL8814B: ret = config_phydm_switch_channel_bw_8814b(dm, ch, pri_ch, bw); @@ -2570,7 +3108,9 @@ phydm_api_trx_mode(void *dm_void, enum bb_path tx_path, enum bb_path rx_path, } return ret; } -#else +#endif + +#ifdef PHYDM_COMMON_API_NOT_SUPPORT u8 config_phydm_read_txagc_n(void *dm_void, enum rf_path path, u8 hw_rate) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -2671,7 +3211,6 @@ u8 config_phydm_read_txagc_n(void *dm_void, enum rf_path path, u8 hw_rate) reg_txagc = R_0xe14; reg_mask = 0x7f000000; break; - case ODM_RATEMCS8: reg_txagc = R_0xe18; reg_mask = 0x0000007f; diff --git a/hal/phydm/phydm_api.h b/hal/phydm/phydm_api.h index 9305632..a27b725 100644 --- a/hal/phydm/phydm_api.h +++ b/hal/phydm/phydm_api.h @@ -26,8 +26,8 @@ #ifndef __PHYDM_API_H__ #define __PHYDM_API_H__ -/* 2019.03.05 add reset txagc API for jgr3 ics*/ -#define PHYDM_API_VERSION "2.1" +/* 2019.10.22 Add get/shift rxagc API for 8822C*/ +#define PHYDM_API_VERSION "2.3" /* @1 ============================================================ * 1 Definition @@ -87,6 +87,7 @@ struct phydm_api_stuc { u32 rxiqc_reg2; /*N-mode: for pathB REG0xc1c*/ u8 tx_queue_bitmap; /*REG0x520[23:16]*/ u8 ccktx_path; + u8 pri_ch_idx; }; /* @1 ============================================================ @@ -98,6 +99,8 @@ struct phydm_api_stuc { * 1 function prototype * 1 ============================================================ */ +enum channel_width phydm_rxsc_2_bw(void *dm_void, u8 rxsc); + void phydm_reset_bb_hw_cnt(void *dm_void); void phydm_dynamic_ant_weighting(void *dm_void); @@ -130,6 +133,10 @@ u8 phydm_stop_ic_trx(void *dm_void, u8 set_type); void phydm_dis_cck_trx(void *dm_void, u8 set_type); +void phydm_bw_fixed_enable(void *dm_void, u8 enable); + +void phydm_bw_fixed_setting(void *dm_void); + void phydm_set_ext_switch(void *dm_void, u32 ext_ant_switch); void phydm_nbi_enable(void *dm_void, u32 enable); @@ -150,7 +157,13 @@ void phydm_stop_ck320(void *dm_void, u8 enable); boolean phydm_set_bb_txagc_offset(void *dm_void, s8 power_offset, u8 add_half_db); + +boolean phydm_spur_case_mapping(void *dm_void); + +enum odm_rf_band phydm_ch_to_rf_band(void *dm_void, u8 central_ch); #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT +u32 phydm_rf_psd_jgr3(void *dm_void, u8 path, u32 tone_idx); + u8 phydm_csi_mask_setting_jgr3(void *dm_void, u32 enable, u32 ch, u32 bw, u32 f_intf, u32 sec_ch, u8 wgt); @@ -183,6 +196,10 @@ phydm_api_set_txagc(void *dm_void, u32 power_index, enum rf_path path, u8 phydm_api_get_txagc(void *dm_void, enum rf_path path, u8 hw_rate); +#if (RTL8822C_SUPPORT) +void phydm_shift_rxagc_table(void *dm_void, boolean shift_up, u8 shift); +#endif + boolean phydm_api_switch_bw_channel(void *dm_void, u8 central_ch, u8 primary_ch_idx, enum channel_width bandwidth); @@ -193,6 +210,10 @@ phydm_api_trx_mode(void *dm_void, enum bb_path tx_path, enum bb_path rx_path, #endif +#ifdef PHYDM_COMMON_API_NOT_SUPPORT +u8 config_phydm_read_txagc_n(void *dm_void, enum rf_path path, u8 hw_rate); +#endif + #ifdef CONFIG_MCC_DM #ifdef DYN_ANT_WEIGHTING_SUPPORT void phydm_dynamic_ant_weighting_mcc_8822b(void *dm_void); diff --git a/hal/phydm/phydm_beamforming.c b/hal/phydm/phydm_beamforming.c index bc4855c..1c055c8 100644 --- a/hal/phydm/phydm_beamforming.c +++ b/hal/phydm/phydm_beamforming.c @@ -48,6 +48,9 @@ void phydm_get_txbf_device_num( u8 act_as_bfer = 0; u8 act_as_bfee = 0; + if (!(dm->support_ability & ODM_BB_ANT_DIV)) + return; + if (is_sta_active(sta)) { bf = &(sta->bf_info); } else { @@ -71,7 +74,7 @@ void phydm_get_txbf_device_num( act_as_bfee = 1; } - if (act_as_bfer)) + if (act_as_bfer) { /* Our Device act as BFer */ dm_bdc_table->w_bfee_client[macid] = true; dm_bdc_table->num_txbfee_client++; @@ -79,7 +82,7 @@ void phydm_get_txbf_device_num( else dm_bdc_table->w_bfee_client[macid] = false; - if (act_as_bfee)) + if (act_as_bfee) { /* Our Device act as BFee */ dm_bdc_table->w_bfer_client[macid] = true; dm_bdc_table->num_txbfer_client++; @@ -460,41 +463,6 @@ beamforming_add_bfer_entry( return NULL; } -#if 0 -boolean -beamforming_remove_entry( - void *adapter, - u8 *RA, - u8 *idx -) -{ - HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter)); - struct dm_struct *dm = &hal_data->DM_OutSrc; - - struct _RT_BEAMFORMER_ENTRY *bfer_entry = phydm_beamforming_get_bfer_entry_by_addr(dm, RA, idx); - struct _RT_BEAMFORMEE_ENTRY *entry = phydm_beamforming_get_bfee_entry_by_addr(dm, RA, idx); - boolean ret = false; - - RT_DISP(FBEAM, FBEAM_FUN, ("[Beamforming]@%s Start!\n", __func__)); - RT_DISP(FBEAM, FBEAM_FUN, ("[Beamforming]@%s, bfer_entry=0x%x\n", __func__, bfer_entry)); - RT_DISP(FBEAM, FBEAM_FUN, ("[Beamforming]@%s, entry=0x%x\n", __func__, entry)); - - if (entry != NULL) { - entry->is_used = false; - entry->beamform_entry_cap = BEAMFORMING_CAP_NONE; - /*@entry->beamform_entry_state = BEAMFORMING_ENTRY_STATE_UNINITIALIZE;*/ - entry->is_beamforming_in_progress = false; - ret = true; - } - if (bfer_entry != NULL) { - bfer_entry->is_used = false; - bfer_entry->beamform_entry_cap = BEAMFORMING_CAP_NONE; - ret = true; - } - return ret; -} -#endif - /* Used for beamforming_start_v1 */ void phydm_beamforming_ndpa_rate( void *dm_void, @@ -1807,35 +1775,6 @@ void beamforming_leave( PHYDM_DBG(dm, DBG_TXBF, "[%s] End!!\n", __func__); } -#if 0 -/* Nobody calls this function */ -void -phydm_beamforming_set_txbf_en( - void *dm_void, - u8 mac_id, - boolean is_txbf -) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - u8 idx = 0; - struct _RT_BEAMFORMEE_ENTRY *entry; - - PHYDM_DBG(dm, DBG_TXBF, "%s Start!\n", __func__); - - entry = phydm_beamforming_get_entry_by_mac_id(dm, mac_id, &idx); - - if (entry == NULL) - return; - else - entry->is_txbf = is_txbf; - - PHYDM_DBG(dm, DBG_TXBF, "%s mac_id %d TxBF %d\n", __func__, - entry->mac_id, entry->is_txbf); - - phydm_beamforming_notify(dm); -} -#endif - enum beamforming_cap phydm_beamforming_get_beam_cap( void *dm_void, diff --git a/hal/phydm/phydm_beamforming.h b/hal/phydm/phydm_beamforming.h index 26e54c0..efb53e3 100644 --- a/hal/phydm/phydm_beamforming.h +++ b/hal/phydm/phydm_beamforming.h @@ -45,7 +45,7 @@ #define MAX_BEAMFORMEE_SU 2 #define MAX_BEAMFORMER_SU 2 -#if (RTL8822B_SUPPORT == 1) +#if ((RTL8822B_SUPPORT == 1) || (RTL8812F_SUPPORT == 1)) #define MAX_BEAMFORMEE_MU 6 #define MAX_BEAMFORMER_MU 1 #else diff --git a/hal/phydm/phydm_cck_pd.c b/hal/phydm/phydm_cck_pd.c index 1cdb2fe..24e37dc 100644 --- a/hal/phydm/phydm_cck_pd.c +++ b/hal/phydm/phydm_cck_pd.c @@ -221,6 +221,101 @@ void phydm_set_cckpd_lv_type2(void *dm_void, enum cckpd_lv lv) phydm_write_cck_pd_type2(dm, pd_th, cs_ratio); } +#if 0 +void phydm_set_cckpd_lv_type2_bcn(void *dm_void, enum cckpd_lv lv) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + u8 pd_th = 0, cs_ratio = 0, cs_2r_offset = 0; + u8 cck_n_rx = 1; + u8 cs_ratio_pre = 0; + u8 bcn_cnt = dm->phy_dbg_info.beacon_cnt_in_period; //BCN CNT + u8 ofst = 0; + u8 ofst_direc = 0; //0:+, 1:- + + PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__); + PHYDM_DBG(dm, DBG_CCKPD, "lv: (%d) -> (%d)\n", cckpd_t->cck_pd_lv, lv); + + /*@r_mrx & r_cca_mrc*/ + cck_n_rx = (odm_get_bb_reg(dm, R_0xa2c, BIT(18)) && + odm_get_bb_reg(dm, R_0xa2c, BIT(22))) ? 2 : 1; + cs_ratio_pre = (u8)((odm_get_bb_reg(dm, R_0xaa8, 0x1f0000))); + PHYDM_DBG(dm, DBG_CCKPD, "BCN: %d, pre CS ratio: 0x%x\n", bcn_cnt, + cs_ratio_pre); + + if (cckpd_t->cck_pd_lv == lv && cckpd_t->cck_n_rx == cck_n_rx && + (bcn_cnt >= 10 && bcn_cnt < 14)) { + PHYDM_DBG(dm, DBG_CCKPD, "BCN ok, stay lv=%d, cs ratio=0x%x\n", + lv, cs_ratio_pre); + return; + } + + cckpd_t->cck_n_rx = cck_n_rx; + cckpd_t->cck_pd_lv = lv; + cckpd_t->cck_fa_ma = CCK_FA_MA_RESET; + + if (lv == CCK_PD_LV_4) { + cs_ratio = cckpd_t->aaa_default + 8; + cs_2r_offset = 5; + pd_th = 0xd; + } else if (lv == CCK_PD_LV_3) { + cs_ratio = cckpd_t->aaa_default + 6; + cs_2r_offset = 4; + pd_th = 0xd; + } else if (lv == CCK_PD_LV_2) { + cs_ratio = cckpd_t->aaa_default + 4; + cs_2r_offset = 3; + pd_th = 0xd; + } else if (lv == CCK_PD_LV_1) { + cs_ratio = cckpd_t->aaa_default + 2; + cs_2r_offset = 1; + pd_th = 0x7; + } else if (lv == CCK_PD_LV_0) { + cs_ratio = cckpd_t->aaa_default; + cs_2r_offset = 0; + pd_th = 0x3; + } + + if (cckpd_t->cck_n_rx == 2) { + if (cs_ratio >= cs_2r_offset) + cs_ratio = cs_ratio - cs_2r_offset; + else + cs_ratio = 0; + } + + if (bcn_cnt >= 18) { + ofst_direc = 0; + ofst = 0x2; + } else if (bcn_cnt >= 14) { + ofst_direc = 0; + ofst = 0x1; + } else if (bcn_cnt >= 10) { + ofst_direc = 0; + ofst = 0x0; + } else if (bcn_cnt >= 5) { + ofst_direc = 1; + ofst = 0x3; + } else { + ofst_direc = 1; + ofst = 0x4; + } + PHYDM_DBG(dm, DBG_CCKPD, "bcn:(%d), ofst:(%s%d)\n", bcn_cnt, + ((ofst_direc) ? "-" : "+"), ofst); + + if (ofst_direc == 0) + cs_ratio = cs_ratio + ofst; + else + cs_ratio = cs_ratio - ofst; + + if (cs_ratio == cs_ratio_pre) { + PHYDM_DBG(dm, DBG_CCKPD, "Same cs ratio, lv=%d cs_ratio=0x%x\n", + lv, cs_ratio); + return; + } + phydm_write_cck_pd_type2(dm, pd_th, cs_ratio); +} +#endif + void phydm_cckpd_type2(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -412,12 +507,6 @@ void phydm_set_cckpd_lv_type3(void *dm_void, enum cckpd_lv lv) pd_th += 1; cs_ratio += 1; } - #if 0 - else if (lv == CCK_PD_LV_0) { - pd_th += 0; - cs_ratio += 0; - } - #endif phydm_write_cck_pd_type3(dm, pd_th, cs_ratio, cck_mode); } @@ -450,6 +539,17 @@ void phydm_cckpd_type3(void *dm_void) else is_update = false; } + if (igi >= 0x20 && dm->rssi_min >= 27) { + //printf(">>>>>TUYA CCK FA CNT = %d, RSSI = %d, IGI =%d \n", cckpd_t->cck_fa_ma, dm->rssi_min, igi); + is_update = false; + odm_set_bb_reg(dm, R_0xa08, BIT(21) | BIT(20), 0x2); + //odm_set_bb_reg(dm, R_0xac8, 0xff, 0x18); + } + else { + //printf("CCK FA CNT = %d, RSSI = %d, IGI =%d \n", cckpd_t->cck_fa_ma, dm->rssi_min, igi); + odm_set_bb_reg(dm, R_0xa08, BIT(21) | BIT(20), cckpd_t->cck_din_shift_opt); + //odm_set_bb_reg(dm, R_0xac8, 0xff, cckpd_t->cck_pd_20m_1r); + } } else { if (cckpd_t->cck_fa_ma > 1000) lv = CCK_PD_LV_1; @@ -496,6 +596,7 @@ void phydm_cck_pd_init_type3(void *dm_void) cckpd_t->cck_pd_20m_2r = (u8)odm_get_bb_reg(dm, R_0xac8, 0xff00); cckpd_t->cck_pd_40m_1r = (u8)odm_get_bb_reg(dm, R_0xacc, 0xff); cckpd_t->cck_pd_40m_2r = (u8)odm_get_bb_reg(dm, R_0xacc, 0xff00); + cckpd_t->cck_din_shift_opt = (u8)odm_get_bb_reg(dm, R_0xa08, BIT(21) | BIT(20)); reg_tmp = odm_get_bb_reg(dm, R_0xad0, MASKDWORD); cckpd_t->cck_cs_ratio_20m_1r = (u8)(reg_tmp & 0x1f); @@ -517,65 +618,65 @@ void phydm_write_cck_pd_type4(void *dm_void, enum cckpd_lv lv, switch (mode) { case CCK_BW20_1R: /*RFBW20_1R*/ { - val = cckpd_t->cck_pd_table_jgr3[0][0][0][lv]; + val = cckpd_t->cckpd_jgr3[0][0][0][lv]; odm_set_bb_reg(dm, R_0x1ac8, 0xff, val); - val = cckpd_t->cck_pd_table_jgr3[0][0][1][lv]; + val = cckpd_t->cckpd_jgr3[0][0][1][lv]; odm_set_bb_reg(dm, R_0x1ad0, 0x1f, val); } break; case CCK_BW40_1R: /*RFBW40_1R*/ { - val = cckpd_t->cck_pd_table_jgr3[1][0][0][lv]; + val = cckpd_t->cckpd_jgr3[1][0][0][lv]; odm_set_bb_reg(dm, R_0x1acc, 0xff, val); - val = cckpd_t->cck_pd_table_jgr3[1][0][1][lv]; + val = cckpd_t->cckpd_jgr3[1][0][1][lv]; odm_set_bb_reg(dm, R_0x1ad0, 0x01F00000, val); } break; #if (defined(PHYDM_COMPILE_ABOVE_2SS)) case CCK_BW20_2R: /*RFBW20_2R*/ { - val = cckpd_t->cck_pd_table_jgr3[0][1][0][lv]; + val = cckpd_t->cckpd_jgr3[0][1][0][lv]; odm_set_bb_reg(dm, R_0x1ac8, 0xff00, val); - val = cckpd_t->cck_pd_table_jgr3[0][1][1][lv]; + val = cckpd_t->cckpd_jgr3[0][1][1][lv]; odm_set_bb_reg(dm, R_0x1ad0, 0x3e0, val); } break; case CCK_BW40_2R: /*RFBW40_2R*/ { - val = cckpd_t->cck_pd_table_jgr3[1][1][0][lv]; + val = cckpd_t->cckpd_jgr3[1][1][0][lv]; odm_set_bb_reg(dm, R_0x1acc, 0xff00, val); - val = cckpd_t->cck_pd_table_jgr3[1][1][1][lv]; + val = cckpd_t->cckpd_jgr3[1][1][1][lv]; odm_set_bb_reg(dm, R_0x1ad0, 0x3E000000, val); } break; #endif #if (defined(PHYDM_COMPILE_ABOVE_3SS)) case CCK_BW20_3R: /*RFBW20_3R*/ { - val = cckpd_t->cck_pd_table_jgr3[0][2][0][lv]; + val = cckpd_t->cckpd_jgr3[0][2][0][lv]; odm_set_bb_reg(dm, R_0x1ac8, 0xff0000, val); - val = cckpd_t->cck_pd_table_jgr3[0][2][1][lv]; + val = cckpd_t->cckpd_jgr3[0][2][1][lv]; odm_set_bb_reg(dm, R_0x1ad0, 0x7c00, val); } break; case CCK_BW40_3R: /*RFBW40_3R*/ { - val = cckpd_t->cck_pd_table_jgr3[1][2][0][lv]; + val = cckpd_t->cckpd_jgr3[1][2][0][lv]; odm_set_bb_reg(dm, R_0x1acc, 0xff0000, val); - val = cckpd_t->cck_pd_table_jgr3[1][2][1][lv] & 0x3; + val = cckpd_t->cckpd_jgr3[1][2][1][lv] & 0x3; odm_set_bb_reg(dm, R_0x1ad0, 0xC0000000, val); - val = (cckpd_t->cck_pd_table_jgr3[1][2][1][lv] & 0x1c) >> 2; + val = (cckpd_t->cckpd_jgr3[1][2][1][lv] & 0x1c) >> 2; odm_set_bb_reg(dm, R_0x1ad4, 0x7, val); } break; #endif #if (defined(PHYDM_COMPILE_ABOVE_4SS)) case CCK_BW20_4R: /*RFBW20_4R*/ { - val = cckpd_t->cck_pd_table_jgr3[0][3][0][lv]; + val = cckpd_t->cckpd_jgr3[0][3][0][lv]; odm_set_bb_reg(dm, R_0x1ac8, 0xff000000, val); - val = cckpd_t->cck_pd_table_jgr3[0][3][1][lv]; + val = cckpd_t->cckpd_jgr3[0][3][1][lv]; odm_set_bb_reg(dm, R_0x1ad0, 0xF8000, val); } break; case CCK_BW40_4R: /*RFBW40_4R*/ { - val = cckpd_t->cck_pd_table_jgr3[1][3][0][lv]; + val = cckpd_t->cckpd_jgr3[1][3][0][lv]; odm_set_bb_reg(dm, R_0x1acc, 0xff000000, val); - val = cckpd_t->cck_pd_table_jgr3[1][3][1][lv]; + val = cckpd_t->cckpd_jgr3[1][3][1][lv]; odm_set_bb_reg(dm, R_0x1ad4, 0xf8, val); } break; #endif @@ -677,6 +778,9 @@ void phydm_read_cckpd_para_type4(void *dm_void) u32 reg2 = 0; u32 reg3 = 0; + if (!(dm->debug_components & DBG_CCKPD)) + return; + bw = (u8)odm_get_bb_reg(dm, R_0x9b0, 0xc); n_rx = (u8)odm_get_bb_reg(dm, R_0x1a2c, 0x60000) + 1; @@ -702,7 +806,7 @@ void phydm_read_cckpd_para_type4(void *dm_void) curr_cck_pd_t[1][2][0] = (u8)((reg1 & 0x00ff0000) >> 16); curr_cck_pd_t[0][2][1] = (u8)((reg2 & 0x00007C00) >> 10); curr_cck_pd_t[1][2][1] = (u8)((reg2 & 0xC0000000) >> 30) | - (u8)((reg3 & 0x00000007) << 3); + (u8)((reg3 & 0x00000007) << 2); } #endif #if (defined(PHYDM_COMPILE_ABOVE_4SS)) @@ -733,6 +837,29 @@ void phydm_cckpd_type4(void *dm_void) if (dm->is_linked) { PHYDM_DBG(dm, DBG_CCKPD, "Linked!!!\n"); + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) + if (dm->rssi_min > 40) { + lv = CCK_PD_LV_4; + PHYDM_DBG(dm, DBG_CCKPD, "Order 1\n"); + } else if (dm->rssi_min > 32) { + lv = CCK_PD_LV_3; + PHYDM_DBG(dm, DBG_CCKPD, "Order 2\n"); + } else if (dm->rssi_min > 24) { + lv = CCK_PD_LV_2; + PHYDM_DBG(dm, DBG_CCKPD, "Order 3\n"); + } else { + if (cckpd_t->cck_fa_ma > 1000) { + lv = CCK_PD_LV_1; + PHYDM_DBG(dm, DBG_CCKPD, "Order 4-1\n"); + } else if (cckpd_t->cck_fa_ma < 500) { + lv = CCK_PD_LV_0; + PHYDM_DBG(dm, DBG_CCKPD, "Order 4-2\n"); + } else { + is_update = false; + PHYDM_DBG(dm, DBG_CCKPD, "Order 4-3\n"); + } + } + #else /*ODM_AP*/ if (igi > 0x38 && dm->rssi_min > 32) { lv = CCK_PD_LV_4; PHYDM_DBG(dm, DBG_CCKPD, "Order 1\n"); @@ -754,6 +881,7 @@ void phydm_cckpd_type4(void *dm_void) PHYDM_DBG(dm, DBG_CCKPD, "Order 4-3\n"); } } + #endif } else { PHYDM_DBG(dm, DBG_CCKPD, "UnLinked!!!\n"); if (cckpd_t->cck_fa_ma > 1000) { @@ -772,9 +900,9 @@ void phydm_cckpd_type4(void *dm_void) phydm_set_cck_pd_lv_type4(dm, lv); PHYDM_DBG(dm, DBG_CCKPD, "setting CS_th = 0x%x, PD th = 0x%x\n", - cckpd_t->cck_pd_table_jgr3[cckpd_t->cck_bw] + cckpd_t->cckpd_jgr3[cckpd_t->cck_bw] [cckpd_t->cck_n_rx - 1][1][lv], - cckpd_t->cck_pd_table_jgr3[cckpd_t->cck_bw] + cckpd_t->cckpd_jgr3[cckpd_t->cck_bw] [cckpd_t->cck_n_rx - 1][0][lv]); } phydm_read_cckpd_para_type4(dm); @@ -788,7 +916,8 @@ void phydm_cck_pd_init_type4(void *dm_void) u32 reg1 = 0; u32 reg2 = 0; u32 reg3 = 0; - u8 pd_step = 0; + u8 pw_step = 0; + u8 cs_step = 0; u8 cck_bw = 0; /*r_RX_RF_BW*/ u8 cck_n_rx = 0; u8 val = 0; @@ -815,7 +944,7 @@ void phydm_cck_pd_init_type4(void *dm_void) *cckpd_t[1][0][1][0] = 1ad0[24:20] r_CS_ratio_RFBW40_1R[4:0] *cckpd_t[1][1][1][0] = 1ad0[29:25] r_CS_ratio_RFBW40_2R[4:0] *cckpd_t[1][2][1][0] = 1ad0[31:30] r_CS_ratio_RFBW40_3R[1:0] - * 1ad4[2:0] r_CS_ratio_RFBW40_3R[4:2] + * 1ad4[2:0] r_CS_ratio_RFBW40_3R[4:2] *cckpd_t[1][3][1][0] = 1ad4[7:3] r_CS_ratio_RFBW40_4R[4:0] */ #endif @@ -839,65 +968,95 @@ void phydm_cck_pd_init_type4(void *dm_void) reg3 = odm_get_bb_reg(dm, R_0x1ad4, MASKDWORD); for (i = 0 ; i < CCK_PD_LV_MAX ; i++) { - pd_step = i * 2; + pw_step = i * 2; + cs_step = i * 2; - val = (u8)(reg0 & 0x000000ff) + pd_step; + #if (RTL8197G_SUPPORT) + if (dm->support_ic_type & ODM_RTL8197G) { + pw_step = i; + cs_step = i; + if (i > CCK_PD_LV_3) { + pw_step = 3; + cs_step = 3; + } + } + #endif + + #if (RTL8822C_SUPPORT) + if (dm->support_ic_type & ODM_RTL8822C) { + if (i == CCK_PD_LV_1) { + pw_step = 9; /*IGI-19.2:0x11=d'17*/ + cs_step = 0; + } else if (i == CCK_PD_LV_2) { + pw_step = 12; /*IGI-15.5:0x14=d'20*/ + cs_step = 1; + } else if (i == CCK_PD_LV_3) { + pw_step = 14; /*IGI-14:0x16=d'22*/ + cs_step = 1; + } else if (i == CCK_PD_LV_4) { + pw_step = 17; /*IGI-12:0x19=d'25*/ + cs_step = 1; + } + } + #endif + + val = (u8)(reg0 & 0x000000ff) + pw_step; PHYDM_DBG(dm, DBG_CCKPD, "lvl %d val = %x\n\n", i, val); - cckpd_t->cck_pd_table_jgr3[0][0][0][i] = val; + cckpd_t->cckpd_jgr3[0][0][0][i] = val; - val = (u8)(reg1 & 0x000000ff) + pd_step; - cckpd_t->cck_pd_table_jgr3[1][0][0][i] = val; + val = (u8)(reg1 & 0x000000ff) + pw_step; + cckpd_t->cckpd_jgr3[1][0][0][i] = val; - val = (u8)(reg2 & 0x0000001F) + pd_step; - cckpd_t->cck_pd_table_jgr3[0][0][1][i] = val; + val = (u8)(reg2 & 0x0000001f) + cs_step; + cckpd_t->cckpd_jgr3[0][0][1][i] = val; - val = (u8)((reg2 & 0x01F00000) >> 20) + pd_step; - cckpd_t->cck_pd_table_jgr3[1][0][1][i] = val; + val = (u8)((reg2 & 0x01f00000) >> 20) + cs_step; + cckpd_t->cckpd_jgr3[1][0][1][i] = val; #ifdef PHYDM_COMPILE_ABOVE_2SS if (dm->support_ic_type & PHYDM_IC_ABOVE_2SS) { - val = (u8)((reg0 & 0x0000ff00) >> 8) + pd_step; - cckpd_t->cck_pd_table_jgr3[0][1][0][i] = val; + val = (u8)((reg0 & 0x0000ff00) >> 8) + pw_step; + cckpd_t->cckpd_jgr3[0][1][0][i] = val; - val = (u8)((reg1 & 0x0000ff00) >> 8) + pd_step; - cckpd_t->cck_pd_table_jgr3[1][1][0][i] = val; + val = (u8)((reg1 & 0x0000ff00) >> 8) + pw_step; + cckpd_t->cckpd_jgr3[1][1][0][i] = val; - val = (u8)((reg2 & 0x000003E0) >> 5) + pd_step; - cckpd_t->cck_pd_table_jgr3[0][1][1][i] = val; + val = (u8)((reg2 & 0x000003e0) >> 5) + cs_step; + cckpd_t->cckpd_jgr3[0][1][1][i] = val; - val = (u8)((reg2 & 0x3E000000) >> 25) + pd_step; - cckpd_t->cck_pd_table_jgr3[1][1][1][i] = val; + val = (u8)((reg2 & 0x3e000000) >> 25) + cs_step; + cckpd_t->cckpd_jgr3[1][1][1][i] = val; } #endif #ifdef PHYDM_COMPILE_ABOVE_3SS if (dm->support_ic_type & PHYDM_IC_ABOVE_3SS) { - val = (u8)((reg0 & 0x00ff0000) >> 16) + pd_step; - cckpd_t->cck_pd_table_jgr3[0][2][0][i] = val; + val = (u8)((reg0 & 0x00ff0000) >> 16) + pw_step; + cckpd_t->cckpd_jgr3[0][2][0][i] = val; - val = (u8)((reg1 & 0x00ff0000) >> 16) + pd_step; - cckpd_t->cck_pd_table_jgr3[1][2][0][i] = val; - val = (u8)((reg2 & 0x00007C00) >> 10) + pd_step; - cckpd_t->cck_pd_table_jgr3[0][2][1][i] = val; - val = (u8)(((reg2 & 0xC0000000) >> 30) | - ((reg3 & 0x7) << 3)) + pd_step; - cckpd_t->cck_pd_table_jgr3[1][2][1][i] = val; + val = (u8)((reg1 & 0x00ff0000) >> 16) + pw_step; + cckpd_t->cckpd_jgr3[1][2][0][i] = val; + val = (u8)((reg2 & 0x00007c00) >> 10) + cs_step; + cckpd_t->cckpd_jgr3[0][2][1][i] = val; + val = (u8)(((reg2 & 0xc0000000) >> 30) | + ((reg3 & 0x7) << 3)) + cs_step; + cckpd_t->cckpd_jgr3[1][2][1][i] = val; } #endif #ifdef PHYDM_COMPILE_ABOVE_4SS if (dm->support_ic_type & PHYDM_IC_ABOVE_4SS) { - val = (u8)((reg0 & 0xff000000) >> 24) + pd_step; - cckpd_t->cck_pd_table_jgr3[0][3][0][i] = val; + val = (u8)((reg0 & 0xff000000) >> 24) + pw_step; + cckpd_t->cckpd_jgr3[0][3][0][i] = val; - val = (u8)((reg1 & 0xff000000) >> 24) + pd_step; - cckpd_t->cck_pd_table_jgr3[1][3][0][i] = val; + val = (u8)((reg1 & 0xff000000) >> 24) + pw_step; + cckpd_t->cckpd_jgr3[1][3][0][i] = val; - val = (u8)((reg2 & 0x000F8000) >> 15) + pd_step; - cckpd_t->cck_pd_table_jgr3[0][3][1][i] = val; + val = (u8)((reg2 & 0x000f8000) >> 15) + cs_step; + cckpd_t->cckpd_jgr3[0][3][1][i] = val; - val = (u8)((reg3 & 0x000000F8) >> 3) + pd_step; - cckpd_t->cck_pd_table_jgr3[1][3][1][i] = val; + val = (u8)((reg3 & 0x000000f8) >> 3) + cs_step; + cckpd_t->cckpd_jgr3[1][3][1][i] = val; } #endif } @@ -909,45 +1068,486 @@ void phydm_invalid_cckpd_type4(void *dm_void) struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; u8 val = 0; u8 i = 0; + u8 j = 0; u8 k = 0; PHYDM_DBG(dm, DBG_CCKPD, "[%s]======>\n", __func__); for (i = 0; i < CCK_PD_LV_MAX; i++) { - for (k = RF_PATH_A; k < dm->num_rf_path; k++) { - val = cckpd_t->cck_pd_table_jgr3[0][k][1][i]; - - if (val == INVALID_CS_RATIO_0) - cckpd_t->cck_pd_table_jgr3[0][k][1][i] = 28; - else if (val == INVALID_CS_RATIO_1) - cckpd_t->cck_pd_table_jgr3[0][k][1][i] = 30; - else if (val > MAXVALID_CS_RATIO) - cckpd_t->cck_pd_table_jgr3[0][k][1][i] = - MAXVALID_CS_RATIO; - val = cckpd_t->cck_pd_table_jgr3[1][k][1][i]; - - if (val == INVALID_CS_RATIO_0) - cckpd_t->cck_pd_table_jgr3[1][k][1][i] = 28; - else if (val == INVALID_CS_RATIO_1) - cckpd_t->cck_pd_table_jgr3[1][k][1][i] = 30; - else if (val > MAXVALID_CS_RATIO) - cckpd_t->cck_pd_table_jgr3[1][k][1][i] = - MAXVALID_CS_RATIO; - val = cckpd_t->cck_pd_table_jgr3[0][k][0][i]; - - if (val > MAXVALID_PD_THRES) - cckpd_t->cck_pd_table_jgr3[0][k][0][i] = - MAXVALID_PD_THRES; - val = cckpd_t->cck_pd_table_jgr3[1][k][0][i]; - if (val > MAXVALID_PD_THRES) - cckpd_t->cck_pd_table_jgr3[1][k][0][i] = - MAXVALID_PD_THRES; + for (j = 0; j < 2; j++) { + for (k = 0; k < dm->num_rf_path; k++) { + val = cckpd_t->cckpd_jgr3[j][k][1][i]; + if (val == INVALID_CS_RATIO_0) + cckpd_t->cckpd_jgr3[j][k][1][i] = 0x1c; + else if (val == INVALID_CS_RATIO_1) + cckpd_t->cckpd_jgr3[j][k][1][i] = 0x1e; + else if (val > MAXVALID_CS_RATIO) + cckpd_t->cckpd_jgr3[j][k][1][i] = + MAXVALID_CS_RATIO; + } } + + #if (RTL8198F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8198F) { + val = cckpd_t->cckpd_jgr3[0][3][1][i]; + if (i == CCK_PD_LV_1 && val > 0x10) + cckpd_t->cckpd_jgr3[0][3][1][i] = 0x10; + else if (i == CCK_PD_LV_2 && val > 0x10) + cckpd_t->cckpd_jgr3[0][3][1][i] = 0x10; + else if (i == CCK_PD_LV_3 && val > 0x10) + cckpd_t->cckpd_jgr3[0][3][1][i] = 0x10; + else if (i == CCK_PD_LV_4 && val > 0x10) + cckpd_t->cckpd_jgr3[0][3][1][i] = 0x10; + val = cckpd_t->cckpd_jgr3[1][3][1][i]; + if (i == CCK_PD_LV_1 && val > 0xF) + cckpd_t->cckpd_jgr3[1][3][1][i] = 0xF; + else if (i == CCK_PD_LV_2 && val > 0xF) + cckpd_t->cckpd_jgr3[1][3][1][i] = 0xF; + else if (i == CCK_PD_LV_3 && val > 0xF) + cckpd_t->cckpd_jgr3[1][3][1][i] = 0xF; + else if (i == CCK_PD_LV_4 && val > 0xF) + cckpd_t->cckpd_jgr3[1][3][1][i] = 0xF; + } + #endif } } #endif /*#ifdef PHYDM_COMPILE_CCKPD_TYPE4*/ + +#ifdef PHYDM_COMPILE_CCKPD_TYPE5 +void phydm_write_cck_pd_type5(void *dm_void, enum cckpd_lv lv, + enum cckpd_mode mode) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + u32 val = 0; + + PHYDM_DBG(dm, DBG_CCKPD, "write CCK CCA parameters(CS_ratio & PD)\n"); + switch (mode) { + case CCK_BW20_1R: /*RFBW20_1R*/ + { + val = cckpd_t->cck_pd_table_jgr3[0][0][0][lv]; + odm_set_bb_reg(dm, R_0x1a30, 0x1f, val); + val = cckpd_t->cck_pd_table_jgr3[0][0][1][lv]; + odm_set_bb_reg(dm, R_0x1a20, 0x1f, val); + } break; + case CCK_BW40_1R: /*RFBW40_1R*/ + { + val = cckpd_t->cck_pd_table_jgr3[1][0][0][lv]; + odm_set_bb_reg(dm, R_0x1a34, 0x1f, val); + val = cckpd_t->cck_pd_table_jgr3[1][0][1][lv]; + odm_set_bb_reg(dm, R_0x1a24, 0x1f, val); + } break; + #if (defined(PHYDM_COMPILE_ABOVE_2SS)) + case CCK_BW20_2R: /*RFBW20_2R*/ + { + val = cckpd_t->cck_pd_table_jgr3[0][1][0][lv]; + odm_set_bb_reg(dm, R_0x1a30, 0x3e0, val); + val = cckpd_t->cck_pd_table_jgr3[0][1][1][lv]; + odm_set_bb_reg(dm, R_0x1a20, 0x3e0, val); + } break; + case CCK_BW40_2R: /*RFBW40_2R*/ + { + val = cckpd_t->cck_pd_table_jgr3[1][1][0][lv]; + odm_set_bb_reg(dm, R_0x1a34, 0x3e0, val); + val = cckpd_t->cck_pd_table_jgr3[1][1][1][lv]; + odm_set_bb_reg(dm, R_0x1a24, 0x3e0, val); + } break; + #endif + #if (defined(PHYDM_COMPILE_ABOVE_3SS)) + case CCK_BW20_3R: /*RFBW20_3R*/ + { + val = cckpd_t->cck_pd_table_jgr3[0][2][0][lv]; + odm_set_bb_reg(dm, R_0x1a30, 0x7c00, val); + val = cckpd_t->cck_pd_table_jgr3[0][2][1][lv]; + odm_set_bb_reg(dm, R_0x1a20, 0x7c00, val); + } break; + case CCK_BW40_3R: /*RFBW40_3R*/ + { + val = cckpd_t->cck_pd_table_jgr3[1][2][0][lv]; + odm_set_bb_reg(dm, R_0x1a34, 0x7c00, val); + val = cckpd_t->cck_pd_table_jgr3[1][2][1][lv]; + odm_set_bb_reg(dm, R_0x1a24, 0x7c00, val); + } break; + #endif + #if (defined(PHYDM_COMPILE_ABOVE_4SS)) + case CCK_BW20_4R: /*RFBW20_4R*/ + { + val = cckpd_t->cck_pd_table_jgr3[0][3][0][lv]; + odm_set_bb_reg(dm, R_0x1a30, 0xF8000, val); + val = cckpd_t->cck_pd_table_jgr3[0][3][1][lv]; + odm_set_bb_reg(dm, R_0x1a20, 0xF8000, val); + } break; + case CCK_BW40_4R: /*RFBW40_4R*/ + { + val = cckpd_t->cck_pd_table_jgr3[1][3][0][lv]; + odm_set_bb_reg(dm, R_0x1a34, 0xF8000, val); + val = cckpd_t->cck_pd_table_jgr3[1][3][1][lv]; + odm_set_bb_reg(dm, R_0x1a24, 0xF8000, val); + } break; + #endif + default: + /*@pr_debug("[%s] warning!\n", __func__);*/ + break; + } +} + + +void phydm_set_cck_pd_lv_type5(void *dm_void, enum cckpd_lv lv) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + enum cckpd_mode cck_mode = CCK_BW20_1R; + enum channel_width cck_bw = CHANNEL_WIDTH_20; + u8 cck_n_rx = 0; + u32 val = 0; + /*u32 val_dbg = 0;*/ + + PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__); + PHYDM_DBG(dm, DBG_CCKPD, "lv: (%d) -> (%d)\n", cckpd_t->cck_pd_lv, lv); + + /*[Check Nrx] for 8723F*/ + cck_n_rx = 1; + + /*[Check BW]*/ + val = odm_get_bb_reg(dm, R_0x9b0, 0xc); + if (val == 0) + cck_bw = CHANNEL_WIDTH_20; + else if (val == 1) + cck_bw = CHANNEL_WIDTH_40; + else + cck_bw = CHANNEL_WIDTH_80; + + /*[Check LV]*/ + if (cckpd_t->cck_pd_lv == lv && + cckpd_t->cck_n_rx == cck_n_rx && + cckpd_t->cck_bw == cck_bw) { + PHYDM_DBG(dm, DBG_CCKPD, "stay in lv=%d\n", lv); + return; + } + cckpd_t->cck_bw = cck_bw; + cckpd_t->cck_n_rx = cck_n_rx; + cckpd_t->cck_pd_lv = lv; + cckpd_t->cck_fa_ma = CCK_FA_MA_RESET; + + switch (cck_n_rx) { + case 1: /*1R*/ + { + if (cck_bw == CHANNEL_WIDTH_20) + cck_mode = CCK_BW20_1R; + else if (cck_bw == CHANNEL_WIDTH_40) + cck_mode = CCK_BW40_1R; + } break; + #if (defined(PHYDM_COMPILE_ABOVE_2SS)) + case 2: /*2R*/ + { + if (cck_bw == CHANNEL_WIDTH_20) + cck_mode = CCK_BW20_2R; + else if (cck_bw == CHANNEL_WIDTH_40) + cck_mode = CCK_BW40_2R; + } break; + #endif + #if (defined(PHYDM_COMPILE_ABOVE_3SS)) + case 3: /*3R*/ + { + if (cck_bw == CHANNEL_WIDTH_20) + cck_mode = CCK_BW20_3R; + else if (cck_bw == CHANNEL_WIDTH_40) + cck_mode = CCK_BW40_3R; + } break; + #endif + #if (defined(PHYDM_COMPILE_ABOVE_4SS)) + case 4: /*4R*/ + { + if (cck_bw == CHANNEL_WIDTH_20) + cck_mode = CCK_BW20_4R; + else if (cck_bw == CHANNEL_WIDTH_40) + cck_mode = CCK_BW40_4R; + } break; + #endif + default: + /*@pr_debug("[%s] warning!\n", __func__);*/ + break; + } + + + +phydm_write_cck_pd_type5(dm, lv, cck_mode); +} + +void phydm_read_cckpd_para_type5(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + u8 bw = 0; /*r_RX_RF_BW*/ + u8 n_rx = 0; + u8 curr_cck_pd_t[2][4][2]; + u32 reg0 = 0; + u32 reg1 = 0; + u32 reg2 = 0; + u32 reg3 = 0; + + bw = (u8)odm_get_bb_reg(dm, R_0x9b0, 0xc); + + reg0 = odm_get_bb_reg(dm, R_0x1a30, MASKDWORD); + reg1 = odm_get_bb_reg(dm, R_0x1a34, MASKDWORD); + reg2 = odm_get_bb_reg(dm, R_0x1a20, MASKDWORD); + reg3 = odm_get_bb_reg(dm, R_0x1a24, MASKDWORD); + curr_cck_pd_t[0][0][0] = (u8)(reg0 & 0x0000001f); + curr_cck_pd_t[1][0][0] = (u8)(reg1 & 0x0000001f); + curr_cck_pd_t[0][0][1] = (u8)(reg2 & 0x0000001f); + curr_cck_pd_t[1][0][1] = (u8)(reg3 & 0x0000001f); + n_rx = 1; + #if (defined(PHYDM_COMPILE_ABOVE_2SS)) + if (dm->support_ic_type & PHYDM_IC_ABOVE_2SS) { + curr_cck_pd_t[0][1][0] = (u8)((reg0 & 0x000003E0) >> 5); + curr_cck_pd_t[1][1][0] = (u8)((reg1 & 0x000003E0) >> 5); + curr_cck_pd_t[0][1][1] = (u8)((reg2 & 0x000003E0) >> 5); + curr_cck_pd_t[1][1][1] = (u8)((reg3 & 0x000003E0) >> 5); + n_rx = 2; + } + #endif + #if (defined(PHYDM_COMPILE_ABOVE_3SS)) + if (dm->support_ic_type & PHYDM_IC_ABOVE_3SS) { + curr_cck_pd_t[0][2][0] = (u8)((reg0 & 0x00007C00) >> 10); + curr_cck_pd_t[1][2][0] = (u8)((reg1 & 0x00007C00) >> 10); + curr_cck_pd_t[0][2][1] = (u8)((reg2 & 0x00007C00) >> 10); + curr_cck_pd_t[1][2][1] = (u8)((reg3 & 0x00007C00) >> 10); + n_rx = 3; + } + #endif + #if (defined(PHYDM_COMPILE_ABOVE_4SS)) + if (dm->support_ic_type & PHYDM_IC_ABOVE_4SS) { + curr_cck_pd_t[0][3][0] = (u8)((reg0 & 0x000F8000) >> 15); + curr_cck_pd_t[1][3][0] = (u8)((reg1 & 0x000F8000) >> 15); + curr_cck_pd_t[0][3][1] = (u8)((reg2 & 0x000F8000) >> 15); + curr_cck_pd_t[1][3][1] = (u8)((reg3 & 0x000F8000) >> 15); + n_rx = 4; + } + #endif + + PHYDM_DBG(dm, DBG_CCKPD, "bw=%dM, Nrx=%d\n", 20 << bw, n_rx); + PHYDM_DBG(dm, DBG_CCKPD, "lv=%d, readback CS_th=0x%x, PD th=0x%x\n", + cckpd_t->cck_pd_lv, + curr_cck_pd_t[bw][n_rx - 1][1], + curr_cck_pd_t[bw][n_rx - 1][0]); +} + +void phydm_cckpd_type5(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + u8 igi = dm->dm_dig_table.cur_ig_value; + enum cckpd_lv lv = 0; + boolean is_update = true; + + PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__); + + if (dm->is_linked) { + PHYDM_DBG(dm, DBG_CCKPD, "Linked!!!\n"); + if (dm->rssi_min > 40) { + lv = CCK_PD_LV_4; + PHYDM_DBG(dm, DBG_CCKPD, "Order 1\n"); + } else if (dm->rssi_min > 32) { + lv = CCK_PD_LV_3; + PHYDM_DBG(dm, DBG_CCKPD, "Order 2\n"); + } else if (dm->rssi_min > 24) { + lv = CCK_PD_LV_2; + PHYDM_DBG(dm, DBG_CCKPD, "Order 3\n"); + } else { + if (cckpd_t->cck_fa_ma > 1000) { + lv = CCK_PD_LV_1; + PHYDM_DBG(dm, DBG_CCKPD, "Order 4-1\n"); + } else if (cckpd_t->cck_fa_ma < 500) { + lv = CCK_PD_LV_0; + PHYDM_DBG(dm, DBG_CCKPD, "Order 4-2\n"); + } else { + is_update = false; + PHYDM_DBG(dm, DBG_CCKPD, "Order 4-3\n"); + } + } + } else { + PHYDM_DBG(dm, DBG_CCKPD, "UnLinked!!!\n"); + if (cckpd_t->cck_fa_ma > 1000) { + lv = CCK_PD_LV_1; + PHYDM_DBG(dm, DBG_CCKPD, "Order 1\n"); + } else if (cckpd_t->cck_fa_ma < 500) { + lv = CCK_PD_LV_0; + PHYDM_DBG(dm, DBG_CCKPD, "Order 2\n"); + } else { + is_update = false; + PHYDM_DBG(dm, DBG_CCKPD, "Order 3\n"); + } + } + + if (is_update) { + phydm_set_cck_pd_lv_type5(dm, lv); + + PHYDM_DBG(dm, DBG_CCKPD, "setting CS_th = 0x%x, PD th = 0x%x\n", + cckpd_t->cck_pd_table_jgr3[cckpd_t->cck_bw] + [cckpd_t->cck_n_rx - 1][1][lv], + cckpd_t->cck_pd_table_jgr3[cckpd_t->cck_bw] + [cckpd_t->cck_n_rx - 1][0][lv]); + } + + phydm_read_cckpd_para_type5(dm); +} + +void phydm_cck_pd_init_type5(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + u32 reg0 = 0; + u32 reg1 = 0; + u32 reg2 = 0; + u32 reg3 = 0; + u8 pw_step = 0; + u8 cs_step = 0; + u8 cck_bw = 0; /*r_RX_RF_BW*/ + u8 cck_n_rx = 0; + u8 val = 0; + u8 i = 0; + + PHYDM_DBG(dm, DBG_CCKPD, "[%s]======>\n", __func__); + #if 0 + /*@ + *cckpd_t[0][0][0][0] = 1a30[4:0] r_PD_lim_RFBW20_1R + *cckpd_t[0][1][0][0] = 1a30[9:5] r_PD_lim_RFBW20_2R + *cckpd_t[0][2][0][0] = 1a30[14:10] r_PD_lim_RFBW20_3R + *cckpd_t[0][3][0][0] = 1a30[19:15] r_PD_lim_RFBW20_4R + *cckpd_t[1][0][0][0] = 1a34[4:0] r_PD_lim_RFBW40_1R + *cckpd_t[1][1][0][0] = 1a34[9:5] r_PD_lim_RFBW40_2R + *cckpd_t[1][2][0][0] = 1a34[14:10] r_PD_lim_RFBW40_3R + *cckpd_t[1][3][0][0] = 1a34[19:15] r_PD_lim_RFBW40_4R + * + * + *cckpd_t[0][0][1][0] = 1a20[4:0] r_CS_ratio_RFBW20_1R + *cckpd_t[0][1][1][0] = 1a20[9:5] r_CS_ratio_RFBW20_2R + *cckpd_t[0][2][1][0] = 1a20[14:10] r_CS_ratio_RFBW20_3R + *cckpd_t[0][3][1][0] = 1a20[19:15] r_CS_ratio_RFBW20_4R + *cckpd_t[1][0][1][0] = 1a24[4:0] r_CS_ratio_RFBW40_1R + *cckpd_t[1][1][1][0] = 1a24[9:5] r_CS_ratio_RFBW40_2R + *cckpd_t[1][2][1][0] = 1a24[14:10] r_CS_ratio_RFBW40_3R + *cckpd_t[1][3][1][0] = 1a24[19:15] r_CS_ratio_RFBW40_4R + */ + #endif + /*[Check Nrx]*/ + cck_n_rx = 1; + + /*[Check BW]*/ + val = (u8)odm_get_bb_reg(dm, R_0x9b0, 0xc); + if (val == 0) + cck_bw = CHANNEL_WIDTH_20; + else if (val == 1) + cck_bw = CHANNEL_WIDTH_40; + else + cck_bw = CHANNEL_WIDTH_80; + + cckpd_t->cck_bw = cck_bw; + reg0 = odm_get_bb_reg(dm, R_0x1a30, MASKDWORD); + reg1 = odm_get_bb_reg(dm, R_0x1a34, MASKDWORD); + reg2 = odm_get_bb_reg(dm, R_0x1a20, MASKDWORD); + reg3 = odm_get_bb_reg(dm, R_0x1a24, MASKDWORD); + + for (i = 0 ; i < CCK_PD_LV_MAX ; i++) { + pw_step = i * 2; + cs_step = i * 2; + + #if (RTL8723F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8723F) { + if (i == CCK_PD_LV_1) { + pw_step = 9; /*IGI-19.2:0x11=d'17*/ + cs_step = 0; + } else if (i == CCK_PD_LV_2) { + pw_step = 12; /*IGI-15.5:0x14=d'20*/ + cs_step = 1; + } else if (i == CCK_PD_LV_3) { + pw_step = 14; /*IGI-14:0x16=d'22*/ + cs_step = 1; + } else if (i == CCK_PD_LV_4) { + pw_step = 17; /*IGI-12:0x19=d'25*/ + cs_step = 1; + } + } + #endif + val = (u8)(reg0 & 0x0000001F) + pw_step; + PHYDM_DBG(dm, DBG_CCKPD, "lvl %d val = %x\n\n", i, val); + cckpd_t->cck_pd_table_jgr3[0][0][0][i] = val; + + val = (u8)(reg1 & 0x0000001F) + pw_step; + cckpd_t->cck_pd_table_jgr3[1][0][0][i] = val; + + val = (u8)(reg2 & 0x0000001F) + cs_step; + cckpd_t->cck_pd_table_jgr3[0][0][1][i] = val; + + val = (u8)(reg3 & 0x0000001F) + cs_step; + cckpd_t->cck_pd_table_jgr3[1][0][1][i] = val; + + #ifdef PHYDM_COMPILE_ABOVE_2SS + if (dm->support_ic_type & PHYDM_IC_ABOVE_2SS) { + val = (u8)((reg0 & 0x000003E0) >> 5) + pw_step; + cckpd_t->cck_pd_table_jgr3[0][1][0][i] = val; + + val = (u8)((reg1 & 0x000003E0) >> 5) + pw_step; + cckpd_t->cck_pd_table_jgr3[1][1][0][i] = val; + + val = (u8)((reg2 & 0x000003E0) >> 5) + cs_step; + cckpd_t->cck_pd_table_jgr3[0][1][1][i] = val; + + val = (u8)((reg3 & 0x000003E0) >> 5) + cs_step; + cckpd_t->cck_pd_table_jgr3[1][1][1][i] = val; + + cck_n_rx = 2; + } + #endif + #ifdef PHYDM_COMPILE_ABOVE_3SS + if (dm->support_ic_type & PHYDM_IC_ABOVE_3SS) { + val = (u8)((reg0 & 0x00007C00) >> 10) + pw_step; + cckpd_t->cck_pd_table_jgr3[0][2][0][i] = val; + + val = (u8)((reg1 & 0x00007C00) >> 10) + pw_step; + cckpd_t->cck_pd_table_jgr3[1][2][0][i] = val; + + val = (u8)((reg2 & 0x00007C00) >> 10) + cs_step; + cckpd_t->cck_pd_table_jgr3[0][2][1][i] = val; + + val = (u8)((reg3 & 0x00007C00) >> 10) + cs_step; + cckpd_t->cck_pd_table_jgr3[1][2][1][i] = val; + + cck_n_rx = 3; + } + #endif + + #ifdef PHYDM_COMPILE_ABOVE_4SS + if (dm->support_ic_type & PHYDM_IC_ABOVE_4SS) { + val = (u8)((reg0 & 0x000F8000) >> 15) + pw_step; + cckpd_t->cck_pd_table_jgr3[0][3][0][i] = val; + + val = (u8)((reg1 & 0x000F8000) >> 15) + pw_step; + cckpd_t->cck_pd_table_jgr3[1][3][0][i] = val; + + val = (u8)((reg2 & 0x000F8000) >> 15) + cs_step; + cckpd_t->cck_pd_table_jgr3[0][3][1][i] = val; + + val = (u8)((reg3 & 0x000F8000) >> 15) + cs_step; + cckpd_t->cck_pd_table_jgr3[1][3][1][i] = val; + + cck_n_rx = 4; + } + #endif + } + cckpd_t->cck_n_rx = cck_n_rx; +} + + + + +#endif /*#ifdef PHYDM_COMPILE_CCKPD_TYPE5*/ + + + + void phydm_set_cckpd_val(void *dm_void, u32 *val_buf, u8 val_len) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -987,6 +1587,11 @@ void phydm_set_cckpd_val(void *dm_void, u32 *val_buf, u8 val_len) phydm_set_cck_pd_lv_type4(dm, lv); break; #endif + #ifdef PHYDM_COMPILE_CCKPD_TYPE5 + case 5: + phydm_set_cck_pd_lv_type5(dm, lv); + break; + #endif default: pr_debug("[%s]warning\n", __func__); break; @@ -998,8 +1603,13 @@ phydm_stop_cck_pd_th(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; - if (!(dm->support_ability & (ODM_BB_CCK_PD | ODM_BB_FA_CNT))) { - PHYDM_DBG(dm, DBG_CCKPD, "Not Support\n"); + if (!(dm->support_ability & ODM_BB_FA_CNT)) { + PHYDM_DBG(dm, DBG_CCKPD, "Not Support:ODM_BB_FA_CNT disable\n"); + return true; + } + + if (!(dm->support_ability & ODM_BB_CCK_PD)) { + PHYDM_DBG(dm, DBG_CCKPD, "Not Support:ODM_BB_CCK_PD disable\n"); return true; } @@ -1066,7 +1676,17 @@ void phydm_cck_pd_th(void *dm_void) #endif #ifdef PHYDM_COMPILE_CCKPD_TYPE4 case 4: - phydm_cckpd_type4(dm); + #ifdef PHYDM_DCC_ENHANCE + if (dm->dm_dcc_info.dcc_en) + phydm_cckpd_type4_dcc(dm); + else + #endif + phydm_cckpd_type4(dm); + break; + #endif + #ifdef PHYDM_COMPILE_CCKPD_TYPE5 + case 5: + phydm_cckpd_type5(dm); break; #endif default: @@ -1080,6 +1700,9 @@ void phydm_cck_pd_init(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + if (*dm->mp_mode) + return; + if (dm->support_ic_type & CCK_PD_IC_TYPE1) cckpd_t->cckpd_hw_type = 1; else if (dm->support_ic_type & CCK_PD_IC_TYPE2) @@ -1089,36 +1712,46 @@ void phydm_cck_pd_init(void *dm_void) else if (dm->support_ic_type & CCK_PD_IC_TYPE4) cckpd_t->cckpd_hw_type = 4; + if (dm->support_ic_type & CCK_PD_IC_TYPE5) + cckpd_t->cckpd_hw_type = 5; + PHYDM_DBG(dm, DBG_CCKPD, "[%s] cckpd_hw_type=%d\n", __func__, cckpd_t->cckpd_hw_type); cckpd_t->cck_pd_lv = CCK_PD_LV_INIT; cckpd_t->cck_n_rx = 0xff; cckpd_t->cck_bw = CHANNEL_WIDTH_MAX; + cckpd_t->cck_fa_th[1] = 400; + cckpd_t->cck_fa_th[0] = 200; switch (cckpd_t->cckpd_hw_type) { #ifdef PHYDM_COMPILE_CCKPD_TYPE1 case 1: - phydm_set_cckpd_lv_type1(dm, CCK_PD_LV_0); + phydm_set_cckpd_lv_type1(dm, CCK_PD_LV_1); break; #endif #ifdef PHYDM_COMPILE_CCKPD_TYPE2 case 2: cckpd_t->aaa_default = odm_read_1byte(dm, 0xaaa) & 0x1f; - phydm_set_cckpd_lv_type2(dm, CCK_PD_LV_0); + phydm_set_cckpd_lv_type2(dm, CCK_PD_LV_1); break; #endif #ifdef PHYDM_COMPILE_CCKPD_TYPE3 case 3: phydm_cck_pd_init_type3(dm); - phydm_set_cckpd_lv_type3(dm, CCK_PD_LV_0); + phydm_set_cckpd_lv_type3(dm, CCK_PD_LV_1); break; #endif #ifdef PHYDM_COMPILE_CCKPD_TYPE4 case 4: phydm_cck_pd_init_type4(dm); phydm_invalid_cckpd_type4(dm); - phydm_set_cck_pd_lv_type4(dm, CCK_PD_LV_0); + phydm_set_cck_pd_lv_type4(dm, CCK_PD_LV_1); + break; + #endif + #ifdef PHYDM_COMPILE_CCKPD_TYPE5 + case 5: + phydm_cck_pd_init_type5(dm); break; #endif default: @@ -1126,5 +1759,160 @@ void phydm_cck_pd_init(void *dm_void) break; } } + +#ifdef PHYDM_DCC_ENHANCE + +void phydm_cckpd_type4_dcc(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + enum cckpd_lv lv_curr = cckpd_t->cck_pd_lv; + enum phydm_cck_pd_trend trend = CCKPD_STABLE; + u8 th_ofst = 0; + u16 lv_up_th, lv_down_th; + + PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__); + + if (!dm->is_linked) + th_ofst = 1; + + lv_up_th = (cckpd_t->cck_fa_th[1]) << th_ofst; + lv_down_th = (cckpd_t->cck_fa_th[0]) << th_ofst; + + PHYDM_DBG(dm, DBG_CCKPD, "th{Up, Down}: {%d, %d}\n", + lv_up_th, lv_down_th); + + if (cckpd_t->cck_fa_ma > lv_up_th) { + if (lv_curr <= CCK_PD_LV_3) { + lv_curr++; + trend = CCKPD_INCREASING; + } else { + lv_curr = CCK_PD_LV_4; + } + } else if (cckpd_t->cck_fa_ma < lv_down_th) { + if (lv_curr >= CCK_PD_LV_1) { + lv_curr--; + trend = CCKPD_DECREASING; + } else { + lv_curr = CCK_PD_LV_0; + } + } + + PHYDM_DBG(dm, DBG_CCKPD, "lv: %d->%d\n", cckpd_t->cck_pd_lv, lv_curr); +#if 1 + if (trend != CCKPD_STABLE) { + phydm_set_cck_pd_lv_type4(dm, lv_curr); + + PHYDM_DBG(dm, DBG_CCKPD, "setting CS_th = 0x%x, PD th = 0x%x\n", + cckpd_t->cckpd_jgr3[cckpd_t->cck_bw] + [cckpd_t->cck_n_rx - 1][1][lv_curr], + cckpd_t->cckpd_jgr3[cckpd_t->cck_bw] + [cckpd_t->cck_n_rx - 1][0][lv_curr]); + } + phydm_read_cckpd_para_type4(dm); +#endif +} + +boolean phydm_do_cckpd(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_dig_struct *dig_t = &dm->dm_dig_table; + + if (dig_t->igi_trend == DIG_INCREASING) + return false; + + return true; +} + +void phydm_dig_cckpd_coex(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_dcc_struct *dcc = &dm->dm_dcc_info; + + if (*dm->channel > 36) { + phydm_dig(dm); + return; + } else if (!dcc->dcc_en) { + phydm_dig(dm); + phydm_cck_pd_th(dm); + return; + } + + dcc->dig_execute_cnt++; + PHYDM_DBG(dm, DBG_CCKPD, "DCC_cnt: %d\n", dcc->dig_execute_cnt); + + if (dcc->dig_execute_cnt % dcc->dcc_ratio) { + PHYDM_DBG(dm, DBG_CCKPD, "DCC: DIG\n"); + phydm_dig(dm); + } else { + if (phydm_do_cckpd(dm)) { + PHYDM_DBG(dm, DBG_CCKPD, "DCC: CCKPD\n"); + dcc->dcc_mode = DCC_CCK_PD; + phydm_cck_pd_th(dm); + } else { + PHYDM_DBG(dm, DBG_CCKPD, "DCC: Boost_DIG\n"); + dcc->dcc_mode = DCC_DIG; + phydm_dig(dm); + } + } +} + +void phydm_dig_cckpd_coex_init(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_dig_struct *dig_t = &dm->dm_dig_table; + struct phydm_dcc_struct *dcc = &dm->dm_dcc_info; + + dcc->dcc_mode = DCC_DIG; + dcc->dcc_en = false; + dcc->dig_execute_cnt = 0; + dcc->dcc_ratio = 2; +} + +void phydm_dig_cckpd_coex_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + struct phydm_dcc_struct *dcc = &dm->dm_dcc_info; + char help[] = "-h"; + u32 var[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u8 i = 0; + + for (i = 0; i < 3; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var[i]); + } + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "Enable: en {0/1}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "DCC_ratio: ratio {x}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "threshold: th {Down_th} {Up_th}\n"); + } else if ((strcmp(input[1], "en") == 0)) { + dcc->dcc_en = (var[1]) ? true : false; + PDM_SNPF(out_len, used, output + used, out_len - used, + "en=%d\n", dcc->dcc_en); + } else if ((strcmp(input[1], "ratio") == 0)) { + dcc->dcc_ratio = (u8)var[1]; + PDM_SNPF(out_len, used, output + used, out_len - used, + "Ratio=%d\n", dcc->dcc_ratio); + } else if ((strcmp(input[1], "th") == 0)) { + cckpd_t->cck_fa_th[1] = (u16)var[2]; + cckpd_t->cck_fa_th[0] = (u16)var[1]; + PDM_SNPF(out_len, used, output + used, out_len - used, + "th{Down, Up}: {%d, %d}\n", + cckpd_t->cck_fa_th[0], cckpd_t->cck_fa_th[1]); + } + + *_used = used; + *_out_len = out_len; +} + +#endif #endif /*#ifdef PHYDM_SUPPORT_CCKPD*/ diff --git a/hal/phydm/phydm_cck_pd.h b/hal/phydm/phydm_cck_pd.h index 6572f26..2a1d3ea 100644 --- a/hal/phydm/phydm_cck_pd.h +++ b/hal/phydm/phydm_cck_pd.h @@ -26,7 +26,8 @@ #ifndef __PHYDM_CCK_PD_H__ #define __PHYDM_CCK_PD_H__ -#define CCK_PD_VERSION "3.3" /* @ modify invalid type4 API*/ +/* 2019.12.25 decrease CS_ratio in 8822C due to Lenovo test result(PCIE-5136).*/ +#define CCK_PD_VERSION "4.0" /*@ * 1 ============================================================ @@ -35,10 +36,9 @@ */ #define CCK_FA_MA_RESET 0xffffffff -#define INVALID_CS_RATIO_0 27 /* @ only for type4 ICs*/ -#define INVALID_CS_RATIO_1 29 /* @ only for type4 ICs*/ -#define MAXVALID_CS_RATIO 31 -#define MAXVALID_PD_THRES 255 +#define INVALID_CS_RATIO_0 0x1b /* @ only for type4 ICs*/ +#define INVALID_CS_RATIO_1 0x1d /* @ only for type4 ICs*/ +#define MAXVALID_CS_RATIO 0x1f /*@Run time flag of CCK_PD HW type*/ #define CCK_PD_IC_TYPE1 (ODM_RTL8188E | ODM_RTL8812 | ODM_RTL8821 |\ ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8814A |\ @@ -52,6 +52,7 @@ /*@extend for different bw & path*/ #define CCK_PD_IC_TYPE4 ODM_IC_JGR3_SERIES /*@extend for different bw & path*/ +#define CCK_PD_IC_TYPE5 (ODM_RTL8723F) /*@extend for different CR*/ /*@Compile time flag of CCK_PD HW type*/ #if (RTL8188E_SUPPORT || RTL8812A_SUPPORT || RTL8821A_SUPPORT ||\ @@ -73,6 +74,10 @@ #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT #define PHYDM_COMPILE_CCKPD_TYPE4 /*@extend for different bw & path*/ #endif +#if (RTL8723F_SUPPORT) + #define PHYDM_COMPILE_CCKPD_TYPE5 /*@extend for different & path*/ +#endif + /*@ * 1 ============================================================ * 1 enumeration @@ -99,6 +104,17 @@ enum cckpd_mode { CCK_BW40_4R = 7 }; +enum dcc_mode { + DCC_DIG = 0, + DCC_CCK_PD = 1 +}; + +enum phydm_cck_pd_trend { + CCKPD_STABLE = 0, + CCKPD_INCREASING = 1, + CCKPD_DECREASING = 2 +}; + /*@ * 1 ============================================================ * 1 structure @@ -106,6 +122,16 @@ enum cckpd_mode { */ #ifdef PHYDM_SUPPORT_CCKPD + +#ifdef PHYDM_DCC_ENHANCE +struct phydm_dcc_struct { /*DIG CCK_PD coexistence*/ + boolean dcc_en; + enum dcc_mode dcc_mode; + u32 dig_execute_cnt; + u8 dcc_ratio; +}; +#endif + struct phydm_cckpd_struct { u8 cckpd_hw_type; u8 cur_cck_cca_thres; /*@current cck_pd value 0xa0a*/ @@ -113,6 +139,7 @@ struct phydm_cckpd_struct { u32 rvrt_val; /*all rvrt_val for pause API must set to u32*/ u8 pause_lv; u8 cck_n_rx; + u16 cck_fa_th[2]; enum channel_width cck_bw; enum cckpd_lv cck_pd_lv; #ifdef PHYDM_COMPILE_CCKPD_TYPE2 @@ -129,6 +156,7 @@ struct phydm_cckpd_struct { u8 cck_cs_ratio_20m_2r; u8 cck_cs_ratio_40m_1r; u8 cck_cs_ratio_40m_2r; + u8 cck_din_shift_opt; /*Current value*/ u8 cur_cck_pd_20m_1r; u8 cur_cck_pd_20m_2r; @@ -141,6 +169,10 @@ struct phydm_cckpd_struct { #endif #ifdef PHYDM_COMPILE_CCKPD_TYPE4 /*@[bw][nrx][0:PD/1:CS][lv]*/ + u8 cckpd_jgr3[2][4][2][CCK_PD_LV_MAX]; + #endif + #ifdef PHYDM_COMPILE_CCKPD_TYPE5 + /*@[bw][nrx][0:PD/1:CS][lv]*/ u8 cck_pd_table_jgr3[2][4][2][CCK_PD_LV_MAX]; #endif }; @@ -156,4 +188,15 @@ void phydm_set_cckpd_val(void *dm_void, u32 *val_buf, u8 val_len); void phydm_cck_pd_th(void *dm_void); void phydm_cck_pd_init(void *dm_void); + +#ifdef PHYDM_DCC_ENHANCE +void phydm_cckpd_type4_dcc(void *dm_void); + +void phydm_dig_cckpd_coex(void *dm_void); + +void phydm_dig_cckpd_coex_init(void *dm_void); + +void phydm_dig_cckpd_coex_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); +#endif #endif diff --git a/hal/phydm/phydm_cck_rx_pathdiv.c b/hal/phydm/phydm_cck_rx_pathdiv.c index bbe05e3..3106f19 100644 --- a/hal/phydm/phydm_cck_rx_pathdiv.c +++ b/hal/phydm/phydm_cck_rx_pathdiv.c @@ -131,8 +131,7 @@ void phydm_cck_rx_pathdiv_dbg(void *dm_void, char input[][16], u32 *_used, return; for (i = 0; i < 3; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); } if ((strcmp(input[1], help) == 0)) { diff --git a/hal/phydm/phydm_ccx.c b/hal/phydm/phydm_ccx.c index 5e7b25c..6bc88ba 100644 --- a/hal/phydm/phydm_ccx.c +++ b/hal/phydm/phydm_ccx.c @@ -26,6 +26,35 @@ #include "mp_precomp.h" #include "phydm_precomp.h" +u8 phydm_env_mntr_get_802_11_k_rsni(void *dm_void, s8 rcpi, s8 anpi) +{ + u8 rsni = 0; + u8 signal = 0; + u8 sig_to_rsni[13] = {0, 8, 15, 20, 24, 27, 30, 32, 35, 37, 39, 41, 43}; + + /*rcpi = signal + noise + interference = rssi*/ + /*anpi = noise + interferecne = nhm*/ + /*signal = rcpi - anpi*/ + + /*rsni = 2*(10*log10((rcpi_lin/anpi_lin)-1)+10), unit = 0.5dB*/ + /*rcpi_lin/anpi_lin=10^((rcpi_dB-anpi_db)/10)*/ + /*rsni is approximated as 2*((rcpi_db-anpi_db)+10) when signal >= 13*/ + + if (rcpi <= anpi) + signal = 0; + else if (rcpi - anpi >= 117) + signal = 117; + else + signal = rcpi - anpi; + + if (signal < 13) + rsni = sig_to_rsni[signal]; + else + rsni = 2 * (signal + 10); + + return rsni; +} + void phydm_ccx_hw_restart(void *dm_void) /*@Will Restart NHM/CLM/FAHM simultaneously*/ { @@ -48,284 +77,15 @@ void phydm_ccx_hw_restart(void *dm_void) odm_set_bb_reg(dm, reg1, BIT(8), 0x1); } -#ifdef FAHM_SUPPORT - -u16 phydm_hw_divider(void *dm_void, u16 numerator, u16 denumerator) +u8 phydm_ccx_get_rpt_ratio(void *dm_void, u16 rpt, u16 denom) { - struct dm_struct *dm = (struct dm_struct *)dm_void; - u16 result = DEVIDER_ERROR; - u32 tmp_u32 = ((numerator << 16) | denumerator); - u32 reg_devider_input; - u32 reg; - u8 i; + u32 numer = 0; - PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + numer = rpt * 100 + (denom >> 1); - if (dm->support_ic_type & ODM_IC_11AC_SERIES) { - reg_devider_input = 0x1cbc; - reg = 0x1f98; - } else { - reg_devider_input = 0x980; - reg = 0x9f0; - } - - odm_set_bb_reg(dm, reg_devider_input, MASKDWORD, tmp_u32); - - for (i = 0; i < 10; i++) { - ODM_delay_ms(1); - if (odm_get_bb_reg(dm, reg, BIT(24))) { - /*@Chk HW rpt is ready*/ - - result = (u16)odm_get_bb_reg(dm, reg, MASKBYTE2); - break; - } - } - return result; + return (u8)PHYDM_DIV(numer, denom); } -void phydm_fahm_trigger(void *dm_void, u16 tgr_period) -{ /*@unit (4us)*/ - struct dm_struct *dm = (struct dm_struct *)dm_void; - u32 fahm_reg1; - - if (dm->support_ic_type & ODM_IC_11AC_SERIES) { - odm_set_bb_reg(dm, R_0x1cf8, 0xffff00, tgr_period); - - fahm_reg1 = 0x994; - } else { - odm_set_bb_reg(dm, R_0x978, 0xff000000, (tgr_period & 0xff)); - odm_set_bb_reg(dm, R_0x97c, 0xff, (tgr_period & 0xff00) >> 8); - - fahm_reg1 = 0x890; - } - - odm_set_bb_reg(dm, fahm_reg1, BIT(2), 0); - odm_set_bb_reg(dm, fahm_reg1, BIT(2), 1); -} - -void phydm_fahm_set_valid_cnt(void *dm_void, u8 numerator_sel, - u8 denominator_sel) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct ccx_info *ccx_info = &dm->dm_ccx_info; - u32 fahm_reg1; - - PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); - - if (ccx_info->fahm_nume_sel == numerator_sel && - ccx_info->fahm_denom_sel == denominator_sel) { - PHYDM_DBG(dm, DBG_ENV_MNTR, "no need to update\n"); - return; - } - - ccx_info->fahm_nume_sel = numerator_sel; - ccx_info->fahm_denom_sel = denominator_sel; - - if (dm->support_ic_type & ODM_IC_11AC_SERIES) - fahm_reg1 = 0x994; - else - fahm_reg1 = 0x890; - - odm_set_bb_reg(dm, fahm_reg1, 0xe0, numerator_sel); - odm_set_bb_reg(dm, fahm_reg1, 0x7000, denominator_sel); -} - -void phydm_fahm_get_result(void *dm_void) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - u16 fahm_cnt[12]; /*packet count*/ - u16 fahm_rpt[12]; /*percentage*/ - u16 denominator; /*@fahm_denominator packet count*/ - u32 reg_rpt, reg_rpt_2; - u32 reg_tmp; - boolean is_ready = false; - u8 i; - - PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); - - if (dm->support_ic_type & ODM_IC_11AC_SERIES) { - reg_rpt = 0x1f80; - reg_rpt_2 = 0x1f98; - } else { - reg_rpt = 0x9d8; - reg_rpt_2 = 0x9f0; - } - - for (i = 0; i < 3; i++) { - if (odm_get_bb_reg(dm, reg_rpt_2, BIT(31))) { - /*@Chk HW rpt is ready*/ - is_ready = true; - break; - } - ODM_delay_ms(1); - } - - if (!is_ready) - return; - - /*@Get FAHM Denominator*/ - denominator = (u16)odm_get_bb_reg(dm, reg_rpt_2, MASKLWORD); - - PHYDM_DBG(dm, DBG_ENV_MNTR, "Reg[0x%x] fahm_denmrtr = %d\n", reg_rpt_2, - denominator); - - /*@Get FAHM nemerator*/ - for (i = 0; i < 6; i++) { - reg_tmp = odm_get_bb_reg(dm, reg_rpt + (i << 2), MASKDWORD); - - PHYDM_DBG(dm, DBG_ENV_MNTR, "Reg[0x%x] fahm_denmrtr = %d\n", - reg_rpt + (i * 4), reg_tmp); - - fahm_cnt[i * 2] = (u16)(reg_tmp & MASKLWORD); - fahm_cnt[i * 2 + 1] = (u16)((reg_tmp & MASKHWORD) >> 16); - } - - for (i = 0; i < 12; i++) - fahm_rpt[i] = phydm_hw_divider(dm, fahm_cnt[i], denominator); - - PHYDM_DBG(dm, DBG_ENV_MNTR, - "FAHM_RPT_cnt[10:0]=[%d, %d, %d, %d, %d(IGI), %d, %d, %d, %d, %d, %d, %d]\n", - fahm_cnt[11], fahm_cnt[10], fahm_cnt[9], - fahm_cnt[8], fahm_cnt[7], fahm_cnt[6], - fahm_cnt[5], fahm_cnt[4], fahm_cnt[3], - fahm_cnt[2], fahm_cnt[1], fahm_cnt[0]); - - PHYDM_DBG(dm, DBG_ENV_MNTR, - "FAHM_RPT[10:0]=[%d, %d, %d, %d, %d(IGI), %d, %d, %d, %d, %d, %d, %d]\n", - fahm_rpt[11], fahm_rpt[10], fahm_rpt[9], fahm_rpt[8], - fahm_rpt[7], fahm_rpt[6], fahm_rpt[5], fahm_rpt[4], - fahm_rpt[3], fahm_rpt[2], fahm_rpt[1], fahm_rpt[0]); -} - -void phydm_fahm_set_th_by_igi(void *dm_void, u8 igi) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct ccx_info *ccx_info = &dm->dm_ccx_info; - u32 val = 0; - u8 f_th[11]; /*@FAHM Threshold*/ - u8 rssi_th[11]; /*@in RSSI scale*/ - u8 th_gap = 2 * IGI_TO_NHM_TH_MULTIPLIER; /*unit is 0.5dB for FAHM*/ - u8 i; - - PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); - - if (ccx_info->env_mntr_igi == igi) { - PHYDM_DBG(dm, DBG_ENV_MNTR, - "No need to update FAHM_th, IGI=0x%x\n", - ccx_info->env_mntr_igi); - return; - } - - ccx_info->env_mntr_igi = igi; /*@bkp IGI*/ - - if (igi >= CCA_CAP) - f_th[0] = (igi - CCA_CAP) * IGI_TO_NHM_TH_MULTIPLIER; - else - f_th[0] = 0; - - rssi_th[0] = igi - 10 - CCA_CAP; - - for (i = 1; i <= 10; i++) { - f_th[i] = f_th[0] + th_gap * i; - rssi_th[i] = rssi_th[0] + (i << 1); - } - - PHYDM_DBG(dm, DBG_ENV_MNTR, - "FAHM_RSSI_th[10:0]=[%d, %d, %d, (IGI)%d, %d, %d, %d, %d, %d, %d, %d]\n", - rssi_th[10], rssi_th[9], rssi_th[8], rssi_th[7], rssi_th[6], - rssi_th[5], rssi_th[4], rssi_th[3], rssi_th[2], rssi_th[1], - rssi_th[0]); - - if (dm->support_ic_type & ODM_IC_11AC_SERIES) { - val = BYTE_2_DWORD(0, f_th[2], f_th[1], f_th[0]); - odm_set_bb_reg(dm, R_0x1c38, 0xffffff00, val); - val = BYTE_2_DWORD(0, f_th[5], f_th[4], f_th[3]); - odm_set_bb_reg(dm, R_0x1c78, 0xffffff00, val); - val = BYTE_2_DWORD(0, 0, f_th[7], f_th[6]); - odm_set_bb_reg(dm, R_0x1c7c, 0xffff0000, val); - val = BYTE_2_DWORD(0, f_th[10], f_th[9], f_th[8]); - odm_set_bb_reg(dm, R_0x1cb8, 0xffffff00, val); - } else { - val = BYTE_2_DWORD(f_th[3], f_th[2], f_th[1], f_th[0]); - odm_set_bb_reg(dm, R_0x970, MASKDWORD, val); - val = BYTE_2_DWORD(f_th[7], f_th[6], f_th[5], f_th[4]); - odm_set_bb_reg(dm, R_0x974, MASKDWORD, val); - val = BYTE_2_DWORD(0, f_th[10], f_th[9], f_th[8]); - odm_set_bb_reg(dm, R_0x978, 0xffffff, val); - } -} - -void phydm_fahm_init(void *dm_void) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct ccx_info *ccx_info = &dm->dm_ccx_info; - u32 fahm_reg1; - u8 denumerator_sel = 0; - - PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); - PHYDM_DBG(dm, DBG_ENV_MNTR, "IGI=0x%x\n", - dm->dm_dig_table.cur_ig_value); - - if (dm->support_ic_type & ODM_IC_11AC_SERIES) - fahm_reg1 = 0x994; - else - fahm_reg1 = 0x890; - - ccx_info->fahm_period = 65535; - - odm_set_bb_reg(dm, fahm_reg1, 0x6, 3); /*@FAHM HW block enable*/ - - denumerator_sel = FAHM_INCLD_FA | FAHM_INCLD_CRC_OK | FAHM_INCLD_CRC_ER; - phydm_fahm_set_valid_cnt(dm, FAHM_INCLD_FA, denumerator_sel); - phydm_fahm_set_th_by_igi(dm, dm->dm_dig_table.cur_ig_value); -} - -void phydm_fahm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, - u32 *_out_len) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct ccx_info *ccx_info = &dm->dm_ccx_info; - char help[] = "-h"; - u32 var1[10] = {0}; - u32 used = *_used; - u32 out_len = *_out_len; - u32 i; - - for (i = 0; i < 2; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); - } - - if ((strcmp(input[1], help) == 0)) { - PDM_SNPF(out_len, used, output + used, out_len - used, - "{1: trigger, 2:get result}\n"); - PDM_SNPF(out_len, used, output + used, out_len - used, - "{3: MNTR mode sel} {1: driver, 2. FW}\n"); - return; - } else if (var1[0] == 1) { /* Set & trigger CLM */ - - phydm_fahm_set_th_by_igi(dm, dm->dm_dig_table.cur_ig_value); - phydm_fahm_trigger(dm, ccx_info->fahm_period); - PDM_SNPF(out_len, used, output + used, out_len - used, - "Monitor FAHM for %d * 4us\n", ccx_info->fahm_period); - - } else if (var1[0] == 2) { /* @Get CLM results */ - - phydm_fahm_get_result(dm); - PDM_SNPF(out_len, used, output + used, out_len - used, - "FAHM_result=%d us\n", (ccx_info->clm_result << 2)); - - } else { - PDM_SNPF(out_len, used, output + used, out_len - used, - "Error\n"); - } - - *_used = used; - *_out_len = out_len; -} - -#endif /*@#ifdef FAHM_SUPPORT*/ - #ifdef NHM_SUPPORT void phydm_nhm_racing_release(void *dm_void) @@ -428,21 +188,124 @@ phydm_nhm_check_rdy(void *dm_void) return is_ready; } +void phydm_nhm_cal_wgt(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 i = 0; + + for (i = 0; i < NHM_RPT_NUM; i++) { + if (i == 0) + ccx->nhm_wgt[0] = (u8)(MAX_2(ccx->nhm_th[0] - 2, 0)); + else if (i == (NHM_RPT_NUM - 1)) + ccx->nhm_wgt[NHM_RPT_NUM - 1] = (u8)(ccx->nhm_th[NHM_TH_NUM - 1] + 2); + else + ccx->nhm_wgt[i] = (u8)((ccx->nhm_th[i - 1] + ccx->nhm_th[i]) >> 1); + } +} + +u8 phydm_nhm_cal_wgt_avg(void *dm_void, u8 start_i, u8 end_i, u8 n_sum) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 i = 0; + u32 noise_tmp = 0; + u8 noise = 0; + u32 nhm_valid = 0; + + if (n_sum == 0) { + PHYDM_DBG(dm, DBG_ENV_MNTR, + "n_sum = 0, don't need to update noise\n"); + return 0x0; + } else if (end_i > NHM_RPT_NUM - 1) { + PHYDM_DBG(dm, DBG_ENV_MNTR, + "[WARNING]end_i is larger than 11!!\n"); + return 0x0; + } + + for (i = start_i; i <= end_i; i++) + noise_tmp += ccx->nhm_result[i] * ccx->nhm_wgt[i]; + + /* protection for the case of minus noise(RSSI)*/ + noise = (u8)(NTH_TH_2_RSSI(MAX_2(PHYDM_DIV(noise_tmp, n_sum), 20))); + nhm_valid = (n_sum * 100) >> 8; + PHYDM_DBG(dm, DBG_ENV_MNTR, + "cal wgt_avg : valid: ((%d)) percent, noise(RSSI)=((%d))\n", + nhm_valid, noise); + + return noise; +} + +u8 phydm_nhm_cal_nhm_env(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 first_idx = 0; + u8 nhm_env = 0; + u8 i = 0; + + nhm_env = ccx->nhm_rpt_sum; + + /*search first cluster*/ + for (i = 0; i < NHM_RPT_NUM; i++) { + if (ccx->nhm_result[i]) { + first_idx = i; + break; + } + } + + /*exclude first cluster under -80dBm*/ + for (i = 0; i < 4; i++) { + if (((first_idx + i) < NHM_RPT_NUM) && + (ccx->nhm_wgt[first_idx + i] <= NHM_IC_NOISE_TH)) + nhm_env -= ccx->nhm_result[first_idx + i]; + } + + /*exclude nhm_rpt[0] above -80dBm*/ + if (ccx->nhm_wgt[0] > NHM_IC_NOISE_TH) + nhm_env -= ccx->nhm_result[0]; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "cal nhm_env: first_idx=%d, nhm_env=%d\n", + first_idx, nhm_env); + + return nhm_env; +} + void phydm_nhm_get_utility(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; u8 nhm_rpt_non_0 = 0; + u8 nhm_rpt_non_11 = 0; + u8 nhm_env = 0; if (ccx->nhm_rpt_sum >= ccx->nhm_result[0]) { + phydm_nhm_cal_wgt(dm); + nhm_rpt_non_0 = ccx->nhm_rpt_sum - ccx->nhm_result[0]; - ccx->nhm_ratio = (nhm_rpt_non_0 * 100) >> 8; + nhm_rpt_non_11 = ccx->nhm_rpt_sum - ccx->nhm_result[11]; + /*exclude nhm_r[0] above -80dBm or first cluster under -80dBm*/ + nhm_env = phydm_nhm_cal_nhm_env(dm); + ccx->nhm_ratio = phydm_ccx_get_rpt_ratio(dm, nhm_rpt_non_0, + NHM_RPT_MAX); + ccx->nhm_env_ratio = phydm_ccx_get_rpt_ratio(dm, nhm_env, + NHM_RPT_MAX); + ccx->nhm_level_valid = phydm_ccx_get_rpt_ratio(dm, + nhm_rpt_non_11, NHM_RPT_MAX); + ccx->nhm_level = phydm_nhm_cal_wgt_avg(dm, 0, NHM_RPT_NUM - 2, + nhm_rpt_non_11); + ccx->nhm_pwr = phydm_nhm_cal_wgt_avg(dm, 0, NHM_RPT_NUM - 1, + ccx->nhm_rpt_sum); } else { PHYDM_DBG(dm, DBG_ENV_MNTR, "[warning] nhm_rpt_sum invalid\n"); ccx->nhm_ratio = 0; + ccx->nhm_env_ratio = 0; } - PHYDM_DBG(dm, DBG_ENV_MNTR, "nhm_ratio=%d\n", ccx->nhm_ratio); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "nhm_ratio=%d, nhm_env_ratio=%d, nhm_level=%d, nhm_pwr=%d\n", + ccx->nhm_ratio, ccx->nhm_env_ratio, ccx->nhm_level, + ccx->nhm_pwr); } boolean @@ -454,6 +317,7 @@ phydm_nhm_get_result(void *dm_void) u8 i = 0; u32 nhm_reg1 = 0; u16 nhm_rpt_sum_tmp = 0; + u16 nhm_duration = 0; if (dm->support_ic_type & ODM_IC_11AC_SERIES) nhm_reg1 = R_0x994; @@ -466,7 +330,7 @@ phydm_nhm_get_result(void *dm_void) PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); if (!(dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8812F | - ODM_RTL8197G))) + ODM_RTL8197G | ODM_RTL8723F))) pdm_set_reg(dm, nhm_reg1, BIT(1), 0); if (!(phydm_nhm_check_rdy(dm))) { @@ -487,7 +351,7 @@ phydm_nhm_get_result(void *dm_void) /*@Get NHM duration*/ value32 = odm_read_4byte(dm, R_0xfb4); - ccx->nhm_duration = (u16)(value32 & MASKLWORD); + nhm_duration = (u16)(value32 & MASKLWORD); #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT } else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { value32 = odm_read_4byte(dm, R_0x2d40); @@ -501,7 +365,7 @@ phydm_nhm_get_result(void *dm_void) /*@Get NHM duration*/ value32 = odm_read_4byte(dm, R_0x2d4c); - ccx->nhm_duration = (u16)(value32 & MASKLWORD); + nhm_duration = (u16)(value32 & MASKLWORD); #endif } else { value32 = odm_read_4byte(dm, R_0x8d8); @@ -519,19 +383,17 @@ phydm_nhm_get_result(void *dm_void) ccx->nhm_result[11] = (u8)((value32 & MASKBYTE3) >> 24); /*@Get NHM duration*/ - ccx->nhm_duration = (u16)(value32 & MASKLWORD); + nhm_duration = (u16)(value32 & MASKLWORD); } /* sum all nhm_result */ - if (ccx->nhm_period >= 65530) { - value32 = (ccx->nhm_duration * 100) >> 16; + if (ccx->nhm_period >= 65530) PHYDM_DBG(dm, DBG_ENV_MNTR, "NHM valid time = %d, valid: %d percent\n", - ccx->nhm_duration, value32); - } + nhm_duration, (nhm_duration * 100) >> 16); for (i = 0; i < NHM_RPT_NUM; i++) - nhm_rpt_sum_tmp += (u16)ccx->nhm_result[i]; + nhm_rpt_sum_tmp = (u16)(nhm_rpt_sum_tmp + ccx->nhm_result[i]); ccx->nhm_rpt_sum = (u8)nhm_rpt_sum_tmp; @@ -607,7 +469,7 @@ void phydm_nhm_set_th_reg(void *dm_void) boolean phydm_nhm_th_update_chk(void *dm_void, enum nhm_application nhm_app, u8 *nhm_th, - u32 *igi_new) + u32 *igi_new, boolean en_1db_mode, u8 nhm_th0_manual) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; @@ -639,8 +501,7 @@ phydm_nhm_th_update_chk(void *dm_void, enum nhm_application nhm_app, u8 *nhm_th, *igi_new = (u32)igi_curr; #ifdef NHM_DYM_PW_TH_SUPPORT - if ((dm->support_ic_type & ODM_IC_JGR3_SERIES) && - ccx->nhm_dym_pw_th_en) { + if (ccx->nhm_dym_pw_th_en) { th_tmp = MAX_2(igi_curr - DYM_PWTH_CCA_CAP, 0); th_step = 3; } @@ -691,9 +552,18 @@ phydm_nhm_th_update_chk(void *dm_void, enum nhm_application nhm_app, u8 *nhm_th, if (ccx->nhm_igi != igi_curr || ccx->nhm_app != nhm_app) { is_update = true; *igi_new = (u32)igi_curr; - nhm_th[0] = (u8)IGI_2_NHM_TH(igi_curr - CCA_CAP); + if (en_1db_mode) { + nhm_th[0] = (u8)IGI_2_NHM_TH(nhm_th0_manual + + 10); + th_step = 1; + } else { + nhm_th[0] = (u8)IGI_2_NHM_TH(igi_curr - + CCA_CAP); + } + for (i = 1; i <= 10; i++) - nhm_th[i] = nhm_th[0] + IGI_2_NHM_TH(2 * i); + nhm_th[i] = nhm_th[0] + IGI_2_NHM_TH(th_step * + i); } break; } @@ -715,7 +585,8 @@ phydm_nhm_th_update_chk(void *dm_void, enum nhm_application nhm_app, u8 *nhm_th, void phydm_nhm_set(void *dm_void, enum nhm_option_txon_all include_tx, enum nhm_option_cca_all include_cca, enum nhm_divider_opt_all divi_opt, - enum nhm_application nhm_app, u16 period) + enum nhm_application nhm_app, u16 period, + boolean en_1db_mode, u8 nhm_th0_manual) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; @@ -761,14 +632,6 @@ void phydm_nhm_set(void *dm_void, enum nhm_option_txon_all include_tx, ccx->nhm_include_txon = include_tx; ccx->nhm_include_cca = include_cca; ccx->nhm_divider_opt = divi_opt; - #if 0 - PHYDM_DBG(dm, DBG_ENV_MNTR, - "val_tmp=%d, incld{tx, cca}={%d, %d}, divi_opt=%d, period=%d\n", - val_tmp, include_tx, include_cca, divi_opt, period); - - PHYDM_DBG(dm, DBG_ENV_MNTR, "0x994=0x%x\n", - odm_get_bb_reg(dm, 0x994, 0xf00)); - #endif } /*Set NHM period*/ @@ -782,7 +645,8 @@ void phydm_nhm_set(void *dm_void, enum nhm_option_txon_all include_tx, } /*Set NHM threshold*/ - if (phydm_nhm_th_update_chk(dm, nhm_app, &(nhm_th[0]), &igi)) { + if (phydm_nhm_th_update_chk(dm, nhm_app, &nhm_th[0], &igi, + en_1db_mode, nhm_th0_manual)) { /*Pause IGI*/ if (nhm_app == NHM_BACKGROUND || nhm_app == NHM_ACS) { PHYDM_DBG(dm, DBG_ENV_MNTR, "DIG Free Run\n"); @@ -803,7 +667,8 @@ void phydm_nhm_set(void *dm_void, enum nhm_option_txon_all include_tx, } } -u8 phydm_nhm_mntr_set(void *dm_void, struct nhm_para_info *nhm_para) +boolean +phydm_nhm_mntr_set(void *dm_void, struct nhm_para_info *nhm_para) { struct dm_struct *dm = (struct dm_struct *)dm_void; u16 nhm_time = 0; /*unit: 4us*/ @@ -811,15 +676,15 @@ u8 phydm_nhm_mntr_set(void *dm_void, struct nhm_para_info *nhm_para) PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); if (nhm_para->mntr_time == 0) - return PHYDM_SET_FAIL; + return false; if (nhm_para->nhm_lv >= NHM_MAX_NUM) { PHYDM_DBG(dm, DBG_ENV_MNTR, "Wrong LV=%d\n", nhm_para->nhm_lv); - return PHYDM_SET_FAIL; + return false; } if (phydm_nhm_racing_ctrl(dm, nhm_para->nhm_lv) == PHYDM_SET_FAIL) - return PHYDM_SET_FAIL; + return false; if (nhm_para->mntr_time >= 262) nhm_time = NHM_PERIOD_MAX; @@ -827,52 +692,10 @@ u8 phydm_nhm_mntr_set(void *dm_void, struct nhm_para_info *nhm_para) nhm_time = nhm_para->mntr_time * MS_TO_4US_RATIO; phydm_nhm_set(dm, nhm_para->incld_txon, nhm_para->incld_cca, - nhm_para->div_opt, nhm_para->nhm_app, nhm_time); + nhm_para->div_opt, nhm_para->nhm_app, nhm_time, + nhm_para->en_1db_mode, nhm_para->nhm_th0_manual); - return PHYDM_SET_SUCCESS; -} - -void phydm_nhm_cal_noise(void *dm_void, u8 start_i, u8 end_i, u8 n_sum) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct ccx_info *ccx = &dm->dm_ccx_info; - u8 i = 0; - u32 noise_tmp = 0; - u8 noise = 0; - u8 th_step = 2; - u32 nhm_valid = 0; - - PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); - - if (n_sum == 0) { - PHYDM_DBG(dm, DBG_ENV_MNTR, - "n_sum = 0, don't need to update noise\n"); - return; - } else if (end_i > NHM_RPT_NUM - 1) { - PHYDM_DBG(dm, DBG_ENV_MNTR, - "[WARNING]end_i is larger than 11!!\n"); - return; - } - - #ifdef NHM_DYM_PW_TH_SUPPORT - if ((dm->support_ic_type & ODM_IC_JGR3_SERIES) && - ccx->nhm_dym_pw_th_en) - th_step = 3; - #endif - - for (i = start_i; i <= end_i; i++) - noise_tmp += ccx->nhm_result[i] * (ccx->nhm_th[0] - th_step + - th_step * i * 2); - - /* protection for the case of minus noise(RSSI)*/ - noise = (u8)(NTH_TH_2_RSSI(MAX_2(PHYDM_DIV(noise_tmp, n_sum), 20))); - ccx->nhm_noise_pwr = noise; - ccx->nhm_noise_pwr_point = n_sum; - nhm_valid = (n_sum * 100) >> 8; - PHYDM_DBG(dm, DBG_ENV_MNTR, - "valid: ((%d)) percent, noise(RSSI)=((%d)), nhm_r[11](RSSI > %d)=((%d))\n", - nhm_valid, noise, NTH_TH_2_RSSI(ccx->nhm_th[NHM_TH_NUM - 1]), - ccx->nhm_result[NHM_RPT_NUM - 1]); + return true; } #ifdef NHM_DYM_PW_TH_SUPPORT @@ -882,7 +705,7 @@ phydm_nhm_restore_pw_th(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; - odm_set_bb_reg(dm, R_0x82c, 0x3f, ccx->nhm_pw_th_rf20_dft); + odm_set_bb_reg(dm, R_0x82c, 0x3f, ccx->pw_th_rf20_ori); } void @@ -890,8 +713,8 @@ phydm_nhm_set_pw_th(void *dm_void, u8 noise, boolean chk_succ) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; - u8 pre_pw_th_rf20 = 0; - u8 new_pw_th_rf20 = 0; + boolean not_update = false; + u8 pw_th_rf20_new = 0; u8 pw_th_u_bnd = 0; s8 noise_diff = 0; u8 point_mean = 15; @@ -906,18 +729,6 @@ phydm_nhm_set_pw_th(void *dm_void, u8 noise, boolean chk_succ) return; } - pre_pw_th_rf20 = (u8)odm_get_bb_reg(dm, R_0x82c, 0x3f); - - /* @pre_pw_th can not be lower than default value*/ - if (pre_pw_th_rf20 < ccx->nhm_pw_th_rf20_dft) { - PHYDM_DBG(dm, DBG_ENV_MNTR, - "pre_pw_th=((%d)), new_pw_th=((%d))\n", - pre_pw_th_rf20, ccx->nhm_pw_th_rf20_dft); - - phydm_nhm_restore_pw_th(dm); - return; - } - if (chk_succ) { noise_diff = noise - (ccx->nhm_igi - 10); pw_th_u_bnd = (u8)(noise_diff + 32 + point_mean); @@ -928,164 +739,34 @@ phydm_nhm_set_pw_th(void *dm_void, u8 noise, boolean chk_succ) "noise_diff=((%d)), max=((%d)), pw_th_u_bnd=((%d))\n", noise_diff, ccx->nhm_pw_th_max, pw_th_u_bnd); - if (pw_th_u_bnd > pre_pw_th_rf20) { - new_pw_th_rf20 = pre_pw_th_rf20 + 1; - } else if (pw_th_u_bnd == pre_pw_th_rf20) { - new_pw_th_rf20 = pre_pw_th_rf20; - } else { - if (pre_pw_th_rf20 > ccx->nhm_pw_th_rf20_dft) - new_pw_th_rf20 = pre_pw_th_rf20 - 1; - else /* @pre_pw_th = ccx->nhm_pw_th_dft*/ - new_pw_th_rf20 = pre_pw_th_rf20; + if (pw_th_u_bnd > ccx->pw_th_rf20_cur) { + pw_th_rf20_new = ccx->pw_th_rf20_cur + 1; + } else if (pw_th_u_bnd < ccx->pw_th_rf20_cur) { + if (ccx->pw_th_rf20_cur > ccx->pw_th_rf20_ori) + pw_th_rf20_new = ccx->pw_th_rf20_cur - 1; + else /*ccx->pw_th_rf20_cur == ccx->pw_th_ori*/ + not_update = true; + } else {/*pw_th_u_bnd == ccx->pw_th_rf20_cur*/ + not_update = true; } } else { - if (pre_pw_th_rf20 > ccx->nhm_pw_th_rf20_dft) - new_pw_th_rf20 = pre_pw_th_rf20 - 1; - else /* @pre_pw_th = ccx->nhm_pw_th_dft*/ - new_pw_th_rf20 = pre_pw_th_rf20; + if (ccx->pw_th_rf20_cur > ccx->pw_th_rf20_ori) + pw_th_rf20_new = ccx->pw_th_rf20_cur - 1; + else /*ccx->pw_th_rf20_cur == ccx->pw_th_ori*/ + not_update = true; } - PHYDM_DBG(dm, DBG_ENV_MNTR, "pre_pw_th=((%d)), new_pw_th=((%d))\n", - pre_pw_th_rf20, new_pw_th_rf20); + PHYDM_DBG(dm, DBG_ENV_MNTR, "pw_th_cur=((%d)), pw_th_new=((%d))\n", + ccx->pw_th_rf20_cur, pw_th_rf20_new); - if (new_pw_th_rf20 != pre_pw_th_rf20) - odm_set_bb_reg(dm, R_0x82c, 0x3f, new_pw_th_rf20); + if (!not_update) { + odm_set_bb_reg(dm, R_0x82c, 0x3f, pw_th_rf20_new); + ccx->pw_th_rf20_cur = pw_th_rf20_new; + } } void -phydm_nhm_dym_pw_th_1peak(void *dm_void) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct ccx_info *ccx = &dm->dm_ccx_info; - u8 i = 0; - u8 max_i = 0; - u8 m_dif_l1 = 0; - u8 m_dif_r1 = 0; - u8 patt_case = 0; - u8 l1_dif_r2 = 0; - u8 l2_dif_r1 = 0; - u8 l1_dif_r1 = 0; - u8 n_sum = 0; - u8 r1_dif_r2 = 0; - u8 l1_dif_l2 = 0; - u8 noise = 0; - boolean chk_succ = false; - - PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); - - /* @step1*/ - for (i = 1; i < NHM_RPT_NUM; i++) { - if (ccx->nhm_result[i] >= ccx->nhm_result[max_i]) - max_i = i; - } - - if (max_i == 0 || max_i == (NHM_RPT_NUM - 1)) { - PHYDM_DBG(dm, DBG_ENV_MNTR, "max index can not be 0 or 11\n"); - phydm_nhm_set_pw_th(dm, 0, chk_succ); - return; - } - - /* @step2*/ - m_dif_l1 = ccx->nhm_result[max_i] - ccx->nhm_result[max_i - 1]; - m_dif_r1 = ccx->nhm_result[max_i] - ccx->nhm_result[max_i + 1]; - - if (m_dif_r1 <= NHM_TH1 && (max_i != NHM_RPT_NUM - 1)) - patt_case = NHM_1PEAK_PS; - else if ((m_dif_l1 <= NHM_TH1) && (max_i != 0)) - patt_case = NHM_1PEAK_NS; - else - patt_case = NHM_1PEAK_SYM; - - switch (patt_case) { - case NHM_1PEAK_PS: - /* @step3*/ - l1_dif_r2 = DIFF_2(ccx->nhm_result[max_i - 1], - ccx->nhm_result[max_i + 2]); - if (l1_dif_r2 > NHM_TH2) { - PHYDM_DBG(dm, DBG_ENV_MNTR, "S3 fail:c1((%d))\n", - l1_dif_r2); - break; - } - /* @step4*/ - n_sum = ccx->nhm_result[max_i - 1] + ccx->nhm_result[max_i] + - ccx->nhm_result[max_i + 1] + ccx->nhm_result[max_i + 2]; - if (n_sum < NHM_TH4) { - PHYDM_DBG(dm, DBG_ENV_MNTR, "S4 fail:((%d))\n", n_sum); - break; - } - /* @step5*/ - r1_dif_r2 = DIFF_2(ccx->nhm_result[max_i + 1], - ccx->nhm_result[max_i + 2]); - if (m_dif_l1 < NHM_TH5 || r1_dif_r2 < NHM_TH5) { - PHYDM_DBG(dm, DBG_ENV_MNTR, "S5 fail:c1((%d, %d))\n", - m_dif_l1, r1_dif_r2); - break; - } - /* @step6*/ - chk_succ = true; - phydm_nhm_cal_noise(dm, max_i - 1, max_i + 2, n_sum); - break; - case NHM_1PEAK_NS: - /* @step3*/ - l2_dif_r1 = DIFF_2(ccx->nhm_result[max_i - 2], - ccx->nhm_result[max_i + 1]); - if (l2_dif_r1 > NHM_TH2) { - PHYDM_DBG(dm, DBG_ENV_MNTR, "S3 fail:c2((%d))\n", - l2_dif_r1); - break; - } - /* @step4*/ - n_sum = ccx->nhm_result[max_i - 2] + - ccx->nhm_result[max_i - 1] + - ccx->nhm_result[max_i] + ccx->nhm_result[max_i + 1]; - if (n_sum < NHM_TH4) { - PHYDM_DBG(dm, DBG_ENV_MNTR, "S4 fail:((%d))\n", n_sum); - break; - } - /* @step5*/ - l1_dif_l2 = DIFF_2(ccx->nhm_result[max_i - 1], - ccx->nhm_result[max_i - 2]); - if (m_dif_r1 < NHM_TH5 || l1_dif_l2 < NHM_TH5) { - PHYDM_DBG(dm, DBG_ENV_MNTR, "S5 fail:c2((%d, %d))\n", - m_dif_r1, l1_dif_l2); - break; - } - /* @step6*/ - chk_succ = true; - phydm_nhm_cal_noise(dm, max_i - 2, max_i + 1, n_sum); - break; - case NHM_1PEAK_SYM: - /* @step3*/ - l1_dif_r1 = DIFF_2(ccx->nhm_result[max_i - 1], - ccx->nhm_result[max_i + 1]); - if (l1_dif_r1 > NHM_TH3) { - PHYDM_DBG(dm, DBG_ENV_MNTR, "S3 fail: c3((%d))\n", - l1_dif_r1); - break; - } - /* @step4*/ - n_sum = ccx->nhm_result[max_i - 1] + ccx->nhm_result[max_i] + - ccx->nhm_result[max_i + 1]; - if (n_sum < NHM_TH4) { - PHYDM_DBG(dm, DBG_ENV_MNTR, "S4 fail:((%d))\n", n_sum); - break; - } - /* @step5*/ - if (m_dif_l1 < NHM_TH6 || m_dif_r1 < NHM_TH6) { - PHYDM_DBG(dm, DBG_ENV_MNTR, "S5 fail:c3((%d, %d))\n", - m_dif_l1, m_dif_r1); - break; - } - /* @step6*/ - chk_succ = true; - phydm_nhm_cal_noise(dm, max_i - 1, max_i + 1, n_sum); - break; - } - phydm_nhm_set_pw_th(dm, ccx->nhm_noise_pwr, chk_succ); -} - -void -phydm_nhm_dym_pw_th_sl(void *dm_void) +phydm_nhm_dym_pw_th(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; @@ -1102,7 +783,7 @@ phydm_nhm_dym_pw_th_sl(void *dm_void) if (n_sum >= ccx->nhm_sl_pw_th) { PHYDM_DBG(dm, DBG_ENV_MNTR, "Do sl[%d:%d]\n", i, i + 3); chk_succ = true; - phydm_nhm_cal_noise(dm, i, i + 3, n_sum); + noise = phydm_nhm_cal_wgt_avg(dm, i, i + 3, n_sum); break; } } @@ -1110,55 +791,49 @@ phydm_nhm_dym_pw_th_sl(void *dm_void) if (!chk_succ) PHYDM_DBG(dm, DBG_ENV_MNTR, "SL method failed!\n"); - phydm_nhm_set_pw_th(dm, ccx->nhm_noise_pwr, chk_succ); + phydm_nhm_set_pw_th(dm, noise, chk_succ); } -void -phydm_nhm_dym_pw_th(void *dm_void) +boolean +phydm_nhm_dym_pw_th_en(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; + struct phydm_iot_center *iot_table = &dm->iot_table; - if (ccx->nhm_dym_1_peak_en) - phydm_nhm_dym_pw_th_1peak(dm); - else - phydm_nhm_dym_pw_th_sl(dm); -} + if (!(dm->support_ic_type & ODM_RTL8822C)) + return false; -void -phydm_nhm_dym_pw_th_patch_id_chk(void *dm_void) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct ccx_info *ccx = &dm->dm_ccx_info; + if (ccx->dym_pwth_manual_ctrl) + return true; - if (dm->iot_table.phydm_patch_id == 0x100f0401) { - ccx->nhm_dym_pw_th_en = true; + if (dm->iot_table.phydm_patch_id == 0x100f0401 || + iot_table->patch_id_100f0401) { + return true; + } else if (ccx->nhm_dym_pw_th_en) { + phydm_nhm_restore_pw_th(dm); + return false; } else { - if (ccx->nhm_dym_pw_th_en) { - phydm_nhm_restore_pw_th(dm); - ccx->nhm_dym_pw_th_en = false; - } + return false; } } #endif -/*@Environment Monitor*/ +/*Environment Monitor*/ boolean -phydm_nhm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/) +phydm_nhm_mntr_racing_chk(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; - struct nhm_para_info nhm_para = {0}; - boolean nhm_chk_result = false; u32 sys_return_time = 0; - PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); - if (ccx->nhm_manual_ctrl) { PHYDM_DBG(dm, DBG_ENV_MNTR, "NHM in manual ctrl\n"); - return nhm_chk_result; + return true; } + sys_return_time = ccx->nhm_trigger_time + MAX_ENV_MNTR_TIME; + if (ccx->nhm_app != NHM_BACKGROUND && (sys_return_time > dm->phydm_sys_up_time)) { PHYDM_DBG(dm, DBG_ENV_MNTR, @@ -1166,59 +841,74 @@ phydm_nhm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/) ccx->nhm_app, ccx->nhm_trigger_time, dm->phydm_sys_up_time); - return nhm_chk_result; + return true; } - /*@[NHM get result & calculate Utility----------------------------*/ + return false; +} + +boolean +phydm_nhm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + struct nhm_para_info nhm_para = {0}; + boolean nhm_chk_result = false; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + if (phydm_nhm_mntr_racing_chk(dm)) + return nhm_chk_result; + + /*[NHM trigger setting]------------------------------------------*/ + nhm_para.incld_txon = NHM_EXCLUDE_TXON; + nhm_para.incld_cca = NHM_EXCLUDE_CCA; + nhm_para.div_opt = NHM_CNT_ALL; + nhm_para.nhm_app = NHM_BACKGROUND; + nhm_para.nhm_lv = NHM_LV_1; + nhm_para.en_1db_mode = false; + nhm_para.mntr_time = monitor_time; + #ifdef NHM_DYM_PW_TH_SUPPORT - if (!(ccx->dym_pwth_manual_ctrl)) - phydm_nhm_dym_pw_th_patch_id_chk(dm); + if (ccx->nhm_dym_pw_th_en) { + nhm_para.div_opt = NHM_VALID; + nhm_para.mntr_time = monitor_time >> ccx->nhm_period_decre; + } #endif + nhm_chk_result = phydm_nhm_mntr_set(dm, &nhm_para); + + return nhm_chk_result; +} + +boolean +phydm_nhm_mntr_result(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + boolean nhm_chk_result = false; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + if (phydm_nhm_mntr_racing_chk(dm)) + return nhm_chk_result; + + /*[NHM get result & calculate Utility]---------------------------*/ if (phydm_nhm_get_result(dm)) { PHYDM_DBG(dm, DBG_ENV_MNTR, "Get NHM_rpt success\n"); phydm_nhm_get_utility(dm); - - #ifdef NHM_DYM_PW_TH_SUPPORT - if ((dm->support_ic_type & ODM_IC_JGR3_SERIES) && - ccx->nhm_dym_pw_th_en) - phydm_nhm_dym_pw_th(dm); - else - #endif - /* bypass r[11]*/ - phydm_nhm_cal_noise(dm, 0, NHM_RPT_NUM - 2, - ccx->nhm_rpt_sum - - ccx->nhm_result[11]); - } else { - #ifdef NHM_DYM_PW_TH_SUPPORT - if ((dm->support_ic_type & ODM_IC_JGR3_SERIES) && - ccx->nhm_dym_pw_th_en) - phydm_nhm_set_pw_th(dm, 0, false); - #endif + nhm_chk_result = true; } - /*@[NHM trigger setting]------------------------------------------*/ - nhm_para.incld_txon = NHM_EXCLUDE_TXON; - nhm_para.incld_cca = NHM_EXCLUDE_CCA; #ifdef NHM_DYM_PW_TH_SUPPORT - if ((dm->support_ic_type & ODM_IC_JGR3_SERIES) && - ccx->nhm_app == NHM_BACKGROUND && ccx->nhm_dym_pw_th_en) - nhm_para.div_opt = NHM_VALID; - else + ccx->nhm_dym_pw_th_en = phydm_nhm_dym_pw_th_en(dm); + if (ccx->nhm_dym_pw_th_en) { + if (nhm_chk_result) + phydm_nhm_dym_pw_th(dm); + else + phydm_nhm_set_pw_th(dm, 0x0, false); + } #endif - nhm_para.div_opt = NHM_CNT_ALL; - - nhm_para.nhm_app = NHM_BACKGROUND; - nhm_para.nhm_lv = NHM_LV_1; - #ifdef NHM_DYM_PW_TH_SUPPORT - if ((dm->support_ic_type & ODM_IC_JGR3_SERIES) && - ccx->nhm_app == NHM_BACKGROUND && ccx->nhm_dym_pw_th_en) - nhm_para.mntr_time = monitor_time >> ccx->nhm_period_decre; - else - #endif - nhm_para.mntr_time = monitor_time; - - nhm_chk_result = phydm_nhm_mntr_set(dm, &nhm_para); return nhm_chk_result; } @@ -1240,7 +930,7 @@ void phydm_nhm_init(void *dm_void) ccx->nhm_set_lv = NHM_RELEASE; if (phydm_nhm_th_update_chk(dm, ccx->nhm_app, &ccx->nhm_th[0], - (u32 *)&ccx->nhm_igi)) + (u32 *)&ccx->nhm_igi, false, 0)) phydm_nhm_set_th_reg(dm); ccx->nhm_period = 0; @@ -1253,12 +943,12 @@ void phydm_nhm_init(void *dm_void) ccx->nhm_rpt_stamp = 0; #ifdef NHM_DYM_PW_TH_SUPPORT - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + if (dm->support_ic_type & ODM_RTL8822C) { ccx->nhm_dym_pw_th_en = false; - ccx->nhm_dym_1_peak_en = false; - ccx->nhm_pw_th_rf20_dft = (u8)odm_get_bb_reg(dm, R_0x82c, 0x3f); + ccx->pw_th_rf20_ori = (u8)odm_get_bb_reg(dm, R_0x82c, 0x3f); + ccx->pw_th_rf20_cur = ccx->pw_th_rf20_ori; ccx->nhm_pw_th_max = 63; - ccx->nhm_sl_pw_th = 100; /* @39%*/ + ccx->nhm_sl_pw_th = 100; /*39%*/ ccx->nhm_period_decre = 1; ccx->dym_pwth_manual_ctrl = false; } @@ -1270,14 +960,13 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, { struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; - struct nhm_para_info nhm_para; + struct nhm_para_info nhm_para = {0}; char help[] = "-h"; u32 var1[10] = {0}; u32 used = *_used; u32 out_len = *_out_len; - boolean nhm_rpt_success = true; u8 result_tmp = 0; - u8 i; + u8 i = 0; PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); @@ -1286,13 +975,13 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, "NHM Basic-Trigger 262ms: {1}\n"); PDM_SNPF(out_len, used, output + used, out_len - used, - "NHM Adv-Trigger: {2} {Include TXON} {Include CCA}\n{0:Cnt_all, 1:Cnt valid} {App} {LV} {0~262ms}\n"); + "NHM Adv-Trigger: {2} {Include TXON} {Include CCA}\n{0:Cnt_all, 1:Cnt valid} {App:5 for dbg} {LV:1~4} {0~262ms}, 1dB mode :{en} {t[0](RSSI)}\n"); #ifdef NHM_DYM_PW_TH_SUPPORT - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + if (dm->support_ic_type & ODM_RTL8822C) { PDM_SNPF(out_len, used, output + used, out_len - used, "NHM dym_pw_th: {3} {0:off}\n"); PDM_SNPF(out_len, used, output + used, out_len - used, - "NHM dym_pw_th: {3} {1:on} {en_1-peak} {max} {period_decre} {sl_th}\n"); + "NHM dym_pw_th: {3} {1:on} {max} {period_decre} {sl_th}\n"); PDM_SNPF(out_len, used, output + used, out_len - used, "NHM dym_pw_th: {3} {2:fast on}\n"); } @@ -1300,16 +989,14 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, PDM_SNPF(out_len, used, output + used, out_len - used, "NHM Get Result: {100}\n"); - } else if (var1[0] == 100) { /*@Get NHM results*/ + } else if (var1[0] == 100) { /*Get NHM results*/ PDM_SNPF(out_len, used, output + used, out_len - used, "IGI=0x%x, rpt_stamp=%d\n", ccx->nhm_igi, ccx->nhm_rpt_stamp); - nhm_rpt_success = phydm_nhm_get_result(dm); - - if (nhm_rpt_success) { - for (i = 0; i <= 11; i++) { + if (phydm_nhm_get_result(dm)) { + for (i = 0; i < NHM_RPT_NUM; i++) { result_tmp = ccx->nhm_result[i]; PDM_SNPF(out_len, used, output + used, out_len - used, @@ -1317,31 +1004,37 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, i, result_tmp, (((result_tmp * 100) + 128) >> 8)); } + phydm_nhm_get_utility(dm); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "NHM_noise: valid: %d percent, noise(RSSI) = %d\n", + ccx->nhm_level_valid, ccx->nhm_level); + PDM_SNPF(out_len, used, output + used, out_len - used, + "NHM_pwr: nhm_pwr (RSSI) = %d\n", ccx->nhm_pwr); + PDM_SNPF(out_len, used, output + used, out_len - used, + "ratio: nhm_ratio=%d, nhm_env_ratio=%d\n", + ccx->nhm_ratio, ccx->nhm_env_ratio); } else { PDM_SNPF(out_len, used, output + used, out_len - used, "Get NHM_rpt Fail\n"); } ccx->nhm_manual_ctrl = 0; #ifdef NHM_DYM_PW_TH_SUPPORT - } else if (var1[0] == 3) { /* @NMH dym_pw_th*/ - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + } else if (var1[0] == 3) { /*NMH dym_pw_th*/ + if (dm->support_ic_type & ODM_RTL8822C) { for (i = 1; i < 7; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, - &var1[i]); - } + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); } if (var1[1] == 1) { ccx->nhm_dym_pw_th_en = true; - ccx->nhm_dym_1_peak_en = (boolean)var1[2]; - ccx->nhm_pw_th_max = (u8)var1[3]; - ccx->nhm_period_decre = (u8)var1[4]; - ccx->nhm_sl_pw_th = (u8)var1[5]; + ccx->nhm_pw_th_max = (u8)var1[2]; + ccx->nhm_period_decre = (u8)var1[3]; + ccx->nhm_sl_pw_th = (u8)var1[4]; ccx->dym_pwth_manual_ctrl = true; } else if (var1[1] == 2) { ccx->nhm_dym_pw_th_en = true; - ccx->nhm_dym_1_peak_en = false; ccx->nhm_pw_th_max = 63; ccx->nhm_period_decre = 1; ccx->nhm_sl_pw_th = 100; @@ -1354,14 +1047,11 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, } #endif } else { /*NMH trigger*/ - ccx->nhm_manual_ctrl = 1; - for (i = 1; i < 7; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, - &var1[i]); - } + for (i = 1; i < 9; i++) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); } if (var1[0] == 1) { @@ -1371,6 +1061,8 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, nhm_para.nhm_app = NHM_DBG; nhm_para.nhm_lv = NHM_LV_4; nhm_para.mntr_time = 262; + nhm_para.en_1db_mode = false; + nhm_para.nhm_th0_manual = 0; } else { nhm_para.incld_txon = (enum nhm_option_txon_all)var1[1]; nhm_para.incld_cca = (enum nhm_option_cca_all)var1[2]; @@ -1378,8 +1070,10 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, nhm_para.nhm_app = (enum nhm_application)var1[4]; nhm_para.nhm_lv = (enum phydm_nhm_level)var1[5]; nhm_para.mntr_time = (u16)var1[6]; + nhm_para.en_1db_mode = (boolean)var1[7]; + nhm_para.nhm_th0_manual = (u8)var1[8]; - /* some old ic is not supported on NHM divider option */ + /*some old ic is not supported on NHM divider option */ if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8723B | ODM_RTL8195A | ODM_RTL8192E)) { nhm_para.div_opt = NHM_CNT_ALL; @@ -1392,14 +1086,18 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, nhm_para.div_opt, nhm_para.nhm_app, nhm_para.nhm_lv, nhm_para.mntr_time); - if (phydm_nhm_mntr_set(dm, &nhm_para) == PHYDM_SET_SUCCESS) + PDM_SNPF(out_len, used, output + used, out_len - used, + "en_1db_mode=%d, th0(for 1db mode)=%d\n", + nhm_para.en_1db_mode, nhm_para.nhm_th0_manual); + + if (phydm_nhm_mntr_set(dm, &nhm_para)) phydm_nhm_trigger(dm); PDM_SNPF(out_len, used, output + used, out_len - used, "IGI=0x%x, rpt_stamp=%d\n", ccx->nhm_igi, ccx->nhm_rpt_stamp); - for (i = 0; i <= 10; i++) { + for (i = 0; i < NHM_TH_NUM; i++) { PDM_SNPF(out_len, used, output + used, out_len - used, "NHM_th[%d] RSSI = %d\n", i, NTH_TH_2_RSSI(ccx->nhm_th[i])); @@ -1591,17 +1289,13 @@ void phydm_clm_get_utility(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; - u32 clm_result_tmp; if (ccx->clm_period == 0) { PHYDM_DBG(dm, DBG_ENV_MNTR, "[warning] clm_period = 0\n"); ccx->clm_ratio = 0; - } else if (ccx->clm_period >= 65530) { - clm_result_tmp = (u32)(ccx->clm_result * 100); - ccx->clm_ratio = (u8)((clm_result_tmp + (1 << 15)) >> 16); } else { - clm_result_tmp = (u32)(ccx->clm_result * 100); - ccx->clm_ratio = (u8)(clm_result_tmp / (u32)ccx->clm_period); + ccx->clm_ratio = phydm_ccx_get_rpt_ratio(dm, ccx->clm_result, + ccx->clm_period); } } @@ -1622,7 +1316,7 @@ phydm_clm_get_result(void *dm_void) else reg1 = R_0x890; if (!(dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8812F | - ODM_RTL8197G))) + ODM_RTL8197G | ODM_RTL8723F))) odm_set_bb_reg(dm, reg1, BIT(0), 0x0); if (!(phydm_clm_check_rdy(dm))) { PHYDM_DBG(dm, DBG_ENV_MNTR, "Get CLM report Fail\n"); @@ -1649,37 +1343,8 @@ phydm_clm_get_result(void *dm_void) return true; } -void phydm_clm_mntr_fw(void *dm_void, u16 monitor_time /*unit ms*/) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct ccx_info *ccx = &dm->dm_ccx_info; - u32 val = 0; - - /*@[Get CLM report]*/ - if (ccx->clm_fw_result_cnt != 0) { - val = ccx->clm_fw_result_acc / ccx->clm_fw_result_cnt; - ccx->clm_ratio = (u8)val; - } else { - ccx->clm_ratio = 0; - } - - PHYDM_DBG(dm, DBG_ENV_MNTR, - "clm_fw_result_acc=%d, clm_fw_result_cnt=%d\n", - ccx->clm_fw_result_acc, ccx->clm_fw_result_cnt); - - ccx->clm_fw_result_acc = 0; - ccx->clm_fw_result_cnt = 0; - - /*@[CLM trigger]*/ - if (monitor_time >= 262) - ccx->clm_period = 65535; - else - ccx->clm_period = monitor_time * MS_TO_4US_RATIO; - - phydm_clm_h2c(dm, ccx->clm_period, true); -} - -u8 phydm_clm_mntr_set(void *dm_void, struct clm_para_info *clm_para) +boolean +phydm_clm_mntr_set(void *dm_void, struct clm_para_info *clm_para) { /*@Driver Monitor CLM*/ struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -1687,16 +1352,16 @@ u8 phydm_clm_mntr_set(void *dm_void, struct clm_para_info *clm_para) u16 clm_period = 0; if (clm_para->mntr_time == 0) - return PHYDM_SET_FAIL; + return false; if (clm_para->clm_lv >= CLM_MAX_NUM) { PHYDM_DBG(dm, DBG_ENV_MNTR, "[WARNING] Wrong LV=%d\n", clm_para->clm_lv); - return PHYDM_SET_FAIL; + return false; } if (phydm_clm_racing_ctrl(dm, clm_para->clm_lv) == PHYDM_SET_FAIL) - return PHYDM_SET_FAIL; + return false; if (clm_para->mntr_time >= 262) clm_period = CLM_PERIOD_MAX; @@ -1706,7 +1371,34 @@ u8 phydm_clm_mntr_set(void *dm_void, struct clm_para_info *clm_para) ccx->clm_app = clm_para->clm_app; phydm_clm_setting(dm, clm_period); - return PHYDM_SET_SUCCESS; + return true; +} + +boolean +phydm_clm_mntr_racing_chk(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u32 sys_return_time = 0; + + if (ccx->clm_manual_ctrl) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "CLM in manual ctrl\n"); + return true; + } + + sys_return_time = ccx->clm_trigger_time + MAX_ENV_MNTR_TIME; + + if (ccx->clm_app != CLM_BACKGROUND && + (sys_return_time > dm->phydm_sys_up_time)) { + PHYDM_DBG(dm, DBG_ENV_MNTR, + "clm_app=%d, trigger_time %d, sys_time=%d\n", + ccx->clm_app, ccx->clm_trigger_time, + dm->phydm_sys_up_time); + + return true; + } + + return false; } boolean @@ -1716,45 +1408,68 @@ phydm_clm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/) struct ccx_info *ccx = &dm->dm_ccx_info; struct clm_para_info clm_para = {0}; boolean clm_chk_result = false; - u32 sys_return_time = 0; PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__); - if (ccx->clm_manual_ctrl) { - PHYDM_DBG(dm, DBG_ENV_MNTR, "CLM in manual ctrl\n"); + + if (phydm_clm_mntr_racing_chk(dm)) return clm_chk_result; - } - - sys_return_time = ccx->clm_trigger_time + MAX_ENV_MNTR_TIME; - - if (ccx->clm_app != CLM_BACKGROUND && - sys_return_time > dm->phydm_sys_up_time) { - PHYDM_DBG(dm, DBG_ENV_MNTR, "trigger_time %d, sys_time=%d\n", - ccx->clm_trigger_time, dm->phydm_sys_up_time); - - return clm_chk_result; - } clm_para.clm_app = CLM_BACKGROUND; clm_para.clm_lv = CLM_LV_1; clm_para.mntr_time = monitor_time; if (ccx->clm_mntr_mode == CLM_DRIVER_MNTR) { - /*@[Get CLM report]*/ + if (phydm_clm_mntr_set(dm, &clm_para)) + clm_chk_result = true; + } else { + if (monitor_time >= 262) + ccx->clm_period = 65535; + else + ccx->clm_period = monitor_time * MS_TO_4US_RATIO; + + phydm_clm_h2c(dm, ccx->clm_period, true); + } + + return clm_chk_result; +} + +boolean +phydm_clm_mntr_result(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + boolean clm_chk_result = false; + u32 val = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__); + + if (phydm_clm_mntr_racing_chk(dm)) + return clm_chk_result; + + if (ccx->clm_mntr_mode == CLM_DRIVER_MNTR) { if (phydm_clm_get_result(dm)) { PHYDM_DBG(dm, DBG_ENV_MNTR, "Get CLM_rpt success\n"); phydm_clm_get_utility(dm); + clm_chk_result = true; + } + } else { + if (ccx->clm_fw_result_cnt != 0) { + val = ccx->clm_fw_result_acc / ccx->clm_fw_result_cnt; + ccx->clm_ratio = (u8)val; + clm_chk_result = true; + } else { + ccx->clm_ratio = 0; } - /*@[CLM trigger]----------------------------------------------*/ - if (phydm_clm_mntr_set(dm, &clm_para) == PHYDM_SET_SUCCESS) - clm_chk_result = true; - } else { - phydm_clm_mntr_fw(dm, monitor_time); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "clm_fw_result_acc=%d, clm_fw_result_cnt=%d\n", + ccx->clm_fw_result_acc, ccx->clm_fw_result_cnt); + + ccx->clm_fw_result_acc = 0; + ccx->clm_fw_result_cnt = 0; } PHYDM_DBG(dm, DBG_ENV_MNTR, "clm_ratio=%d\n", ccx->clm_ratio); - /*@PHYDM_DBG(dm, DBG_ENV_MNTR, "clm_chk_result=%d\n",clm_chk_result);*/ - return clm_chk_result; } @@ -1768,7 +1483,7 @@ void phydm_set_clm_mntr_mode(void *dm_void, enum clm_monitor_mode mode) phydm_ccx_hw_restart(dm); if (mode == CLM_DRIVER_MNTR) - phydm_clm_h2c(dm, 0, 0); + phydm_clm_h2c(dm, CLM_PERIOD_MAX, 0); } } @@ -1799,8 +1514,7 @@ void phydm_clm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, u32 i; for (i = 0; i < 4; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); } if ((strcmp(input[1], help) == 0)) { @@ -1852,7 +1566,7 @@ void phydm_clm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, ((ccx->clm_mntr_mode == CLM_FW_MNTR) ? "FW" : "driver"), clm_para.mntr_time); - if (phydm_clm_mntr_set(dm, &clm_para) == PHYDM_SET_SUCCESS) + if (phydm_clm_mntr_set(dm, &clm_para)) phydm_clm_trigger(dm); PDM_SNPF(out_len, used, output + used, out_len - used, @@ -1869,12 +1583,12 @@ u8 phydm_env_mntr_trigger(void *dm_void, struct nhm_para_info *nhm_para, struct clm_para_info *clm_para, struct env_trig_rpt *trig_rpt) { + u8 trigger_result = 0; #if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT)) struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; boolean nhm_set_ok = false; boolean clm_set_ok = false; - u8 trigger_result = 0; PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__); @@ -1907,17 +1621,16 @@ u8 phydm_env_mntr_trigger(void *dm_void, struct nhm_para_info *nhm_para, PHYDM_DBG(dm, DBG_ENV_MNTR, "nhm_rpt_stamp=%d, clm_rpt_stamp=%d,\n\n", trig_rpt->nhm_rpt_stamp, trig_rpt->clm_rpt_stamp); - - return trigger_result; #endif + return trigger_result; } u8 phydm_env_mntr_result(void *dm_void, struct env_mntr_rpt *rpt) { + u8 env_mntr_rpt = 0; #if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT)) struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; - u8 env_mntr_rpt = 0; u64 progressing_time = 0; u32 val_tmp = 0; @@ -1930,17 +1643,17 @@ u8 phydm_env_mntr_result(void *dm_void, struct env_mntr_rpt *rpt) if (phydm_nhm_get_result(dm)) { PHYDM_DBG(dm, DBG_ENV_MNTR, "Get NHM_rpt success\n"); phydm_nhm_get_utility(dm); - /* bypass r[11]*/ - phydm_nhm_cal_noise(dm, 0, NHM_RPT_NUM - 2, - ccx->nhm_rpt_sum - ccx->nhm_result[11]); rpt->nhm_ratio = ccx->nhm_ratio; - rpt->nhm_noise_pwr = ccx->nhm_noise_pwr; + rpt->nhm_env_ratio = ccx->nhm_env_ratio; + rpt->nhm_noise_pwr = ccx->nhm_level; + rpt->nhm_pwr = ccx->nhm_pwr; env_mntr_rpt |= NHM_SUCCESS; odm_move_memory(dm, &rpt->nhm_result[0], &ccx->nhm_result[0], NHM_RPT_NUM); } else { rpt->nhm_ratio = ENV_MNTR_FAIL; + rpt->nhm_env_ratio = ENV_MNTR_FAIL; } /*@Get CLM result*/ @@ -1977,58 +1690,11 @@ u8 phydm_env_mntr_result(void *dm_void, struct env_mntr_rpt *rpt) rpt->clm_rpt_stamp = ccx->clm_rpt_stamp; PHYDM_DBG(dm, DBG_ENV_MNTR, - "IGI=0x%x, nhm_ratio=%d, clm_ratio=%d, nhm_rpt_stamp=%d, clm_rpt_stamp=%d\n\n", - ccx->nhm_igi, rpt->nhm_ratio, rpt->clm_ratio, - rpt->nhm_rpt_stamp, rpt->clm_rpt_stamp); - + "IGI=0x%x, nhm_ratio=%d, nhm_env_ratio=%d, clm_ratio=%d, nhm_rpt_stamp=%d, clm_rpt_stamp=%d\n\n", + ccx->nhm_igi, rpt->nhm_ratio, rpt->nhm_env_ratio, + rpt->clm_ratio, rpt->nhm_rpt_stamp, rpt->clm_rpt_stamp); +#endif return env_mntr_rpt; -#endif -} - -/*@Environment Monitor*/ -void phydm_env_mntr_watchdog(void *dm_void) -{ -#if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT)) - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct ccx_info *ccx = &dm->dm_ccx_info; - boolean nhm_chk_ok = false; - boolean clm_chk_ok = false; - - if (!(dm->support_ability & ODM_BB_ENV_MONITOR)) - return; - - PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); - nhm_chk_ok = phydm_nhm_mntr_chk(dm, 262); /*@monitor 262ms*/ - clm_chk_ok = phydm_clm_mntr_chk(dm, 262); /*@monitor 262ms*/ - - /*@PHYDM_DBG(dm, DBG_ENV_MNTR, "nhm_chk_ok %d\n\n",nhm_chk_ok);*/ - /*@PHYDM_DBG(dm, DBG_ENV_MNTR, "clm_chk_ok %d\n\n",clm_chk_ok);*/ - - if (nhm_chk_ok) - phydm_nhm_trigger(dm); - - if (clm_chk_ok) - phydm_clm_trigger(dm); - - PHYDM_DBG(dm, DBG_ENV_MNTR, - "Summary: nhm_ratio=((%d)) clm_ratio=((%d))\n\n", - ccx->nhm_ratio, ccx->clm_ratio); -#endif -} - -void phydm_env_monitor_init(void *dm_void) -{ -#if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT)) - struct dm_struct *dm = (struct dm_struct *)dm_void; - - if (!(dm->support_ability & ODM_BB_ENV_MONITOR)) - return; - - PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); - phydm_ccx_hw_restart(dm); - phydm_nhm_init(dm); - phydm_clm_init(dm); -#endif } void phydm_env_mntr_dbg(void *dm_void, char input[][16], u32 *_used, @@ -2043,8 +1709,9 @@ void phydm_env_mntr_dbg(void *dm_void, char input[][16], u32 *_used, struct nhm_para_info nhm_para = {0}; struct env_mntr_rpt rpt = {0}; struct env_trig_rpt trig_rpt = {0}; - u8 set_result; - u8 i; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 set_result = 0; + u8 i = 0; PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); @@ -2053,13 +1720,13 @@ void phydm_env_mntr_dbg(void *dm_void, char input[][16], u32 *_used, "Basic-Trigger 262ms: {1}\n"); PDM_SNPF(out_len, used, output + used, out_len - used, "Get Result: {100}\n"); - } else if (var1[0] == 100) { /* @Get CLM results */ + } else if (var1[0] == 100) { /* Get results */ set_result = phydm_env_mntr_result(dm, &rpt); PDM_SNPF(out_len, used, output + used, out_len - used, - "Set Result=%d\n nhm_ratio=%d clm_ratio=%d\n nhm_rpt_stamp=%d, clm_rpt_stamp=%d,\n", - set_result, rpt.nhm_ratio, rpt.clm_ratio, - rpt.nhm_rpt_stamp, rpt.clm_rpt_stamp); + "Set Result=%d\n nhm_ratio=%d nhm_env_ratio=%d clm_ratio=%d\n nhm_rpt_stamp=%d, clm_rpt_stamp=%d,\n", + set_result, rpt.nhm_ratio, rpt.nhm_env_ratio, + rpt.clm_ratio, rpt.nhm_rpt_stamp, rpt.clm_rpt_stamp); for (i = 0; i <= 11; i++) { PDM_SNPF(out_len, used, output + used, out_len - used, @@ -2067,8 +1734,10 @@ void phydm_env_mntr_dbg(void *dm_void, char input[][16], u32 *_used, rpt.nhm_result[i], (((rpt.nhm_result[i] * 100) + 128) >> 8)); } - - } else { /* Set & trigger CLM */ + PDM_SNPF(out_len, used, output + used, out_len - used, + "[NHM] valid: %d percent, noise(RSSI) = %d\n", + ccx->nhm_level_valid, ccx->nhm_level); + } else { /* Set & trigger*/ /*nhm para*/ nhm_para.incld_txon = NHM_EXCLUDE_TXON; nhm_para.incld_cca = NHM_EXCLUDE_CCA; @@ -2076,8 +1745,9 @@ void phydm_env_mntr_dbg(void *dm_void, char input[][16], u32 *_used, nhm_para.nhm_app = NHM_ACS; nhm_para.nhm_lv = NHM_LV_2; nhm_para.mntr_time = 262; + nhm_para.en_1db_mode = false; - /*@clm para*/ + /*clm para*/ clm_para.clm_app = CLM_ACS; clm_para.clm_lv = CLM_LV_2; clm_para.mntr_time = 262; @@ -2095,3 +1765,1704 @@ void phydm_env_mntr_dbg(void *dm_void, char input[][16], u32 *_used, *_out_len = out_len; } +#ifdef FAHM_SUPPORT + +void phydm_fahm_racing_release(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u32 value32 = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "fahm_racing_release : lv:(%d)->(0)\n", + ccx->fahm_set_lv); + + ccx->fahm_ongoing = false; + ccx->fahm_set_lv = FAHM_RELEASE; + + if (!(ccx->fahm_app == FAHM_BACKGROUND || ccx->fahm_app == FAHM_ACS)) + phydm_pause_func(dm, F00_DIG, PHYDM_RESUME, + PHYDM_PAUSE_LEVEL_1, 1, &value32); + + ccx->fahm_app = FAHM_BACKGROUND; +} + +u8 phydm_fahm_racing_ctrl(void *dm_void, enum phydm_fahm_level lv) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 set_result = PHYDM_SET_SUCCESS; + /*acquire to control FAHM API*/ + + PHYDM_DBG(dm, DBG_ENV_MNTR, "fahm_ongoing=%d, lv:(%d)->(%d)\n", + ccx->fahm_ongoing, ccx->fahm_set_lv, lv); + if (ccx->fahm_ongoing) { + if (lv <= ccx->fahm_set_lv) { + set_result = PHYDM_SET_FAIL; + } else { + phydm_ccx_hw_restart(dm); + ccx->fahm_ongoing = false; + } + } + + if (set_result) + ccx->fahm_set_lv = lv; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "fahm racing success=%d\n", set_result); + return set_result; +} + +void phydm_fahm_trigger(void *dm_void) +{ /*@unit (4us)*/ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u32 reg = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + switch (dm->ic_ip_series) { + case PHYDM_IC_JGR3: + reg = R_0x1e60; + break; + case PHYDM_IC_AC: + reg = R_0x994; + break; + case PHYDM_IC_N: + reg = R_0x890; + break; + default: + break; + } + + odm_set_bb_reg(dm, reg, BIT(2), 0); + odm_set_bb_reg(dm, reg, BIT(2), 1); + + ccx->fahm_trigger_time = dm->phydm_sys_up_time; + ccx->fahm_rpt_stamp++; + ccx->fahm_ongoing = true; +} + +boolean +phydm_fahm_check_rdy(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + boolean is_ready = false; + u32 reg = 0, reg_bit = 0; + + switch (dm->ic_ip_series) { + case PHYDM_IC_JGR3: + reg = R_0x2d84; + reg_bit = 31; + break; + case PHYDM_IC_AC: + reg = R_0x1f98; + reg_bit = 31; + break; + case PHYDM_IC_N: + reg = R_0x9f0; + reg_bit = 31; + break; + default: + break; + } + + if (odm_get_bb_reg(dm, reg, BIT(reg_bit))) + is_ready = true; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "FAHM rdy=%d\n", is_ready); + + return is_ready; +} + +u8 phydm_fahm_cal_wgt_avg(void *dm_void, u8 start_i, u8 end_i, u16 r_sum, + u16 period) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 i = 0; + u32 pwr_tmp = 0; + u8 pwr = 0; + u32 fahm_valid = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + if (r_sum == 0) { + PHYDM_DBG(dm, DBG_ENV_MNTR, + "rpt_sum = 0, don't need to update\n"); + return 0x0; + } else if (end_i > FAHM_RPT_NUM - 1) { + PHYDM_DBG(dm, DBG_ENV_MNTR, + "[WARNING]end_i is larger than 11!!\n"); + return 0x0; + } + + for (i = start_i; i <= end_i; i++) { + if (i == 0) + pwr_tmp += ccx->fahm_result[0] * + MAX_2(ccx->fahm_th[0] - 2, 0); + else if (i == (FAHM_RPT_NUM - 1)) + pwr_tmp += ccx->fahm_result[FAHM_RPT_NUM - 1] * + (ccx->fahm_th[FAHM_TH_NUM - 1] + 2); + else + pwr_tmp += ccx->fahm_result[i] * + (ccx->fahm_th[i - 1] + ccx->fahm_th[i]) >> 1; + } + + /* protection for the case of minus pwr(RSSI)*/ + pwr = (u8)(NTH_TH_2_RSSI(MAX_2(PHYDM_DIV(pwr_tmp, r_sum), 20))); + fahm_valid = PHYDM_DIV(r_sum * 100, period); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "valid: ((%d)) percent, pwr(RSSI)=((%d))\n", + fahm_valid, pwr); + + return pwr; +} + +void phydm_fahm_get_utility(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + + if (ccx->fahm_result_sum >= ccx->fahm_result[0]) { + ccx->fahm_pwr = phydm_fahm_cal_wgt_avg(dm, 0, FAHM_RPT_NUM - 1, + ccx->fahm_result_sum, + ccx->fahm_period); + ccx->fahm_ratio = phydm_ccx_get_rpt_ratio(dm, + ccx->fahm_result_sum, ccx->fahm_period); + ccx->fahm_denom_ratio = phydm_ccx_get_rpt_ratio(dm, + ccx->fahm_denom_result, + ccx->fahm_period); + } else { + PHYDM_DBG(dm, DBG_ENV_MNTR, + "[warning] fahm_result_sum invalid\n"); + ccx->fahm_pwr = 0; + ccx->fahm_ratio = 0; + ccx->fahm_denom_ratio = 0; + } + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "fahm_pwr=%d, fahm_ratio=%d, fahm_denom_ratio=%d\n", + ccx->fahm_pwr, ccx->fahm_ratio, ccx->fahm_denom_ratio); +} + +boolean +phydm_fahm_get_result(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u32 value32 = 0; + u32 reg1 = 0; + u32 reg2 = 0; + u8 i = 0; + u32 fahm_rpt_sum_tmp = 0; + + switch (dm->ic_ip_series) { + case PHYDM_IC_JGR3: + reg1 = R_0x2d6c; + reg2 = R_0x2d84; + break; + case PHYDM_IC_AC: + reg1 = R_0x1f80; + reg2 = R_0x1f98; + break; + case PHYDM_IC_N: + reg1 = R_0x9d8; + reg2 = R_0x9f0; + break; + default: + break; + } + + if (!(phydm_fahm_check_rdy(dm))) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "Get FAHM report Fail\n"); + phydm_fahm_racing_release(dm); + return false; + } + + /*Get FAHM numerator and sum all fahm_result*/ + for (i = 0; i < 6; i++) { + value32 = odm_get_bb_reg(dm, reg1 + (i << 2), MASKDWORD); + ccx->fahm_result[i * 2] = (u16)(value32 & MASKLWORD); + ccx->fahm_result[i * 2 + 1] = (u16)((value32 & MASKHWORD) >> 16); + fahm_rpt_sum_tmp = (u32)(fahm_rpt_sum_tmp + + ccx->fahm_result[i * 2] + + ccx->fahm_result[i * 2 + 1]); + } + ccx->fahm_result_sum = (u16)fahm_rpt_sum_tmp; + + /*Get FAHM Denominator*/ + ccx->fahm_denom_result = (u16)odm_get_bb_reg(dm, reg2, MASKLWORD); + + if (!(ccx->fahm_inclu_cck)) + PHYDM_DBG(dm, DBG_ENV_MNTR, + "===>The following fahm report does not count CCK pkt\n"); + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "fahm_result_sum=%d, fahm_denom_result = %d\n", + ccx->fahm_result_sum, ccx->fahm_denom_result); + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "FAHM_Rpt[%d](H->L)[%d %d %d %d %d %d %d %d %d %d %d %d]\n", + ccx->fahm_rpt_stamp, ccx->fahm_result[11], + ccx->fahm_result[10], ccx->fahm_result[9], + ccx->fahm_result[8], ccx->fahm_result[7], ccx->fahm_result[6], + ccx->fahm_result[5], ccx->fahm_result[4], ccx->fahm_result[3], + ccx->fahm_result[2], ccx->fahm_result[1], + ccx->fahm_result[0]); + + phydm_fahm_racing_release(dm); + + if (fahm_rpt_sum_tmp > 0xffff) { + PHYDM_DBG(dm, DBG_ENV_MNTR, + "[Warning] Invalid FAHM RPT, total=%d\n", + fahm_rpt_sum_tmp); + return false; + } + + return true; +} + +void phydm_fahm_set_th_reg(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u32 val = 0; + + /*Set FAHM threshold*/ /*Unit: PWdB U(8,1)*/ + switch (dm->ic_ip_series) { + case PHYDM_IC_JGR3: + val = BYTE_2_DWORD(ccx->fahm_th[3], ccx->fahm_th[2], + ccx->fahm_th[1], ccx->fahm_th[0]); + odm_set_bb_reg(dm, R_0x1e50, MASKDWORD, val); + val = BYTE_2_DWORD(ccx->fahm_th[7], ccx->fahm_th[6], + ccx->fahm_th[5], ccx->fahm_th[4]); + odm_set_bb_reg(dm, R_0x1e54, MASKDWORD, val); + val = BYTE_2_DWORD(0, ccx->fahm_th[10], ccx->fahm_th[9], + ccx->fahm_th[8]); + odm_set_bb_reg(dm, R_0x1e58, 0xffffff, val); + break; + case PHYDM_IC_AC: + val = BYTE_2_DWORD(0, ccx->fahm_th[2], ccx->fahm_th[1], + ccx->fahm_th[0]); + odm_set_bb_reg(dm, R_0x1c38, 0xffffff00, val); + val = BYTE_2_DWORD(0, ccx->fahm_th[5], ccx->fahm_th[4], + ccx->fahm_th[3]); + odm_set_bb_reg(dm, R_0x1c78, 0xffffff00, val); + val = BYTE_2_DWORD(0, 0, ccx->fahm_th[7], ccx->fahm_th[6]); + odm_set_bb_reg(dm, R_0x1c7c, 0xffff0000, val); + val = BYTE_2_DWORD(0, ccx->fahm_th[10], ccx->fahm_th[9], + ccx->fahm_th[8]); + odm_set_bb_reg(dm, R_0x1cb8, 0xffffff00, val); + break; + case PHYDM_IC_N: + val = BYTE_2_DWORD(ccx->fahm_th[3], ccx->fahm_th[2], + ccx->fahm_th[1], ccx->fahm_th[0]); + odm_set_bb_reg(dm, R_0x970, MASKDWORD, val); + val = BYTE_2_DWORD(ccx->fahm_th[7], ccx->fahm_th[6], + ccx->fahm_th[5], ccx->fahm_th[4]); + odm_set_bb_reg(dm, R_0x974, MASKDWORD, val); + val = BYTE_2_DWORD(0, ccx->fahm_th[10], ccx->fahm_th[9], + ccx->fahm_th[8]); + odm_set_bb_reg(dm, R_0x978, 0xffffff, val); + break; + default: + break; + } + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "Update FAHM_th[H->L]=[%d %d %d %d %d %d %d %d %d %d %d]\n", + ccx->fahm_th[10], ccx->fahm_th[9], ccx->fahm_th[8], + ccx->fahm_th[7], ccx->fahm_th[6], ccx->fahm_th[5], + ccx->fahm_th[4], ccx->fahm_th[3], ccx->fahm_th[2], + ccx->fahm_th[1], ccx->fahm_th[0]); +} + +boolean +phydm_fahm_th_update_chk(void *dm_void, enum fahm_application fahm_app, + u8 *fahm_th, u32 *igi_new, boolean en_1db_mode, + u8 fahm_th0_manual) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + boolean is_update = false; + u8 igi_curr = phydm_get_igi(dm, BB_PATH_A); + u8 i = 0; + u8 th_tmp = igi_curr - CCA_CAP; + u8 th_step = 2; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "fahm_th_update_chk : App=%d, fahm_igi=0x%x, igi_curr=0x%x\n", + fahm_app, ccx->fahm_igi, igi_curr); + + if (igi_curr < 0x10) /* Protect for invalid IGI*/ + return false; + + switch (fahm_app) { + case FAHM_BACKGROUND: /*Get IGI from driver parameter(cur_ig_value)*/ + if (ccx->fahm_igi != igi_curr || ccx->fahm_app != fahm_app) { + is_update = true; + *igi_new = (u32)igi_curr; + + fahm_th[0] = (u8)IGI_2_NHM_TH(th_tmp); + + for (i = 1; i <= 10; i++) + fahm_th[i] = fahm_th[0] + + IGI_2_NHM_TH(th_step * i); + + } + break; + case FAHM_ACS: + if (ccx->fahm_igi != igi_curr || ccx->fahm_app != fahm_app) { + is_update = true; + *igi_new = (u32)igi_curr; + fahm_th[0] = (u8)IGI_2_NHM_TH(igi_curr - CCA_CAP); + for (i = 1; i <= 10; i++) + fahm_th[i] = fahm_th[0] + IGI_2_NHM_TH(2 * i); + } + break; + case FAHM_DBG: /*Get IGI from register*/ + igi_curr = phydm_get_igi(dm, BB_PATH_A); + if (ccx->fahm_igi != igi_curr || ccx->fahm_app != fahm_app) { + is_update = true; + *igi_new = (u32)igi_curr; + if (en_1db_mode) { + fahm_th[0] = (u8)IGI_2_NHM_TH(fahm_th0_manual + + 10); + th_step = 1; + } else { + fahm_th[0] = (u8)IGI_2_NHM_TH(igi_curr - + CCA_CAP); + } + + for (i = 1; i <= 10; i++) + fahm_th[i] = fahm_th[0] + + IGI_2_NHM_TH(th_step * i); + } + break; + } + + if (is_update) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "[Update FAHM_TH] igi_RSSI=%d\n", + IGI_2_RSSI(*igi_new)); + + for (i = 0; i < FAHM_TH_NUM; i++) + PHYDM_DBG(dm, DBG_ENV_MNTR, "FAHM_th[%d](RSSI) = %d\n", + i, NTH_TH_2_RSSI(fahm_th[i])); + } else { + PHYDM_DBG(dm, DBG_ENV_MNTR, "No need to update FAHM_TH\n"); + } + return is_update; +} + +void phydm_fahm_set(void *dm_void, u8 numer_opt, u8 denom_opt, + enum fahm_application app, u16 period, boolean en_1db_mode, + u8 th0_manual) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 fahm_th[FAHM_TH_NUM] = {0}; + u32 igi = 0x20; + u32 reg1 = 0, reg2 = 0, reg3 = 0; + u32 val_tmp = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "numer_opt=%d, denom_opt=%d, period=%d\n", + numer_opt, denom_opt, period); + + switch (dm->ic_ip_series) { + case PHYDM_IC_JGR3: + reg1 = R_0x1e60; + reg2 = R_0x1e58; + reg3 = R_0x1e5c; + break; + case PHYDM_IC_AC: + reg1 = R_0x994; + reg2 = R_0x1cf8; + break; + case PHYDM_IC_N: + reg1 = R_0x890; + reg2 = R_0x978; + reg3 = R_0x97c; + break; + default: + break; + } + + /*Set enable fa, ignore crc32 ok, ignore crc32 err*/ + if (numer_opt != ccx->fahm_numer_opt || + denom_opt != ccx->fahm_denom_opt) { + odm_set_bb_reg(dm, reg1, 0xe0, numer_opt); + odm_set_bb_reg(dm, reg1, 0x7000, denom_opt); + ccx->fahm_numer_opt = numer_opt; + ccx->fahm_denom_opt = denom_opt; + + /*[PHYDM-400]*/ + /*Counting B mode pkt for new B mode IP or fahm_opt is non-FA*/ + if ((dm->support_ic_type & ODM_RTL8723F) || + (((numer_opt | denom_opt) & FAHM_INCLU_FA) == 0)) + ccx->fahm_inclu_cck = true; + else + ccx->fahm_inclu_cck = false; + + odm_set_bb_reg(dm, reg1, BIT(4), ccx->fahm_inclu_cck); + PHYDM_DBG(dm, DBG_ENV_MNTR, "fahm_inclu_cck=%d\n", + ccx->fahm_inclu_cck); + } + + /*Set FAHM period*/ + if (period != ccx->fahm_period) { + switch (dm->ic_ip_series) { + case PHYDM_IC_AC: + odm_set_bb_reg(dm, reg2, 0xffff00, period); + break; + case PHYDM_IC_JGR3: + case PHYDM_IC_N: + odm_set_bb_reg(dm, reg2, 0xff000000, (period & 0xff)); + odm_set_bb_reg(dm, reg3, 0xff, (period & 0xff00) >> 8); + break; + default: + break; + } + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "Update FAHM period ((%d)) -> ((%d))\n", + ccx->fahm_period, period); + + ccx->fahm_period = period; + } + + /*Set FAHM threshold*/ + if (phydm_fahm_th_update_chk(dm, app, &fahm_th[0], &igi, en_1db_mode, + th0_manual)) { + /*Pause IGI*/ + if (app == FAHM_BACKGROUND || app == FAHM_ACS) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "DIG Free Run\n"); + } else if (phydm_pause_func(dm, F00_DIG, PHYDM_PAUSE, + PHYDM_PAUSE_LEVEL_1, 1, &igi) + == PAUSE_FAIL) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "pause DIG Fail\n"); + return; + } else { + PHYDM_DBG(dm, DBG_ENV_MNTR, "pause DIG=0x%x\n", igi); + } + ccx->fahm_app = app; + ccx->fahm_igi = (u8)igi; + odm_move_memory(dm, &ccx->fahm_th[0], &fahm_th, FAHM_TH_NUM); + + /*Set FAHM th*/ + phydm_fahm_set_th_reg(dm); + } +} + +boolean +phydm_fahm_mntr_set(void *dm_void, struct fahm_para_info *para) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u16 fahm_time = 0; /*unit: 4us*/ + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + if (para->mntr_time == 0) + return false; + + if (para->lv >= FAHM_MAX_NUM) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "Wrong LV=%d\n", para->lv); + return false; + } + + if (phydm_fahm_racing_ctrl(dm, para->lv) == PHYDM_SET_FAIL) + return false; + + if (para->mntr_time >= 262) + fahm_time = FAHM_PERIOD_MAX; + else + fahm_time = para->mntr_time * MS_TO_4US_RATIO; + + phydm_fahm_set(dm, para->numer_opt, para->denom_opt, para->app, + fahm_time, para->en_1db_mode, para->th0_manual); + + return true; +} + +boolean +phydm_fahm_mntr_racing_chk(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u32 sys_return_time = 0; + + if (ccx->fahm_manual_ctrl) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "FAHM in manual ctrl\n"); + return true; + } + + sys_return_time = ccx->fahm_trigger_time + MAX_ENV_MNTR_TIME; + + if (ccx->fahm_app != FAHM_BACKGROUND && + (sys_return_time > dm->phydm_sys_up_time)) { + PHYDM_DBG(dm, DBG_ENV_MNTR, + "fahm_app=%d, trigger_time %d, sys_time=%d\n", + ccx->fahm_app, ccx->fahm_trigger_time, + dm->phydm_sys_up_time); + + return true; + } + + return false; +} + +boolean +phydm_fahm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + struct fahm_para_info para = {0}; + boolean fahm_chk_result = false; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + if (phydm_fahm_mntr_racing_chk(dm)) + return fahm_chk_result; + + /*[FAHM trigger setting]------------------------------------------*/ + para.numer_opt = FAHM_INCLU_FA; + para.denom_opt = FAHM_INCLU_CRC_ERR; + para.app = FAHM_BACKGROUND; + para.lv = FAHM_LV_1; + para.en_1db_mode = false; + para.mntr_time = monitor_time; + + fahm_chk_result = phydm_fahm_mntr_set(dm, ¶); + + return fahm_chk_result; +} + +boolean +phydm_fahm_mntr_result(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + boolean fahm_chk_result = false; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + if (phydm_fahm_mntr_racing_chk(dm)) + return fahm_chk_result; + + /*[FAHM get result & calculate Utility]---------------------------*/ + if (phydm_fahm_get_result(dm)) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "Get FAHM_rpt success\n"); + phydm_fahm_get_utility(dm); + fahm_chk_result = true; + } + + return fahm_chk_result; +} + +void phydm_fahm_init(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u32 reg = 0; + + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM)) + return; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + ccx->fahm_app = FAHM_BACKGROUND; + ccx->fahm_igi = 0xff; + + /*Set FAHM threshold*/ + ccx->fahm_ongoing = false; + ccx->fahm_set_lv = FAHM_RELEASE; + + if (phydm_fahm_th_update_chk(dm, ccx->fahm_app, &ccx->fahm_th[0], + (u32 *)&ccx->fahm_igi, false, 0)) + phydm_fahm_set_th_reg(dm); + + ccx->fahm_period = 0; + ccx->fahm_numer_opt = 0; + ccx->fahm_denom_opt = 0; + ccx->fahm_manual_ctrl = 0; + ccx->fahm_rpt_stamp = 0; + ccx->fahm_inclu_cck = false; + + switch (dm->ic_ip_series) { + case PHYDM_IC_JGR3: + reg = R_0x1e60; + break; + case PHYDM_IC_AC: + reg = R_0x994; + break; + case PHYDM_IC_N: + reg = R_0x890; + break; + default: + break; + } + + /*Counting OFDM pkt*/ + odm_set_bb_reg(dm, reg, BIT(3), 1); +} + +void phydm_fahm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, + u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + struct fahm_para_info para = {0}; + char help[] = "-h"; + u32 var1[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u16 result_tmp = 0; + u8 i = 0; + + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM)) + return; + + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "FAHM Basic-Trigger 262ms: {1}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "FAHM Adv-Trigger: {2} {numer_opt} {denom_opt}\n {App:1 for dbg} {LV:1~4} {0~262ms}, 1dB mode :{en} {t[0](RSSI)}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "FAHM Get Result: {100}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "numer_opt/denom_opt: {BIT 0/1/2} = {FA/CRC32_OK/CRC32_ERR}\n"); + } else if (var1[0] == 100) { /*Get FAHM results*/ + PDM_SNPF(out_len, used, output + used, out_len - used, + "IGI=0x%x, rpt_stamp=%d\n", ccx->fahm_igi, + ccx->fahm_rpt_stamp); + + if (phydm_fahm_get_result(dm)) { + if (!(ccx->fahm_inclu_cck)) + PDM_SNPF(out_len, used, output + used, + out_len - used, + "===>The following fahm report does not count CCK pkt\n"); + + for (i = 0; i < FAHM_RPT_NUM; i++) { + result_tmp = ccx->fahm_result[i]; + PDM_SNPF(out_len, used, output + used, + out_len - used, + "fahm_rpt[%d] = %d (%d percent)\n", + i, result_tmp, + (((result_tmp * 100) + 32768) >> 16)); + } + phydm_fahm_get_utility(dm); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "fahm_pwr=%d, fahm_ratio=%d, fahm_denom_ratio=%d\n", + ccx->fahm_pwr, ccx->fahm_ratio, + ccx->fahm_denom_ratio); + } else { + PDM_SNPF(out_len, used, output + used, out_len - used, + "Get FAHM_rpt Fail\n"); + } + ccx->fahm_manual_ctrl = 0; + } else { /*FAMH trigger*/ + ccx->fahm_manual_ctrl = 1; + + for (i = 1; i < 9; i++) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + + if (var1[0] == 1) { + para.numer_opt = FAHM_INCLU_FA; + para.denom_opt = FAHM_INCLU_CRC_ERR; + para.app = FAHM_DBG; + para.lv = FAHM_LV_4; + para.mntr_time = 262; + para.en_1db_mode = false; + para.th0_manual = 0; + } else { + para.numer_opt = (u8)var1[1]; + para.denom_opt = (u8)var1[2]; + para.app = (enum fahm_application)var1[3]; + para.lv = (enum phydm_fahm_level)var1[4]; + para.mntr_time = (u16)var1[5]; + para.en_1db_mode = (boolean)var1[6]; + para.th0_manual = (u8)var1[7]; + } + + PDM_SNPF(out_len, used, output + used, out_len - used, + "numer_opt=%d, denom_opt=%d, app=%d, lv=%d, time=%d ms\n", + para.numer_opt, para.denom_opt,para.app, para.lv, + para.mntr_time); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "en_1db_mode=%d, th0(for 1db mode)=%d\n", + para.en_1db_mode, para.th0_manual); + + if (phydm_fahm_mntr_set(dm, ¶)) + phydm_fahm_trigger(dm); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "IGI=0x%x, rpt_stamp=%d\n", ccx->fahm_igi, + ccx->fahm_rpt_stamp); + + for (i = 0; i < FAHM_TH_NUM; i++) + PDM_SNPF(out_len, used, output + used, out_len - used, + "FAHM_th[%d] RSSI = %d\n", i, + NTH_TH_2_RSSI(ccx->fahm_th[i])); + } + + *_used = used; + *_out_len = out_len; +} + +#endif /*#ifdef FAHM_SUPPORT*/ + +#ifdef IFS_CLM_SUPPORT +void phydm_ifs_clm_restart(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + /*restart IFS_CLM*/ + odm_set_bb_reg(dm, R_0x1ee4, BIT(29), 0x0); + odm_set_bb_reg(dm, R_0x1ee4, BIT(29), 0x1); +} + +void phydm_ifs_clm_racing_release(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + PHYDM_DBG(dm, DBG_ENV_MNTR, "ifs clm lv:(%d)->(0)\n", + ccx->ifs_clm_set_lv); + + ccx->ifs_clm_ongoing = false; + ccx->ifs_clm_set_lv = IFS_CLM_RELEASE; + ccx->ifs_clm_app = IFS_CLM_BACKGROUND; +} + +u8 phydm_ifs_clm_racing_ctrl(void *dm_void, enum phydm_ifs_clm_level ifs_clm_lv) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 set_result = PHYDM_SET_SUCCESS; + /*acquire to control IFS CLM API*/ + + PHYDM_DBG(dm, DBG_ENV_MNTR, "ifs clm_ongoing=%d, lv:(%d)->(%d)\n", + ccx->ifs_clm_ongoing, ccx->ifs_clm_set_lv, ifs_clm_lv); + if (ccx->ifs_clm_ongoing) { + if (ifs_clm_lv <= ccx->ifs_clm_set_lv) { + set_result = PHYDM_SET_FAIL; + } else { + phydm_ifs_clm_restart(dm); + ccx->ifs_clm_ongoing = false; + } + } + + if (set_result) + ccx->ifs_clm_set_lv = ifs_clm_lv; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "ifs clm racing success=%d\n", set_result); + return set_result; +} + +void phydm_ifs_clm_trigger(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + /*Trigger IFS_CLM*/ + pdm_set_reg(dm, R_0x1ee4, BIT(29), 0); + pdm_set_reg(dm, R_0x1ee4, BIT(29), 1); + ccx->ifs_clm_trigger_time = dm->phydm_sys_up_time; + ccx->ifs_clm_rpt_stamp++; + ccx->ifs_clm_ongoing = true; +} + +void phydm_ifs_clm_get_utility(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u16 denom = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + denom = ccx->ifs_clm_period; + ccx->ifs_clm_tx_ratio = phydm_ccx_get_rpt_ratio(dm, ccx->ifs_clm_tx, + denom); + ccx->ifs_clm_edcca_excl_cca_ratio = phydm_ccx_get_rpt_ratio(dm, + ccx->ifs_clm_edcca_excl_cca, + denom); + ccx->ifs_clm_cck_fa_ratio = phydm_ccx_get_rpt_ratio(dm, + ccx->ifs_clm_cckfa, denom); + ccx->ifs_clm_ofdm_fa_ratio = phydm_ccx_get_rpt_ratio(dm, + ccx->ifs_clm_ofdmfa, denom); + ccx->ifs_clm_cck_cca_excl_fa_ratio = phydm_ccx_get_rpt_ratio(dm, + ccx->ifs_clm_cckcca_excl_fa, + denom); + ccx->ifs_clm_ofdm_cca_excl_fa_ratio = phydm_ccx_get_rpt_ratio(dm, + ccx->ifs_clm_ofdmcca_excl_fa, + denom); + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "Tx_ratio = %d, EDCCA_exclude_CCA_ratio = %d \n", + ccx->ifs_clm_tx_ratio, ccx->ifs_clm_edcca_excl_cca_ratio); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "CCK : FA_ratio = %d, CCA_exclude_FA_ratio = %d \n", + ccx->ifs_clm_cck_fa_ratio, + ccx->ifs_clm_cck_cca_excl_fa_ratio); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "OFDM : FA_ratio = %d, CCA_exclude_FA_ratio = %d \n", + ccx->ifs_clm_ofdm_fa_ratio, + ccx->ifs_clm_ofdm_cca_excl_fa_ratio); +} + +void phydm_ifs_clm_get_result(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u32 value32 = 0; + u8 i = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + /*Enhance CLM result*/ + value32 = odm_get_bb_reg(dm, R_0x2e60, MASKDWORD); + ccx->ifs_clm_tx = (u16)(value32 & MASKLWORD); + ccx->ifs_clm_edcca_excl_cca = (u16)((value32 & MASKHWORD) >> 16); + value32 = odm_get_bb_reg(dm, R_0x2e64, MASKDWORD); + ccx->ifs_clm_ofdmfa = (u16)(value32 & MASKLWORD); + ccx->ifs_clm_ofdmcca_excl_fa = (u16)((value32 & MASKHWORD) >> 16); + value32 = odm_get_bb_reg(dm, R_0x2e68, MASKDWORD); + ccx->ifs_clm_cckfa = (u16)(value32 & MASKLWORD); + ccx->ifs_clm_cckcca_excl_fa = (u16)((value32 & MASKHWORD) >> 16); + value32 = odm_get_bb_reg(dm, R_0x2e6c, MASKDWORD); + ccx->ifs_clm_total_cca = (u16)(value32 & MASKLWORD); + + /* IFS result */ + value32 = odm_get_bb_reg(dm, R_0x2e70, MASKDWORD); + odm_move_memory(dm, &ccx->ifs_clm_his[0], &value32, 4); + value32 = odm_get_bb_reg(dm, R_0x2e74, MASKDWORD); + ccx->ifs_clm_avg[0] = (u16)(value32 & MASKLWORD); + ccx->ifs_clm_avg[1] = (u16)((value32 & MASKHWORD) >> 16); + value32 = odm_get_bb_reg(dm, R_0x2e78, MASKDWORD); + ccx->ifs_clm_avg[2] = (u16)(value32 & MASKLWORD); + ccx->ifs_clm_avg[3] = (u16)((value32 & MASKHWORD) >> 16); + value32 = odm_get_bb_reg(dm, R_0x2e7c, MASKDWORD); + ccx->ifs_clm_avg_cca[0] = (u16)(value32 & MASKLWORD); + ccx->ifs_clm_avg_cca[1] = (u16)((value32 & MASKHWORD) >> 16); + value32 = odm_get_bb_reg(dm, R_0x2e80, MASKDWORD); + ccx->ifs_clm_avg_cca[2] = (u16)(value32 & MASKLWORD); + ccx->ifs_clm_avg_cca[3] = (u16)((value32 & MASKHWORD) >> 16); + + /* Print Result */ + PHYDM_DBG(dm, DBG_ENV_MNTR, + "ECLM_Rpt[%d]: \nTx = %d, EDCCA_exclude_CCA = %d \n", + ccx->ifs_clm_rpt_stamp, ccx->ifs_clm_tx, + ccx->ifs_clm_edcca_excl_cca); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "[FA_cnt] {CCK, OFDM} = {%d, %d}\n", + ccx->ifs_clm_cckfa, ccx->ifs_clm_ofdmfa); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "[CCA_exclude_FA_cnt] {CCK, OFDM} = {%d, %d}\n", + ccx->ifs_clm_cckcca_excl_fa, ccx->ifs_clm_ofdmcca_excl_fa); + PHYDM_DBG(dm, DBG_ENV_MNTR, "CCATotal = %d\n", ccx->ifs_clm_total_cca); + PHYDM_DBG(dm, DBG_ENV_MNTR, "Time:[his, avg, avg_cca]\n"); + for (i = 0; i < IFS_CLM_NUM; i++) + PHYDM_DBG(dm, DBG_ENV_MNTR, + "T%d:[%d, %d, %d]\n", i + 1, + ccx->ifs_clm_his[i], ccx->ifs_clm_avg[i], + ccx->ifs_clm_avg_cca[i]); + + phydm_ifs_clm_racing_release(dm); + + return; +} + +void phydm_ifs_clm_set_th_reg(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 i = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + /*Set IFS period TH*/ + odm_set_bb_reg(dm, R_0x1ed4, BIT(31), ccx->ifs_clm_th_en[0]); + odm_set_bb_reg(dm, R_0x1ed8, BIT(31), ccx->ifs_clm_th_en[1]); + odm_set_bb_reg(dm, R_0x1edc, BIT(31), ccx->ifs_clm_th_en[2]); + odm_set_bb_reg(dm, R_0x1ee0, BIT(31), ccx->ifs_clm_th_en[3]); + odm_set_bb_reg(dm, R_0x1ed4, 0x7fff0000, ccx->ifs_clm_th_low[0]); + odm_set_bb_reg(dm, R_0x1ed8, 0x7fff0000, ccx->ifs_clm_th_low[1]); + odm_set_bb_reg(dm, R_0x1edc, 0x7fff0000, ccx->ifs_clm_th_low[2]); + odm_set_bb_reg(dm, R_0x1ee0, 0x7fff0000, ccx->ifs_clm_th_low[3]); + odm_set_bb_reg(dm, R_0x1ed4, MASKLWORD, ccx->ifs_clm_th_high[0]); + odm_set_bb_reg(dm, R_0x1ed8, MASKLWORD, ccx->ifs_clm_th_high[1]); + odm_set_bb_reg(dm, R_0x1edc, MASKLWORD, ccx->ifs_clm_th_high[2]); + odm_set_bb_reg(dm, R_0x1ee0, MASKLWORD, ccx->ifs_clm_th_high[3]); + + for (i = 0; i < IFS_CLM_NUM; i++) + PHYDM_DBG(dm, DBG_ENV_MNTR, + "Update IFS_CLM_th%d[High Low] : [%d %d]\n", i + 1, + ccx->ifs_clm_th_high[i], ccx->ifs_clm_th_low[i]); +} + +boolean phydm_ifs_clm_th_update_chk(void *dm_void, + enum ifs_clm_application ifs_clm_app, + boolean *ifs_clm_th_en, u16 *ifs_clm_th_low, + u16 *ifs_clm_th_high, s16 th_shift) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + boolean is_update = false; + u16 ifs_clm_th_low_bg[IFS_CLM_NUM] = {12, 5, 2, 0}; + u16 ifs_clm_th_high_bg[IFS_CLM_NUM] = {64, 12, 5, 2}; + u8 i = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + PHYDM_DBG(dm, DBG_ENV_MNTR, "App=%d, th_shift=%d\n", ifs_clm_app, + th_shift); + + switch (ifs_clm_app) { + case IFS_CLM_BACKGROUND: + case IFS_CLM_ACS: + case IFS_CLM_HP_TAS: + if (ccx->ifs_clm_app != ifs_clm_app || th_shift != 0) { + is_update = true; + + for (i = 0; i < IFS_CLM_NUM; i++) { + ifs_clm_th_en[i] = true; + ifs_clm_th_low[i] = ifs_clm_th_low_bg[i]; + ifs_clm_th_high[i] = ifs_clm_th_high_bg[i]; + } + } + break; + case IFS_CLM_DBG: + if (ccx->ifs_clm_app != ifs_clm_app || th_shift != 0) { + is_update = true; + + for (i = 0; i < IFS_CLM_NUM; i++) { + ifs_clm_th_en[i] = true; + ifs_clm_th_low[i] = MAX_2(ccx->ifs_clm_th_low[i] + + th_shift, 0); + ifs_clm_th_high[i] = MAX_2(ccx->ifs_clm_th_high[i] + + th_shift, 0); + } + } + break; + default: + break; + } + + if (is_update) + PHYDM_DBG(dm, DBG_ENV_MNTR, "[Update IFS_TH]\n"); + else + PHYDM_DBG(dm, DBG_ENV_MNTR, "No need to update IFS_TH\n"); + + return is_update; +} + +void phydm_ifs_clm_set(void *dm_void, enum ifs_clm_application ifs_clm_app, + u16 period, u8 ctrl_unit, s16 th_shift) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + boolean ifs_clm_th_en[IFS_CLM_NUM] = {0}; + u16 ifs_clm_th_low[IFS_CLM_NUM] = {0}; + u16 ifs_clm_th_high[IFS_CLM_NUM] = {0}; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + PHYDM_DBG(dm, DBG_ENV_MNTR, "period=%d, ctrl_unit=%d\n", period, + ctrl_unit); + + /*Set Unit*/ + if (ctrl_unit != ccx->ifs_clm_ctrl_unit) { + odm_set_bb_reg(dm, R_0x1ee4, 0xc0000000, ctrl_unit); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "Update IFS_CLM unit ((%d)) -> ((%d))\n", + ccx->ifs_clm_ctrl_unit, ctrl_unit); + ccx->ifs_clm_ctrl_unit = ctrl_unit; + } + + /*Set Duration*/ + if (period != ccx->ifs_clm_period) { + odm_set_bb_reg(dm, R_0x1eec, 0xc0000000, (period & 0x3)); + odm_set_bb_reg(dm, R_0x1ef0, 0xfe000000, ((period >> 2) & + 0x7f)); + odm_set_bb_reg(dm, R_0x1ef4, 0xc0000000, ((period >> 9) & + 0x3)); + odm_set_bb_reg(dm, R_0x1ef8, 0x3e000000, ((period >> 11) & + 0x1f)); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "Update IFS_CLM period ((%d)) -> ((%d))\n", + ccx->ifs_clm_period, period); + ccx->ifs_clm_period = period; + } + + /*Set IFS CLM threshold*/ + if (phydm_ifs_clm_th_update_chk(dm, ifs_clm_app, &ifs_clm_th_en[0], + &ifs_clm_th_low[0], &ifs_clm_th_high[0], + th_shift)) { + + ccx->ifs_clm_app = ifs_clm_app; + odm_move_memory(dm, &ccx->ifs_clm_th_en[0], &ifs_clm_th_en, + IFS_CLM_NUM); + odm_move_memory(dm, &ccx->ifs_clm_th_low[0], &ifs_clm_th_low, + IFS_CLM_NUM); + odm_move_memory(dm, &ccx->ifs_clm_th_high[0], &ifs_clm_th_high, + IFS_CLM_NUM); + + phydm_ifs_clm_set_th_reg(dm); + } +} + +boolean +phydm_ifs_clm_mntr_set(void *dm_void, struct ifs_clm_para_info *ifs_clm_para) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u16 ifs_clm_time = 0; /*unit: 4/8/12/16us*/ + u8 unit = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + if (ifs_clm_para->mntr_time == 0) + return false; + + if (ifs_clm_para->ifs_clm_lv >= IFS_CLM_MAX_NUM) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "Wrong LV=%d\n", + ifs_clm_para->ifs_clm_lv); + return false; + } + + if (phydm_ifs_clm_racing_ctrl(dm, ifs_clm_para->ifs_clm_lv) == PHYDM_SET_FAIL) + return false; + + if (ifs_clm_para->mntr_time >= 1048) { + unit = IFS_CLM_16; + ifs_clm_time = IFS_CLM_PERIOD_MAX; /*65535 * 16us = 1048ms*/ + } else if (ifs_clm_para->mntr_time >= 786) {/*65535 * 12us = 786 ms*/ + unit = IFS_CLM_16; + ifs_clm_time = PHYDM_DIV(ifs_clm_para->mntr_time * MS_TO_US, 16); + } else if (ifs_clm_para->mntr_time >= 524) { + unit = IFS_CLM_12; + ifs_clm_time = PHYDM_DIV(ifs_clm_para->mntr_time * MS_TO_US, 12); + } else if (ifs_clm_para->mntr_time >= 262) { + unit = IFS_CLM_8; + ifs_clm_time = PHYDM_DIV(ifs_clm_para->mntr_time * MS_TO_US, 8); + } else { + unit = IFS_CLM_4; + ifs_clm_time = PHYDM_DIV(ifs_clm_para->mntr_time * MS_TO_US, 4); + } + + phydm_ifs_clm_set(dm, ifs_clm_para->ifs_clm_app, ifs_clm_time, unit, + ifs_clm_para->th_shift); + + return true; +} + +boolean +phydm_ifs_clm_mntr_racing_chk(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u32 sys_return_time = 0; + + if (ccx->ifs_clm_manual_ctrl) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "IFS_CLM in manual ctrl\n"); + return true; + } + + sys_return_time = ccx->ifs_clm_trigger_time + MAX_ENV_MNTR_TIME; + + if (ccx->ifs_clm_app != IFS_CLM_BACKGROUND && + (sys_return_time > dm->phydm_sys_up_time)) { + PHYDM_DBG(dm, DBG_ENV_MNTR, + "ifs_clm_app=%d, trigger_time %d, sys_time=%d\n", + ccx->ifs_clm_app, ccx->ifs_clm_trigger_time, + dm->phydm_sys_up_time); + + return true; + } + + return false; +} + +boolean +phydm_ifs_clm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + struct ifs_clm_para_info ifs_clm_para = {0}; + boolean ifs_clm_chk_result = false; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + if (phydm_ifs_clm_mntr_racing_chk(dm)) + return ifs_clm_chk_result; + + /*[IFS CLM trigger setting]------------------------------------------*/ + ifs_clm_para.ifs_clm_app = IFS_CLM_BACKGROUND; + ifs_clm_para.ifs_clm_lv = IFS_CLM_LV_1; + ifs_clm_para.mntr_time = monitor_time; + ifs_clm_para.th_shift = 0; + + ifs_clm_chk_result = phydm_ifs_clm_mntr_set(dm, &ifs_clm_para); + + return ifs_clm_chk_result; +} + +boolean +phydm_ifs_clm_mntr_result(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + boolean ifs_clm_chk_result = false; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + if (phydm_ifs_clm_mntr_racing_chk(dm)) + return ifs_clm_chk_result; + + /*[IFS CLM get result] ------------------------------------]*/ + phydm_ifs_clm_get_result(dm); + phydm_ifs_clm_get_utility(dm); + ifs_clm_chk_result = true; + + return ifs_clm_chk_result; +} + +void phydm_ifs_clm_init(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + ccx->ifs_clm_app = IFS_CLM_BACKGROUND; + + /*Set IFS threshold*/ + ccx->ifs_clm_ongoing = false; + ccx->ifs_clm_set_lv = IFS_CLM_RELEASE; + + if (phydm_ifs_clm_th_update_chk(dm, ccx->ifs_clm_app, + &ccx->ifs_clm_th_en[0], + &ccx->ifs_clm_th_low[0], + &ccx->ifs_clm_th_high[0], 0xffff)) + phydm_ifs_clm_set_th_reg(dm); + + ccx->ifs_clm_period = 0; + ccx->ifs_clm_ctrl_unit = IFS_CLM_INIT; + ccx->ifs_clm_manual_ctrl = 0; + ccx->ifs_clm_rpt_stamp = 0; +} + +void phydm_ifs_clm_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + struct ifs_clm_para_info ifs_clm_para; + char help[] = "-h"; + u32 var1[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u8 result_tmp = 0; + u8 i = 0; + u16 th_shift = 0; + + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM)) + return; + + for (i = 0; i < 5; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + } + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "IFS_CLM Basic-Trigger 960ms: {1}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "IFS_CLM Adv-Trigger: {2} {App:3 for dbg} {LV:1~4} {0~2096ms} {th_shift}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "IFS_CLM Get Result: {100}\n"); + } else if (var1[0] == 100) { /*Get IFS_CLM results*/ + phydm_ifs_clm_get_result(dm); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "ECLM_Rpt[%d]: \nTx = %d \nEDCCA_exclude_CCA = %d\n", + ccx->ifs_clm_rpt_stamp, ccx->ifs_clm_tx, + ccx->ifs_clm_edcca_excl_cca); + PDM_SNPF(out_len, used, output + used, out_len - used, + "[FA_cnt] {CCK, OFDM} = {%d, %d}\n", + ccx->ifs_clm_cckfa, ccx->ifs_clm_ofdmfa); + PDM_SNPF(out_len, used, output + used, out_len - used, + "[CCA_exclude_FA_cnt] {CCK, OFDM} = {%d, %d}\n", + ccx->ifs_clm_cckcca_excl_fa, + ccx->ifs_clm_ofdmcca_excl_fa); + PDM_SNPF(out_len, used, output + used, out_len - used, + "CCATotal = %d\n", ccx->ifs_clm_total_cca); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Time:[his, avg, avg_cca]\n"); + for (i = 0; i < IFS_CLM_NUM; i++) + PDM_SNPF(out_len, used, output + used, out_len - used, + "T%d:[%d, %d, %d]\n", i + 1, + ccx->ifs_clm_his[i], ccx->ifs_clm_avg[i], + ccx->ifs_clm_avg_cca[i]); + + phydm_ifs_clm_get_utility(dm); + + ccx->ifs_clm_manual_ctrl = 0; + } else { /*IFS_CLM trigger*/ + ccx->ifs_clm_manual_ctrl = 1; + + if (var1[0] == 1) { + ifs_clm_para.ifs_clm_app = IFS_CLM_DBG; + ifs_clm_para.ifs_clm_lv = IFS_CLM_LV_4; + ifs_clm_para.mntr_time = 960; + ifs_clm_para.th_shift = 0; + } else { + ifs_clm_para.ifs_clm_app = (enum ifs_clm_application)var1[1]; + ifs_clm_para.ifs_clm_lv = (enum phydm_ifs_clm_level)var1[2]; + ifs_clm_para.mntr_time = (u16)var1[3]; + ifs_clm_para.th_shift = (s16)var1[4]; + } + + PDM_SNPF(out_len, used, output + used, out_len - used, + "app=%d, lv=%d, time=%d ms, th_shift=%s%d\n", + ifs_clm_para.ifs_clm_app, ifs_clm_para.ifs_clm_lv, + ifs_clm_para.mntr_time, + (ifs_clm_para.th_shift > 0) ? "+" : "-", + ifs_clm_para.th_shift); + + if (phydm_ifs_clm_mntr_set(dm, &ifs_clm_para) == PHYDM_SET_SUCCESS) + phydm_ifs_clm_trigger(dm); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "rpt_stamp=%d\n", ccx->ifs_clm_rpt_stamp); + for (i = 0; i < IFS_CLM_NUM; i++) + PDM_SNPF(out_len, used, output + used, out_len - used, + "IFS_CLM_th%d[High Low] : [%d %d]\n", i + 1, + ccx->ifs_clm_th_high[i], + ccx->ifs_clm_th_low[i]); + } + + *_used = used; + *_out_len = out_len; +} +#endif + +u8 phydm_enhance_mntr_trigger(void *dm_void, struct nhm_para_info *nhm_para, + struct clm_para_info *clm_para, + struct fahm_para_info *fahm_para, + struct ifs_clm_para_info *ifs_clm_para, + struct enhance_mntr_trig_rpt *trig_rpt) +{ + u8 trigger_result = 0; +#if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT) && defined(FAHM_SUPPORT) && defined(IFS_CLM_SUPPORT)) + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + boolean nhm_set_ok = false; + boolean clm_set_ok = false; + boolean fahm_set_ok = false; + boolean ifs_clm_set_ok = false; + + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM) || + !(dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM)) + return trigger_result; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__); + + nhm_set_ok = phydm_nhm_mntr_set(dm, nhm_para); + + if (ccx->clm_mntr_mode == CLM_DRIVER_MNTR) { + clm_set_ok = phydm_clm_mntr_set(dm, clm_para); + } else if (ccx->clm_mntr_mode == CLM_FW_MNTR) { + phydm_clm_h2c(dm, CLM_PERIOD_MAX, true); + trigger_result |= CLM_SUCCESS; + } + + fahm_set_ok = phydm_fahm_mntr_set(dm, fahm_para); + + ifs_clm_set_ok = phydm_ifs_clm_mntr_set(dm, ifs_clm_para); + + if (nhm_set_ok) { + phydm_nhm_trigger(dm); + trigger_result |= NHM_SUCCESS; + } + + if (clm_set_ok) { + phydm_clm_trigger(dm); + trigger_result |= CLM_SUCCESS; + } + + if (fahm_set_ok) { + phydm_fahm_trigger(dm); + trigger_result |= FAHM_SUCCESS; + } + + if (ifs_clm_set_ok) { + phydm_ifs_clm_trigger(dm); + trigger_result |= IFS_CLM_SUCCESS; + } + + /*monitor for the test duration*/ + ccx->start_time = odm_get_current_time(dm); + + trig_rpt->nhm_rpt_stamp = ccx->nhm_rpt_stamp; + trig_rpt->clm_rpt_stamp = ccx->clm_rpt_stamp; + trig_rpt->fahm_rpt_stamp = ccx->fahm_rpt_stamp; + trig_rpt->ifs_clm_rpt_stamp = ccx->ifs_clm_rpt_stamp; + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "rpt_stamp{NHM, CLM, FAHM, IFS_CLM}={%d, %d, %d, %d}\n\n", + trig_rpt->nhm_rpt_stamp, trig_rpt->clm_rpt_stamp, + trig_rpt->fahm_rpt_stamp, trig_rpt->ifs_clm_rpt_stamp); + +#endif + return trigger_result; +} + +u8 phydm_enhance_mntr_result(void *dm_void, struct enhance_mntr_rpt *rpt) +{ + u8 enhance_mntr_rpt = 0; +#if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT) && defined(FAHM_SUPPORT) && defined(IFS_CLM_SUPPORT)) + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u64 progressing_time = 0; + u32 val_tmp = 0; + + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM) || + !(dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM)) + return enhance_mntr_rpt; + + /*monitor for the test duration*/ + progressing_time = odm_get_progressing_time(dm, ccx->start_time); + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__); + PHYDM_DBG(dm, DBG_ENV_MNTR, "enhance_mntr_time=%lld\n", + progressing_time); + + /*Get NHM result*/ + if (phydm_nhm_get_result(dm)) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "Get NHM_rpt success\n"); + phydm_nhm_get_utility(dm); + rpt->nhm_ratio = ccx->nhm_ratio; + rpt->nhm_env_ratio = ccx->nhm_env_ratio; + rpt->nhm_noise_pwr = ccx->nhm_level; + rpt->nhm_pwr = ccx->nhm_pwr; + enhance_mntr_rpt |= NHM_SUCCESS; + + odm_move_memory(dm, &rpt->nhm_result[0], + &ccx->nhm_result[0], NHM_RPT_NUM); + } else { + rpt->nhm_ratio = ENV_MNTR_FAIL; + rpt->nhm_env_ratio = ENV_MNTR_FAIL; + } + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "[NHM]rpt_stamp=%d, IGI=0x%x, ratio=%d, env_ratio=%d, noise_pwr=%d, pwr=%d\n", + rpt->nhm_rpt_stamp, ccx->nhm_igi, rpt->nhm_ratio, + rpt->nhm_env_ratio, rpt->nhm_noise_pwr, rpt->nhm_pwr); + + /*Get CLM result*/ + if (ccx->clm_mntr_mode == CLM_DRIVER_MNTR) { + if (phydm_clm_get_result(dm)) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "Get CLM_rpt success\n"); + phydm_clm_get_utility(dm); + enhance_mntr_rpt |= CLM_SUCCESS; + rpt->clm_ratio = ccx->clm_ratio; + } else { + rpt->clm_ratio = ENV_MNTR_FAIL; + } + } else { + if (ccx->clm_fw_result_cnt != 0) { + val_tmp = ccx->clm_fw_result_acc + / ccx->clm_fw_result_cnt; + ccx->clm_ratio = (u8)val_tmp; + } else { + ccx->clm_ratio = 0; + } + rpt->clm_ratio = ccx->clm_ratio; + PHYDM_DBG(dm, DBG_ENV_MNTR, + "clm_fw_result_acc=%d, clm_fw_result_cnt=%d\n", + ccx->clm_fw_result_acc, ccx->clm_fw_result_cnt); + + ccx->clm_fw_result_acc = 0; + ccx->clm_fw_result_cnt = 0; + enhance_mntr_rpt |= CLM_SUCCESS; + } + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[CLM]rpt_stamp=%d, ratio=%d\n", + rpt->clm_rpt_stamp, rpt->clm_ratio); + + /*Get FAHM result*/ + if (phydm_fahm_get_result(dm)) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "Get FAHM_rpt success\n"); + phydm_fahm_get_utility(dm); + rpt->fahm_pwr = ccx->fahm_pwr; + rpt->fahm_ratio = ccx->fahm_ratio; + rpt->fahm_denom_ratio = ccx->fahm_denom_ratio; + rpt->fahm_inclu_cck = ccx->fahm_inclu_cck; + enhance_mntr_rpt |= FAHM_SUCCESS; + + odm_move_memory(dm, &rpt->fahm_result[0], + &ccx->fahm_result[0], FAHM_RPT_NUM * 2); + } else { + rpt->fahm_pwr = 0; + rpt->fahm_ratio = 0; + rpt->fahm_denom_ratio = 0; + } + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "[FAHM]stamp=%d, IGI=0x%x, fahm_inclu_cck=%d, fahm_pwr=%d, fahm_ratio=%d, fahm_denom_ratio=%d\n", + rpt->fahm_rpt_stamp, ccx->fahm_igi, rpt->fahm_inclu_cck, + rpt->fahm_pwr, rpt->fahm_ratio, rpt->fahm_denom_ratio); + + /*Get IFS_CLM result*/ + phydm_ifs_clm_get_result(dm); + phydm_ifs_clm_get_utility(dm); + rpt->ifs_clm_tx_ratio = ccx->ifs_clm_tx_ratio; + rpt->ifs_clm_edcca_excl_cca_ratio = ccx->ifs_clm_edcca_excl_cca_ratio; + rpt->ifs_clm_cck_fa_ratio = ccx->ifs_clm_cck_fa_ratio; + rpt->ifs_clm_cck_cca_excl_fa_ratio = ccx->ifs_clm_cck_cca_excl_fa_ratio; + rpt->ifs_clm_ofdm_fa_ratio = ccx->ifs_clm_ofdm_fa_ratio; + rpt->ifs_clm_ofdm_cca_excl_fa_ratio = ccx->ifs_clm_ofdm_cca_excl_fa_ratio; + rpt->ifs_clm_rpt_stamp = ccx->ifs_clm_rpt_stamp; + enhance_mntr_rpt |= IFS_CLM_SUCCESS; + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "[IFS_CLM]rpt_stamp = %d, Tx_ratio = %d, EDCCA_exclude_CCA_ratio = %d\n", + ccx->ifs_clm_rpt_stamp, ccx->ifs_clm_tx_ratio, + ccx->ifs_clm_edcca_excl_cca_ratio); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "CCK : FA_ratio = %d, CCA_exclude_FA_ratio = %d\n", + ccx->ifs_clm_cck_fa_ratio, ccx->ifs_clm_cck_cca_excl_fa_ratio); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "OFDM : FA_ratio = %d, CCA_exclude_FA_ratio = %d\n", + ccx->ifs_clm_ofdm_fa_ratio, + ccx->ifs_clm_ofdm_cca_excl_fa_ratio); + + rpt->nhm_rpt_stamp = ccx->nhm_rpt_stamp; + rpt->clm_rpt_stamp = ccx->clm_rpt_stamp; + rpt->fahm_rpt_stamp = ccx->fahm_rpt_stamp; + rpt->ifs_clm_rpt_stamp = ccx->ifs_clm_rpt_stamp; +#endif + return enhance_mntr_rpt; +} + +void phydm_enhance_mntr_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ +#if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT) && defined(FAHM_SUPPORT) && defined(IFS_CLM_SUPPORT)) + struct dm_struct *dm = (struct dm_struct *)dm_void; + char help[] = "-h"; + u32 var1[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + struct nhm_para_info nhm_para = {0}; + struct clm_para_info clm_para = {0}; + struct fahm_para_info fahm_para = {0}; + struct ifs_clm_para_info ifs_clm_para = {0}; + struct enhance_mntr_rpt rpt = {0}; + struct enhance_mntr_trig_rpt trig_rpt = {0}; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 set_result = 0; + u8 i = 0; + + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM) || + !(dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM)) + return; + + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "Basic-Trigger 960ms for ifs_clm, 262ms for others: {1}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Get Result: {100}\n"); + } else if (var1[0] == 100) { /* Get results */ + set_result = phydm_enhance_mntr_result(dm, &rpt); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "Set Result=%d, rpt_stamp{NHM, CLM, FAHM, IFS_CLM}={%d, %d, %d, %d}\n", + set_result, rpt.nhm_rpt_stamp, rpt.clm_rpt_stamp, + rpt.fahm_rpt_stamp, rpt.ifs_clm_rpt_stamp); + PDM_SNPF(out_len, used, output + used, out_len - used, + "clm_ratio=%d\n", rpt.clm_ratio); + + for (i = 0; i < NHM_RPT_NUM; i++) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "nhm_rpt[%d] = %d (%d percent)\n", i, + rpt.nhm_result[i], + (((rpt.nhm_result[i] * 100) + 128) >> 8)); + } + + PDM_SNPF(out_len, used, output + used, out_len - used, + "nhm_IGI=0x%x, nhm_ratio=%d, nhm_env_ratio=%d, nhm_noise_pwr=%d, nhm_pwr=%d\n", + ccx->nhm_igi, rpt.nhm_ratio, rpt.nhm_env_ratio, + rpt.nhm_noise_pwr, rpt.nhm_pwr); + + if (!(rpt.fahm_inclu_cck)) + PDM_SNPF(out_len, used, output + used, + out_len - used, + "===>The following fahm report does not count CCK pkt\n"); + + for (i = 0; i < FAHM_RPT_NUM; i++) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "fahm_rpt[%d] = %d (%d percent)\n", i, + rpt.fahm_result[i], + (((rpt.fahm_result[i] * 100) + 32768) >> 16)); + } + + PDM_SNPF(out_len, used, output + used, out_len - used, + "fahm_IGI=0x%x, fahm_pwr=%d, fahm_ratio=%d, fahm_denom_ratio=%d\n", + ccx->fahm_igi, rpt.fahm_pwr, rpt.fahm_ratio, + rpt.fahm_denom_ratio); + PDM_SNPF(out_len, used, output + used, out_len - used, + "ifs_clm_Tx_ratio = %d, ifs_clm_EDCCA_exclude_CCA_ratio = %d \n", + rpt.ifs_clm_tx_ratio, + rpt.ifs_clm_edcca_excl_cca_ratio); + PDM_SNPF(out_len, used, output + used, out_len - used, + "ifs_clm_cck_fa_ratio = %d, ifs_clm_cck_cca_exclude_FA_ratio = %d \n", + rpt.ifs_clm_cck_fa_ratio, + rpt.ifs_clm_cck_cca_excl_fa_ratio); + PDM_SNPF(out_len, used, output + used, out_len - used, + "ifs_clm_ofdm_fa_ratio = %d, ifs_clm_ofdm_cca_exclude_FA_ratio = %d \n", + rpt.ifs_clm_ofdm_fa_ratio, + rpt.ifs_clm_ofdm_cca_excl_fa_ratio); + } else { /* Set & trigger*/ + /*nhm para*/ + nhm_para.incld_txon = NHM_EXCLUDE_TXON; + nhm_para.incld_cca = NHM_EXCLUDE_CCA; + nhm_para.div_opt = NHM_CNT_ALL; + nhm_para.nhm_app = NHM_ACS; + nhm_para.nhm_lv = NHM_LV_2; + nhm_para.mntr_time = 262; + nhm_para.en_1db_mode = false; + + /*clm para*/ + clm_para.clm_app = CLM_ACS; + clm_para.clm_lv = CLM_LV_2; + clm_para.mntr_time = 262; + + /*fahm para*/ + fahm_para.numer_opt = FAHM_INCLU_FA; + fahm_para.denom_opt = FAHM_INCLU_CRC_ERR; + fahm_para.app = FAHM_ACS; + fahm_para.lv = FAHM_LV_2; + fahm_para.mntr_time = 262; + fahm_para.en_1db_mode = false; + + ifs_clm_para.ifs_clm_app = IFS_CLM_ACS; + ifs_clm_para.ifs_clm_lv = IFS_CLM_LV_2; + ifs_clm_para.mntr_time = 960; + ifs_clm_para.th_shift = 0; + + set_result = phydm_enhance_mntr_trigger(dm, &nhm_para, + &clm_para, &fahm_para, + &ifs_clm_para, + &trig_rpt); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "Set Result=%d, rpt_stamp{NHM, CLM, FAHM, IFS_CLM}={%d, %d ,%d, %d}\n", + set_result, trig_rpt.nhm_rpt_stamp, + trig_rpt.clm_rpt_stamp, trig_rpt.fahm_rpt_stamp, + trig_rpt.ifs_clm_rpt_stamp); + } + *_used = used; + *_out_len = out_len; +#endif +} + +/*Environment Monitor*/ +void phydm_env_mntr_result_watchdog(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + + ccx->ccx_watchdog_result = 0; + + if (!(dm->support_ability & ODM_BB_ENV_MONITOR)) + return; + + #if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT)) + if (phydm_nhm_mntr_result(dm)) + ccx->ccx_watchdog_result |= NHM_SUCCESS; + + if (phydm_clm_mntr_result(dm)) + ccx->ccx_watchdog_result |= CLM_SUCCESS; + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "Summary: nhm_ratio=((%d)) clm_ratio=((%d))\n\n", + ccx->nhm_ratio, ccx->clm_ratio); + #endif + + #ifdef FAHM_SUPPORT + if (dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM) { + if (phydm_fahm_mntr_result(dm)) + ccx->ccx_watchdog_result |= FAHM_SUCCESS; + } + #endif + + #ifdef IFS_CLM_SUPPORT + if (dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM) { + if (phydm_ifs_clm_mntr_result(dm)) + ccx->ccx_watchdog_result |= IFS_CLM_SUCCESS; + } + #endif +} + +void phydm_env_mntr_set_watchdog(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + + if (!(dm->support_ability & ODM_BB_ENV_MONITOR)) + return; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + #if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT)) + if (phydm_nhm_mntr_chk(dm, 262)) + phydm_nhm_trigger(dm); + + if (phydm_clm_mntr_chk(dm, 262)) + phydm_clm_trigger(dm); + #endif + + #ifdef FAHM_SUPPORT + if (dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM) { + if (phydm_fahm_mntr_chk(dm, 262)) + phydm_fahm_trigger(dm); + } + #endif + + #ifdef IFS_CLM_SUPPORT + if (dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM) { + if (phydm_ifs_clm_mntr_chk(dm, 960)) + phydm_ifs_clm_trigger(dm); + } + #endif +} + +void phydm_env_monitor_init(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + #if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT)) + phydm_ccx_hw_restart(dm); + phydm_nhm_init(dm); + phydm_clm_init(dm); + #endif + + #ifdef FAHM_SUPPORT + phydm_fahm_init(dm); + #endif + + #ifdef IFS_CLM_SUPPORT + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM)) + return; + + phydm_ifs_clm_restart(dm); + phydm_ifs_clm_init(dm); + #endif +} + diff --git a/hal/phydm/phydm_ccx.h b/hal/phydm/phydm_ccx.h index d0edf3d..95ec6fa 100644 --- a/hal/phydm/phydm_ccx.h +++ b/hal/phydm/phydm_ccx.h @@ -26,8 +26,8 @@ #ifndef __PHYDMCCX_H__ #define __PHYDMCCX_H__ -/* 2019.03.27 add noise_pwr in env_mntr_rpt.*/ -#define CCX_VERSION "2.4" +/* 2020.08.12 split env_mntr api into set_env_mntr and result_env_mntr api for dig_fa_source*/ +#define CCX_VERSION "4.7" /* @1 ============================================================ * 1 Definition @@ -36,39 +36,38 @@ #define CCX_EN 1 #define MAX_ENV_MNTR_TIME 8 /*second*/ -#define IGI_TO_NHM_TH_MULTIPLIER 2 +#define MS_TO_US 1000 #define MS_TO_4US_RATIO 250 #define CCA_CAP 14 +/*CLM*/ #define CLM_MAX_REPORT_TIME 10 -#define DEVIDER_ERROR 0xffff -#define CLM_PERIOD_MAX 65535 -#define NHM_PERIOD_MAX 65534 +#define CLM_PERIOD_MAX 65535 +/*NHM*/ +#define NHM_PERIOD_MAX 65534 #define NHM_TH_NUM 11 /*threshold number of NHM*/ #define NHM_RPT_NUM 12 +#define NHM_IC_NOISE_TH 60 /*60/2 - 10 = 20 = -80 dBm*/ +#define NHM_RPT_MAX 255 #ifdef NHM_DYM_PW_TH_SUPPORT #define DYM_PWTH_CCA_CAP 24 -#define NHM_1PEAK_PS 1 /* @case1 : positive skew*/ -#define NHM_1PEAK_NS 2 /* @case2 : negative skew*/ -#define NHM_1PEAK_SYM 3 /* @case3 : symmetry*/ -#define NHM_TH1 33 /* @13%, for step2 decision*/ -#define NHM_TH2 35 /* @14%, for step3_c1_c2 decision*/ -#define NHM_TH3 31 /* @12%, for step3_c3 decision*/ -#define NHM_TH4 178 /* @70%, for step4 decision*/ -#define NHM_TH5 25 /* @10%, for step5_c1_c2 decision*/ -#define NHM_TH6 39 /* @15%, for step5_c3 decision*/ #endif - -#define IGI_2_NHM_TH(igi) ((igi) << 1)/*NHM_threshold = IGI * 2*/ +#define IGI_2_NHM_TH(igi) ((igi) << 1)/*NHM/FAHM threshold = IGI * 2*/ #define NTH_TH_2_RSSI(th) ((th >> 1) - 10) - -/*@FAHM*/ -#define FAHM_INCLD_FA BIT(0) -#define FAHM_INCLD_CRC_OK BIT(1) -#define FAHM_INCLD_CRC_ER BIT(2) +/*FAHM*/ +#define FAHM_INCLU_FA BIT(0) +#define FAHM_INCLU_CRC_OK BIT(1) +#define FAHM_INCLU_CRC_ERR BIT(2) +#define FAHM_PERIOD_MAX 65534 +#define FAHM_TH_NUM 11 /*threshold number of FAHM*/ +#define FAHM_RPT_NUM 12 +/*IFS-CLM*/ +#define IFS_CLM_PERIOD_MAX 65535 +#define IFS_CLM_NUM 4 #define NHM_SUCCESS BIT(0) #define CLM_SUCCESS BIT(1) #define FAHM_SUCCESS BIT(2) +#define IFS_CLM_SUCCESS BIT(3) #define ENV_MNTR_FAIL 0xff /* @1 ============================================================ @@ -93,6 +92,24 @@ enum phydm_nhm_level { NHM_MAX_NUM = 5 }; +enum phydm_fahm_level { + FAHM_RELEASE = 0, + FAHM_LV_1 = 1, /* Low Priority function */ + FAHM_LV_2 = 2, /* Middle Priority function */ + FAHM_LV_3 = 3, /* High priority function (ex: Check hang function) */ + FAHM_LV_4 = 4, /* Debug function (the highest priority) */ + FAHM_MAX_NUM = 5 +}; + +enum phydm_ifs_clm_level { + IFS_CLM_RELEASE = 0, + IFS_CLM_LV_1 = 1, /* @Low Priority function */ + IFS_CLM_LV_2 = 2, /* @Middle Priority function */ + IFS_CLM_LV_3 = 3, /* @High priority function (ex: Check hang function) */ + IFS_CLM_LV_4 = 4, /* @Debug function (the highest priority) */ + IFS_CLM_MAX_NUM = 5 +}; + enum nhm_divider_opt_all { NHM_CNT_ALL = 0, /*nhm SUM report <= 255*/ NHM_VALID = 1, /*nhm SUM report = 255*/ @@ -131,11 +148,32 @@ enum clm_application { CLM_ACS = 1, }; +enum fahm_application { + FAHM_BACKGROUND = 0,/*default*/ + FAHM_ACS = 1, + FAHM_DBG = 2, /*manual trigger*/ +}; + +enum ifs_clm_application { + IFS_CLM_BACKGROUND = 0,/*default*/ + IFS_CLM_ACS = 1, + IFS_CLM_HP_TAS = 2, + IFS_CLM_DBG = 3, +}; + enum clm_monitor_mode { CLM_DRIVER_MNTR = 1, CLM_FW_MNTR = 2 }; +enum phydm_ifs_clm_unit { + IFS_CLM_4 = 0, /*4us*/ + IFS_CLM_8 = 1, /*8us*/ + IFS_CLM_12 = 2, /*12us*/ + IFS_CLM_16 = 3, /*16us*/ + IFS_CLM_INIT +}; + /* @1 ============================================================ * 1 structure * 1 ============================================================ @@ -145,14 +183,46 @@ struct env_trig_rpt { u8 clm_rpt_stamp; }; - struct env_mntr_rpt { u8 nhm_ratio; + u8 nhm_env_ratio; /*exclude nhm_r[0] above -80dBm or first cluster under -80dBm*/ u8 nhm_result[NHM_RPT_NUM]; u8 clm_ratio; u8 nhm_rpt_stamp; u8 clm_rpt_stamp; - u8 nhm_noise_pwr; + u8 nhm_noise_pwr; /*including r[0]~r[10]*/ + u8 nhm_pwr; /*including r[0]~r[11]*/ +}; + +struct enhance_mntr_trig_rpt { + u8 nhm_rpt_stamp; + u8 clm_rpt_stamp; + u8 fahm_rpt_stamp; + u8 ifs_clm_rpt_stamp; +}; + +struct enhance_mntr_rpt { + u8 nhm_ratio; + u8 nhm_env_ratio; /*exclude nhm_r[0] above -80dBm or first cluster under -80dBm*/ + u8 nhm_result[NHM_RPT_NUM]; + u8 clm_ratio; + u8 nhm_rpt_stamp; + u8 clm_rpt_stamp; + u8 nhm_noise_pwr; /*including r[0]~r[10]*/ + u8 nhm_pwr; /*including r[0]~r[11]*/ + u16 fahm_result[NHM_RPT_NUM]; + u8 fahm_rpt_stamp; + u8 fahm_pwr; + u8 fahm_ratio; + u8 fahm_denom_ratio; + u8 fahm_inclu_cck; + u8 ifs_clm_rpt_stamp; + u8 ifs_clm_tx_ratio; + u8 ifs_clm_edcca_excl_cca_ratio; + u8 ifs_clm_cck_fa_ratio; + u8 ifs_clm_cck_cca_excl_fa_ratio; + u8 ifs_clm_ofdm_fa_ratio; + u8 ifs_clm_ofdm_cca_excl_fa_ratio; }; struct nhm_para_info { @@ -162,6 +232,8 @@ struct nhm_para_info { enum nhm_application nhm_app; enum phydm_nhm_level nhm_lv; u16 mntr_time; /*@0~262 unit ms*/ + boolean en_1db_mode; + u8 nhm_th0_manual; /* for 1-db mode*/ }; struct clm_para_info { @@ -170,10 +242,34 @@ struct clm_para_info { u16 mntr_time; /*@0~262 unit ms*/ }; +struct fahm_para_info { + enum fahm_application app; + enum phydm_fahm_level lv; + u16 mntr_time; /*0~262 unit ms*/ + u8 numer_opt; + u8 denom_opt; + boolean en_1db_mode; + u8 th0_manual;/* for 1-db mode*/ +}; + +struct ifs_clm_para_info { + enum ifs_clm_application ifs_clm_app; + enum phydm_ifs_clm_level ifs_clm_lv; + enum phydm_ifs_clm_unit ifs_clm_ctrl_unit; /*unit*/ + u16 mntr_time; /*ms*/ + boolean ifs_clm_th_en[IFS_CLM_NUM]; + u16 ifs_clm_th_low[IFS_CLM_NUM]; + u16 ifs_clm_th_high[IFS_CLM_NUM]; + s16 th_shift; +}; + struct ccx_info { u32 nhm_trigger_time; u32 clm_trigger_time; + u32 fahm_trigger_time; + u32 ifs_clm_trigger_time; u64 start_time; /*@monitor for the test duration*/ + u8 ccx_watchdog_result; #ifdef NHM_SUPPORT enum nhm_application nhm_app; enum nhm_option_txon_all nhm_include_txon; @@ -182,22 +278,24 @@ struct ccx_info { /*Report*/ u8 nhm_th[NHM_TH_NUM]; u8 nhm_result[NHM_RPT_NUM]; + u8 nhm_wgt[NHM_RPT_NUM]; u16 nhm_period; /* @4us per unit */ u8 nhm_igi; u8 nhm_manual_ctrl; u8 nhm_ratio; /*@1% per nuit, it means the interference igi can't overcome.*/ + u8 nhm_env_ratio; /*exclude nhm_r[0] above -80dBm or first cluster under -80dBm*/ u8 nhm_rpt_sum; - u16 nhm_duration; /*@Real time of NHM_VALID */ u8 nhm_set_lv; boolean nhm_ongoing; u8 nhm_rpt_stamp; - u8 nhm_noise_pwr; - u8 nhm_noise_pwr_point; + u8 nhm_level; /*including r[0]~r[10]*/ + u8 nhm_level_valid; + u8 nhm_pwr; /*including r[0]~r[11]*/ #ifdef NHM_DYM_PW_TH_SUPPORT boolean nhm_dym_pw_th_en; - boolean nhm_dym_1_peak_en; boolean dym_pwth_manual_ctrl; - u8 nhm_pw_th_rf20_dft; + u8 pw_th_rf20_ori; + u8 pw_th_rf20_cur; u8 nhm_pw_th_max; u8 nhm_period_decre; u8 nhm_sl_pw_th; @@ -218,11 +316,54 @@ struct ccx_info { u8 clm_rpt_stamp; #endif #ifdef FAHM_SUPPORT + enum fahm_application fahm_app; boolean fahm_ongoing; - u8 env_mntr_igi; - u8 fahm_nume_sel; /*@fahm_numerator_sel: select {FA, CRCOK, CRC_fail} */ - u8 fahm_denom_sel; /*@fahm_denominator_sel: select {FA, CRCOK, CRC_fail} */ + u8 fahm_numer_opt; + u8 fahm_denom_opt; + boolean fahm_inclu_cck; + u8 fahm_th[NHM_TH_NUM]; + u16 fahm_result[NHM_RPT_NUM]; + u16 fahm_result_sum; + u16 fahm_denom_result; u16 fahm_period; /*unit: 4us*/ + u8 fahm_igi; + u8 fahm_manual_ctrl; + u8 fahm_set_lv; + u8 fahm_rpt_stamp; + u8 fahm_pwr; /*including r[0]~r[11]*/ + u8 fahm_ratio; + u8 fahm_denom_ratio; +#endif +#ifdef IFS_CLM_SUPPORT + enum ifs_clm_application ifs_clm_app; + /*Control*/ + enum phydm_ifs_clm_unit ifs_clm_ctrl_unit; /*4,8,12,16us per unit*/ + u16 ifs_clm_period; + boolean ifs_clm_th_en[IFS_CLM_NUM]; + u16 ifs_clm_th_low[IFS_CLM_NUM]; + u16 ifs_clm_th_high[IFS_CLM_NUM]; + /*Flow control*/ + u8 ifs_clm_set_lv; + u8 ifs_clm_manual_ctrl; + boolean ifs_clm_ongoing; + /*Report*/ + u8 ifs_clm_rpt_stamp; + u16 ifs_clm_tx; + u16 ifs_clm_edcca_excl_cca; + u16 ifs_clm_ofdmfa; + u16 ifs_clm_ofdmcca_excl_fa; + u16 ifs_clm_cckfa; + u16 ifs_clm_cckcca_excl_fa; + u8 ifs_clm_his[IFS_CLM_NUM]; /*trx_neg_edge to CCA/FA posedge per times*/ + u16 ifs_clm_total_cca; + u16 ifs_clm_avg[IFS_CLM_NUM]; /*4,8,12,16us per unit*/ + u16 ifs_clm_avg_cca[IFS_CLM_NUM]; /*4,8,12,16us per unit*/ + u8 ifs_clm_tx_ratio; + u8 ifs_clm_edcca_excl_cca_ratio; + u8 ifs_clm_cck_fa_ratio; + u8 ifs_clm_cck_cca_excl_fa_ratio; + u8 ifs_clm_ofdm_fa_ratio; + u8 ifs_clm_ofdm_cca_excl_fa_ratio; #endif }; @@ -231,6 +372,8 @@ struct ccx_info { * 1 ============================================================ */ +u8 phydm_env_mntr_get_802_11_k_rsni(void *dm_void, s8 rcpi, s8 anpi); + #ifdef FAHM_SUPPORT void phydm_fahm_init(void *dm_void); @@ -238,14 +381,12 @@ void phydm_fahm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len); #endif -/*@NHM*/ #ifdef NHM_SUPPORT void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len); u8 phydm_get_igi(void *dm_void, enum bb_path path); #endif -/*@CLM*/ #ifdef CLM_SUPPORT void phydm_clm_c2h_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len); @@ -259,10 +400,30 @@ u8 phydm_env_mntr_trigger(void *dm_void, struct nhm_para_info *nhm_para, u8 phydm_env_mntr_result(void *dm_void, struct env_mntr_rpt *rpt); -void phydm_env_mntr_watchdog(void *dm_void); +void phydm_env_mntr_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); + +#ifdef IFS_CLM_SUPPORT +void phydm_ifs_clm_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); +#endif + +u8 phydm_enhance_mntr_trigger(void *dm_void, + struct nhm_para_info *nhm_para, + struct clm_para_info *clm_para, + struct fahm_para_info *fahm_para, + struct ifs_clm_para_info *ifs_clm_para, + struct enhance_mntr_trig_rpt *trig_rpt); + +u8 phydm_enhance_mntr_result(void *dm_void, struct enhance_mntr_rpt *rpt); + +void phydm_enhance_mntr_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); + +void phydm_env_mntr_result_watchdog(void *dm_void); + +void phydm_env_mntr_set_watchdog(void *dm_void); void phydm_env_monitor_init(void *dm_void); -void phydm_env_mntr_dbg(void *dm_void, char input[][16], u32 *_used, - char *output, u32 *_out_len); #endif diff --git a/hal/phydm/phydm_cfotracking.c b/hal/phydm/phydm_cfotracking.c index fd34e1c..68731db 100644 --- a/hal/phydm/phydm_cfotracking.c +++ b/hal/phydm/phydm_cfotracking.c @@ -211,7 +211,7 @@ phydm_set_crystal_cap_reg(void *dm_void, u8 crystal_cap) u32 reg_val = 0; if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | - ODM_RTL8195B | ODM_RTL8812F | ODM_RTL8721D | ODM_RTL8710C)) { + ODM_RTL8195B | ODM_RTL8812F | ODM_RTL8721D | ODM_RTL8710C|ODM_RTL8723F)) { crystal_cap &= 0x7F; reg_val = crystal_cap | (crystal_cap << 7); } else { @@ -249,9 +249,9 @@ phydm_set_crystal_cap_reg(void *dm_void, u8 crystal_cap) } #endif #if (RTL8822B_SUPPORT || RTL8821C_SUPPORT || RTL8197F_SUPPORT ||\ - RTL8192F_SUPPORT || RTL8197G_SUPPORT) + RTL8192F_SUPPORT || RTL8197G_SUPPORT || RTL8198F_SUPPORT) else if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C | - ODM_RTL8197F | ODM_RTL8192F | ODM_RTL8197G)) { + ODM_RTL8197F | ODM_RTL8192F | ODM_RTL8197G | ODM_RTL8198F)) { /* write 0x24[30:25] = 0x28[6:1] = crystal_cap */ odm_set_mac_reg(dm, R_0x24, 0x7e000000, crystal_cap); odm_set_mac_reg(dm, R_0x28, 0x7e, crystal_cap); @@ -289,7 +289,12 @@ phydm_set_crystal_cap_reg(void *dm_void, u8 crystal_cap) phydm_set_crystalcap(dm, (u8)(reg_val & 0x7f)); } #endif - + #if (RTL8723F_SUPPORT) + else if (dm->support_ic_type & ODM_RTL8723F) { + /* write 0x103c[23:17] = 0x103c[16:10] = crystal_cap */ + odm_set_mac_reg(dm, R_0x103c, 0x00FFFC00, reg_val); + } + #endif #if (RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8812F_SUPPORT) else if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | ODM_RTL8812F)) { @@ -325,7 +330,7 @@ void phydm_cfo_tracking_reset(void *dm_void) PHYDM_DBG(dm, DBG_CFO_TRK, "%s ======>\n", __func__); if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | ODM_RTL8195B | - ODM_RTL8812F)) + ODM_RTL8812F | ODM_RTL8710C | ODM_RTL8721D | ODM_RTL8723F)) cfo_track->def_x_cap = cfo_track->crystal_cap_default & 0x7f; else cfo_track->def_x_cap = cfo_track->crystal_cap_default & 0x3f; @@ -349,6 +354,14 @@ void phydm_cfo_tracking_reset(void *dm_void) phydm_set_atc_status(dm, true); #endif #endif +#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE | ODM_AP)) + if (dm->support_ic_type & ODM_RTL8814B) { + /*Disable advance time for CFO residual*/ + odm_set_bb_reg(dm, R_0xc2c, BIT29, 0x0); + } +#endif +#endif } void phydm_cfo_tracking_init(void *dm_void) @@ -358,7 +371,7 @@ void phydm_cfo_tracking_init(void *dm_void) PHYDM_DBG(dm, DBG_CFO_TRK, "[%s]=========>\n", __func__); if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | ODM_RTL8195B | - ODM_RTL8812F)) + ODM_RTL8812F | ODM_RTL8710C | ODM_RTL8721D | ODM_RTL8723F)) cfo_track->crystal_cap = cfo_track->crystal_cap_default & 0x7f; else cfo_track->crystal_cap = cfo_track->crystal_cap_default & 0x3f; @@ -473,7 +486,7 @@ void phydm_cfo_tracking(void *dm_void) crystal_cap -= 1; if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | - ODM_RTL8195B | ODM_RTL8812F)) { + ODM_RTL8195B | ODM_RTL8812F | ODM_RTL8710C | ODM_RTL8721D | ODM_RTL8723F)) { if (crystal_cap > 0x7F) crystal_cap = 0x7F; } else { @@ -501,6 +514,14 @@ void phydm_cfo_tracking(void *dm_void) } #endif #endif + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE | ODM_AP)) + if (dm->support_ic_type & ODM_RTL8814B) { + //Disable advance time for CFO residual + odm_set_bb_reg(dm, R_0xc2c, BIT29, 0x0); + } + #endif + #endif } } diff --git a/hal/phydm/phydm_debug.c b/hal/phydm/phydm_debug.c index 82fe834..6d47868 100644 --- a/hal/phydm/phydm_debug.c +++ b/hal/phydm/phydm_debug.c @@ -141,7 +141,6 @@ u8 phydm_set_bb_dbg_port(void *dm_void, u8 curr_dbg_priority, u32 debug_port) odm_set_bb_reg(dm, R_0x8fc, MASKDWORD, debug_port); } else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { odm_set_bb_reg(dm, R_0x1c3c, 0xfff00, debug_port); - } else { /*@if (dm->support_ic_type & ODM_IC_11N_SERIES)*/ odm_set_bb_reg(dm, R_0x908, MASKDWORD, debug_port); } @@ -745,10 +744,15 @@ void phydm_bb_hw_dbg_info_jgr3(void *dm_void, u32 *_used, char *output, "\r\n %-35s %s", "mode", tmp_string); /*@ [RX counter Info] ===============================================*/ - PDM_SNPF(out_len, used, output + used, out_len - used, - "\r\n %-35s = %d", "CCK CCA cnt", - odm_get_bb_reg(dm, R_0x2c08, 0xFFFF)); - + if (dm->support_ic_type & ODM_RTL8723F) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "\r\n %-35s = %d", "CCK CCA cnt", + odm_get_bb_reg(dm, R_0x2aa0, 0xFFFF)); + } else { + PDM_SNPF(out_len, used, output + used, out_len - used, + "\r\n %-35s = %d", "CCK CCA cnt", + odm_get_bb_reg(dm, R_0x2c08, 0xFFFF)); + } PDM_SNPF(out_len, used, output + used, out_len - used, "\r\n %-35s = %d", "OFDM CCA cnt", odm_get_bb_reg(dm, R_0x2c08, 0xFFFF0000)); @@ -999,19 +1003,18 @@ void phydm_dm_summary_cli_win(void *dm_void, char *buf, u8 macid) return; } - RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, "00.(%s) %-12s: IGI=0x%x, Dyn_Rng=0x%x~0x%x, FA_th={%d,%d,%d}\n", + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, "00.(%s) %-12s: IGI=0x%x, Dyn_Rng=0x%x~0x%x, fa_src=%d, FA_th={%d,%d,%d}\n", ((comp & ODM_BB_DIG) ? ((pause_comp & ODM_BB_DIG) ? "P" : "V") : "."), "DIG", dig_t->cur_ig_value, dig_t->rx_gain_range_min, dig_t->rx_gain_range_max, + dig_t->fa_source, dig_t->fa_th[0], dig_t->fa_th[1], dig_t->fa_th[2]); RT_PRINT(buf); sta = dm->phydm_sta_info[macid]; if (is_sta_active(sta)) { - RT_PRINT(buf); - ra = &sta->ra_info; dtp = &sta->dtp_stat; @@ -1084,11 +1087,13 @@ void phydm_dm_summary_cli_win(void *dm_void, char *buf, u8 macid) DIFF_2(cfo_t->crystal_cap, cfo_t->def_x_cap)); RT_PRINT(buf); - RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, "15.(%s) %-12s: ratio{nhm, clm}={%d, %d}\n", + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, + "15.(%s) %-12s: ratio{nhm, clm}={%d, %d}, level{valid, RSSI}={%d, %d}\n", ((comp & ODM_BB_ENV_MONITOR) ? ((pause_comp & ODM_BB_ENV_MONITOR) ? "P" : "V") : "."), "EnvMntr", - dm->dm_ccx_info.nhm_ratio, dm->dm_ccx_info.clm_ratio); + dm->dm_ccx_info.nhm_ratio, dm->dm_ccx_info.clm_ratio, + dm->dm_ccx_info.nhm_level_valid, dm->dm_ccx_info.nhm_level); RT_PRINT(buf); #ifdef PHYDM_PRIMARY_CCA RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, "16.(%s) %-12s: CCA @ (%s SB)\n", @@ -1122,9 +1127,10 @@ void phydm_basic_dbg_msg_cli_win(void *dm_void, char *buf) struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_fa_struct *fa_t = &dm->false_alm_cnt; struct phydm_cfo_track_struct *cfo_t = &dm->dm_cfo_track; - struct odm_phy_dbg_info *dbg = &dm->phy_dbg_info; + struct odm_phy_dbg_info *dbg = &dm->phy_dbg_info_win_bkp; struct phydm_phystatus_statistic *dbg_s = &dbg->physts_statistic_info; struct phydm_phystatus_avg *dbg_avg = &dbg->phystatus_statistic_avg; + char *rate_type = NULL; u8 tmp_rssi_avg[4]; u8 tmp_snr_avg[4]; @@ -1137,8 +1143,6 @@ void phydm_basic_dbg_msg_cli_win(void *dm_void, char *buf) struct cmn_sta_info *entry = NULL; char dbg_buf[PHYDM_SNPRINT_SIZE] = {0}; - if (dm->debug_components & DBG_CMN) - return; RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, "\r\n PHYDM Common Dbg Msg --------->"); RT_PRINT(buf); @@ -1280,15 +1284,12 @@ void phydm_basic_dbg_msg_cli_win(void *dm_void, char *buf) } #endif - phydm_reset_rx_rate_distribution(dm); - //1 Show phydm_avg_phystatus_val RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, "\r\n [Avg PHY Statistic] ==============>\n"); RT_PRINT(buf); -#if 1 - phydm_get_avg_phystatus_val(dm); + /*===[Beacon]===*/ switch (dm->num_rf_path) { #if (defined(PHYDM_COMPILE_ABOVE_4SS)) case 4: @@ -1329,6 +1330,7 @@ void phydm_basic_dbg_msg_cli_win(void *dm_void, char *buf) } RT_PRINT(buf); + /*===[CCK]===*/ switch (dm->num_rf_path) { #ifdef PHYSTS_3RD_TYPE_SUPPORT #if (defined(PHYDM_COMPILE_ABOVE_4SS)) @@ -1428,118 +1430,6 @@ void phydm_basic_dbg_msg_cli_win(void *dm_void, char *buf) tmp_evm_avg[0], tmp_evm_avg[1], tmp_evm_avg[2], tmp_evm_avg[3]); RT_PRINT(buf); } -#else - phydm_reset_phystatus_avg(dm); - - /*@CCK*/ - dbg_avg->rssi_cck_avg = (u8)((dbg_s->rssi_cck_cnt != 0) ? (dbg_s->rssi_cck_sum / dbg_s->rssi_cck_cnt) : 0); - RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, "\r\n * cck Cnt= ((%d)) RSSI:{%d}", - dbg_s->rssi_cck_cnt, dbg_avg->rssi_cck_avg); - RT_PRINT(buf); - - /*OFDM*/ - if (dbg_s->rssi_ofdm_cnt != 0) { - dbg_avg->rssi_ofdm_avg = (u8)(dbg_s->rssi_ofdm_sum / dbg_s->rssi_ofdm_cnt); - dbg_avg->evm_ofdm_avg = (u8)(dbg_s->evm_ofdm_sum / dbg_s->rssi_ofdm_cnt); - dbg_avg->snr_ofdm_avg = (u8)(dbg_s->snr_ofdm_sum / dbg_s->rssi_ofdm_cnt); - } - - RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, "\r\n * ofdm Cnt= ((%d)) RSSI:{%d} EVM:{%d} SNR:{%d}", - dbg_s->rssi_ofdm_cnt, dbg_avg->rssi_ofdm_avg, - dbg_avg->evm_ofdm_avg, dbg_avg->snr_ofdm_avg); - RT_PRINT(buf); - - if (dbg_s->rssi_1ss_cnt != 0) { - dbg_avg->rssi_1ss_avg = (u8)(dbg_s->rssi_1ss_sum / dbg_s->rssi_1ss_cnt); - dbg_avg->evm_1ss_avg = (u8)(dbg_s->evm_1ss_sum / dbg_s->rssi_1ss_cnt); - dbg_avg->snr_1ss_avg = (u8)(dbg_s->snr_1ss_sum / dbg_s->rssi_1ss_cnt); - } - - RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, "\r\n * 1-ss Cnt= ((%d)) RSSI:{%d} EVM:{%d} SNR:{%d}", - dbg_s->rssi_1ss_cnt, dbg_avg->rssi_1ss_avg, - dbg_avg->evm_1ss_avg, dbg_avg->snr_1ss_avg); - RT_PRINT(buf); - -#if (defined(PHYDM_COMPILE_ABOVE_2SS)) - if (dm->support_ic_type & (PHYDM_IC_ABOVE_2SS)) { - if (dbg_s->rssi_2ss_cnt != 0) { - dbg_avg->rssi_2ss_avg[0] = (u8)(dbg_s->rssi_2ss_sum[0] / dbg_s->rssi_2ss_cnt); - dbg_avg->rssi_2ss_avg[1] = (u8)(dbg_s->rssi_2ss_sum[1] / dbg_s->rssi_2ss_cnt); - - dbg_avg->evm_2ss_avg[0] = (u8)(dbg_s->evm_2ss_sum[0] / dbg_s->rssi_2ss_cnt); - dbg_avg->evm_2ss_avg[1] = (u8)(dbg_s->evm_2ss_sum[1] / dbg_s->rssi_2ss_cnt); - - dbg_avg->snr_2ss_avg[0] = (u8)(dbg_s->snr_2ss_sum[0] / dbg_s->rssi_2ss_cnt); - dbg_avg->snr_2ss_avg[1] = (u8)(dbg_s->snr_2ss_sum[1] / dbg_s->rssi_2ss_cnt); - } - - RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, "\r\n * 2-ss Cnt= ((%d)) RSSI:{%d, %d}, EVM:{%d, %d}, SNR:{%d, %d}", - dbg_s->rssi_2ss_cnt, dbg_avg->rssi_2ss_avg[0], - dbg_avg->rssi_2ss_avg[1], dbg_avg->evm_2ss_avg[0], - dbg_avg->evm_2ss_avg[1], dbg_avg->snr_2ss_avg[0], - dbg_avg->snr_2ss_avg[1]); - RT_PRINT(buf); - } -#endif - -#if (defined(PHYDM_COMPILE_ABOVE_3SS)) - if (dm->support_ic_type & (PHYDM_IC_ABOVE_3SS)) { - if (dbg_s->rssi_3ss_cnt != 0) { - dbg_avg->rssi_3ss_avg[0] = (u8)(dbg_s->rssi_3ss_sum[0] / dbg_s->rssi_3ss_cnt); - dbg_avg->rssi_3ss_avg[1] = (u8)(dbg_s->rssi_3ss_sum[1] / dbg_s->rssi_3ss_cnt); - dbg_avg->rssi_3ss_avg[2] = (u8)(dbg_s->rssi_3ss_sum[2] / dbg_s->rssi_3ss_cnt); - - dbg_avg->evm_3ss_avg[0] = (u8)(dbg_s->evm_3ss_sum[0] / dbg_s->rssi_3ss_cnt); - dbg_avg->evm_3ss_avg[1] = (u8)(dbg_s->evm_3ss_sum[1] / dbg_s->rssi_3ss_cnt); - dbg_avg->evm_3ss_avg[2] = (u8)(dbg_s->evm_3ss_sum[2] / dbg_s->rssi_3ss_cnt); - - dbg_avg->snr_3ss_avg[0] = (u8)(dbg_s->snr_3ss_sum[0] / dbg_s->rssi_3ss_cnt); - dbg_avg->snr_3ss_avg[1] = (u8)(dbg_s->snr_3ss_sum[1] / dbg_s->rssi_3ss_cnt); - dbg_avg->snr_3ss_avg[2] = (u8)(dbg_s->snr_3ss_sum[2] / dbg_s->rssi_3ss_cnt); - } - - RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, "\r\n * 3-ss Cnt= ((%d)) RSSI:{%d, %d, %d} EVM:{%d, %d, %d} SNR:{%d, %d, %d}", - dbg_s->rssi_3ss_cnt, dbg_avg->rssi_3ss_avg[0], - dbg_avg->rssi_3ss_avg[1], dbg_avg->rssi_3ss_avg[2], - dbg_avg->evm_3ss_avg[0], dbg_avg->evm_3ss_avg[1], - dbg_avg->evm_3ss_avg[2], dbg_avg->snr_3ss_avg[0], - dbg_avg->snr_3ss_avg[1], dbg_avg->snr_3ss_avg[2]); - RT_PRINT(buf); - } -#endif - -#if (defined(PHYDM_COMPILE_ABOVE_4SS)) - if (dm->support_ic_type & PHYDM_IC_ABOVE_4SS) { - if (dbg_s->rssi_4ss_cnt != 0) { - dbg_avg->rssi_4ss_avg[0] = (u8)(dbg_s->rssi_4ss_sum[0] / dbg_s->rssi_4ss_cnt); - dbg_avg->rssi_4ss_avg[1] = (u8)(dbg_s->rssi_4ss_sum[1] / dbg_s->rssi_4ss_cnt); - dbg_avg->rssi_4ss_avg[2] = (u8)(dbg_s->rssi_4ss_sum[2] / dbg_s->rssi_4ss_cnt); - dbg_avg->rssi_4ss_avg[3] = (u8)(dbg_s->rssi_4ss_sum[3] / dbg_s->rssi_4ss_cnt); - - dbg_avg->evm_4ss_avg[0] = (u8)(dbg_s->evm_4ss_sum[0] / dbg_s->rssi_4ss_cnt); - dbg_avg->evm_4ss_avg[1] = (u8)(dbg_s->evm_4ss_sum[1] / dbg_s->rssi_4ss_cnt); - dbg_avg->evm_4ss_avg[2] = (u8)(dbg_s->evm_4ss_sum[2] / dbg_s->rssi_4ss_cnt); - dbg_avg->evm_4ss_avg[3] = (u8)(dbg_s->evm_4ss_sum[3] / dbg_s->rssi_4ss_cnt); - - dbg_avg->snr_4ss_avg[0] = (u8)(dbg_s->snr_4ss_sum[0] / dbg_s->rssi_4ss_cnt); - dbg_avg->snr_4ss_avg[1] = (u8)(dbg_s->snr_4ss_sum[1] / dbg_s->rssi_4ss_cnt); - dbg_avg->snr_4ss_avg[2] = (u8)(dbg_s->snr_4ss_sum[2] / dbg_s->rssi_4ss_cnt); - dbg_avg->snr_4ss_avg[3] = (u8)(dbg_s->snr_4ss_sum[3] / dbg_s->rssi_4ss_cnt); - } - - RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, "\r\n * 4-ss Cnt= ((%d)) RSSI:{%d, %d, %d, %d} EVM:{%d, %d, %d, %d} SNR:{%d, %d, %d, %d}", - dbg_s->rssi_4ss_cnt, dbg_avg->rssi_4ss_avg[0], - dbg_avg->rssi_4ss_avg[1], dbg_avg->rssi_4ss_avg[2], - dbg_avg->rssi_4ss_avg[3], dbg_avg->evm_4ss_avg[0], - dbg_avg->evm_4ss_avg[1], dbg_avg->evm_4ss_avg[2], - dbg_avg->evm_4ss_avg[3], dbg_avg->snr_4ss_avg[0], - dbg_avg->snr_4ss_avg[1], dbg_avg->snr_4ss_avg[2], - dbg_avg->snr_4ss_avg[3]); - RT_PRINT(buf); - } -#endif -#endif - phydm_reset_phystatus_statistic(dm); /*@----------------------------------------------------------*/ /*Print TX rate*/ @@ -1591,6 +1481,12 @@ void phydm_basic_dbg_msg_cli_win(void *dm_void, char *buf) RT_PRINT(buf); } + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, + "\r\n [Tx cnt] {CCK_TxEN, CCK_TxON, OFDM_TxEN, OFDM_TxON} = {%d, %d, %d, %d}", + fa_t->cnt_cck_txen, fa_t->cnt_cck_txon, fa_t->cnt_ofdm_txen, + fa_t->cnt_ofdm_txon); + RT_PRINT(buf); + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, "\r\n [CCA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}", fa_t->cnt_cck_cca, fa_t->cnt_ofdm_cca, fa_t->cnt_cca_all); RT_PRINT(buf); @@ -1599,20 +1495,91 @@ void phydm_basic_dbg_msg_cli_win(void *dm_void, char *buf) fa_t->cnt_cck_fail, fa_t->cnt_ofdm_fail, fa_t->cnt_all); RT_PRINT(buf); - #if (ODM_IC_11N_SERIES_SUPPORT) - if (dm->support_ic_type & ODM_IC_11N_SERIES) { + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, + "\r\n [FA duration(us)] {exp, ifs_clm, fahm} = {%d, %d, %d}", + fa_t->time_fa_exp, fa_t->time_fa_ifs_clm, + fa_t->time_fa_fahm); + RT_PRINT(buf); + + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, + "\r\n [OFDM FA] Parity=%d, Rate=%d, Fast_Fsync=%d, SBD=%d", + fa_t->cnt_parity_fail, fa_t->cnt_rate_illegal, + fa_t->cnt_fast_fsync, fa_t->cnt_sb_search_fail); + RT_PRINT(buf); + + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, "\r\n [HT FA] CRC8=%d, MCS=%d", + fa_t->cnt_crc8_fail, fa_t->cnt_mcs_fail); + RT_PRINT(buf); + +#if (ODM_IC_11AC_SERIES_SUPPORT || defined(PHYDM_IC_JGR3_SERIES_SUPPORT)) + if (dm->support_ic_type & (ODM_IC_11AC_SERIES | ODM_IC_JGR3_SERIES)) { RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, - "\r\n [OFDM FA Detail] Parity_Fail=%d, Rate_Illegal=%d, CRC8=%d, MCS_fail=%d, Fast_sync=%d, SB_Search_fail=%d", - fa_t->cnt_parity_fail, fa_t->cnt_rate_illegal, - fa_t->cnt_crc8_fail, fa_t->cnt_mcs_fail, - fa_t->cnt_fast_fsync, fa_t->cnt_sb_search_fail); + "\r\n [VHT FA] SIGA_CRC8=%d, SIGB_CRC8=%d, MCS=%d", + fa_t->cnt_crc8_fail_vhta, fa_t->cnt_crc8_fail_vhtb, + fa_t->cnt_mcs_fail_vht); RT_PRINT(buf); } - #endif +#endif + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, - "\r\n is_linked = %d, Num_client = %d, rssi_min = %d, IGI = 0x%x, bNoisy=%d\n", - dm->is_linked, dm->number_linked_client, dm->rssi_min, - dm->dm_dig_table.cur_ig_value, dm->noisy_decision); + "\r\n [CRC32 OK Cnt] {CCK, OFDM, HT, VHT, Total} = {%d, %d, %d, %d, %d}", + fa_t->cnt_cck_crc32_ok, fa_t->cnt_ofdm_crc32_ok, + fa_t->cnt_ht_crc32_ok, fa_t->cnt_vht_crc32_ok, + fa_t->cnt_crc32_ok_all); + RT_PRINT(buf); + + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, + "\r\n [CRC32 Err Cnt] {CCK, OFDM, HT, VHT, Total} = {%d, %d, %d, %d, %d}", + fa_t->cnt_cck_crc32_error, fa_t->cnt_ofdm_crc32_error, + fa_t->cnt_ht_crc32_error, fa_t->cnt_vht_crc32_error, + fa_t->cnt_crc32_error_all); + RT_PRINT(buf); + + if (fa_t->ofdm2_rate_idx) { + phydm_print_rate_2_buff(dm, fa_t->ofdm2_rate_idx, + dbg_buf, PHYDM_SNPRINT_SIZE); + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, + "\r\n [OFDM:%s CRC32 Cnt] {error, ok}= {%d, %d} (%d percent)", + dbg_buf, fa_t->cnt_ofdm2_crc32_error, + fa_t->cnt_ofdm2_crc32_ok, fa_t->ofdm2_pcr); + RT_PRINT(buf); + } + + if (fa_t->ht2_rate_idx) { + phydm_print_rate_2_buff(dm, fa_t->ht2_rate_idx, dbg_buf, + PHYDM_SNPRINT_SIZE); + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, + "\r\n [HT :%s CRC32 Cnt] {error, ok}= {%d, %d} (%d percent)", + dbg_buf, fa_t->cnt_ht2_crc32_error, + fa_t->cnt_ht2_crc32_ok, fa_t->ht2_pcr); + RT_PRINT(buf); + } + +#if (ODM_IC_11AC_SERIES_SUPPORT || defined(PHYDM_IC_JGR3_SERIES_SUPPORT)) + if (dm->support_ic_type & (ODM_IC_11AC_SERIES | ODM_IC_JGR3_SERIES)) { + if (fa_t->vht2_rate_idx) { + phydm_print_rate_2_buff(dm, fa_t->vht2_rate_idx, + dbg_buf, PHYDM_SNPRINT_SIZE); + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, + "\r\n [VHT :%s CRC32 Cnt] {error, ok}= {%d, %d} (%d percent)", + dbg_buf, fa_t->cnt_vht2_crc32_error, + fa_t->cnt_vht2_crc32_ok, fa_t->vht2_pcr); + RT_PRINT(buf); + } + } +#endif + + if (dm->support_ic_type & (ODM_IC_11N_SERIES | ODM_IC_11AC_SERIES)) + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, + "\r\n is_linked = %d, Num_client = %d, rssi_min = %d, IGI = 0x%x, bNoisy=%d\n", + dm->is_linked, dm->number_linked_client, dm->rssi_min, + dm->dm_dig_table.cur_ig_value, dm->noisy_decision); + else + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, + "\r\n is_linked = %d, Num_client = %d, rssi_min = %d, IGI = 0x%x\n", + dm->is_linked, dm->number_linked_client, dm->rssi_min, + dm->dm_dig_table.cur_ig_value); + RT_PRINT(buf); phydm_dm_summary_cli_win(dm, buf, target_macid); @@ -2005,7 +1972,7 @@ void phydm_show_cn_hitogram(void *dm_void) phydm_print_hist_2_buf(dm, th_tmp, PHY_HIST_TH_SIZE, buf, PHYDM_SNPRINT_SIZE); - PHYDM_DBG(dm, DBG_CMN, "%-22s=%s\n", "[CN_TH]", buf); + PHYDM_DBG(dm, DBG_CMN, "%-24s=%s\n", "[CN_TH]", buf); /*@===[Histogram]=============================================================*/ @@ -2013,13 +1980,16 @@ void phydm_show_cn_hitogram(void *dm_void) if (dbg_s->p4_cnt[i] == 0) continue; - cn_avg = PHYDM_DIV((dbg_s->cn_sum[i] + (dbg_s->p4_cnt[i] >> 1)), - dbg_s->p4_cnt[i]); + cn_avg = PHYDM_DIV((dbg_s->cn_sum[i] + + (dbg_s->p4_cnt[i] >> 1)) << 2, + dbg_s->p4_cnt[i]); /*u(8,1)<<2 -> u(10,3)*/ + cn_hist = &dbg_s->cn_hist[i][0]; phydm_print_hist_2_buf(dm, cn_hist, PHY_HIST_SIZE, buf, PHYDM_SNPRINT_SIZE); - PHYDM_DBG(dm, DBG_CMN, "[%d-SS]%s=(avg:%d.%d)%s\n", - i + 1, "[CN]", cn_avg >> 1, (cn_avg & 0x1) * 5, buf); + PHYDM_DBG(dm, DBG_CMN, "[%d-SS]%s=(avg:%d.%4d)%s\n", + i + 1, "[CN]", cn_avg >> 3, + phydm_show_fraction_num(cn_avg & 0x7, 3), buf); } } #endif @@ -2263,7 +2233,7 @@ void phydm_get_avg_phystatus_val(void *dm_void) if (dbg_s->rssi_cck_cnt) { dbg_avg->rssi_cck_avg = (u8)(dbg_s->rssi_cck_sum / dbg_s->rssi_cck_cnt); - #ifdef PHYSTS_3RD_TYPE_SUPPORT + #if (defined(PHYSTS_3RD_TYPE_SUPPORT) && defined(PHYDM_COMPILE_ABOVE_2SS)) if (dm->support_ic_type & PHYSTS_3RD_TYPE_IC) { for (i = 0; i < dm->num_rf_path - 1; i++) { avg_tmp = dbg_s->rssi_cck_sum_abv_2ss[i] / @@ -2310,30 +2280,8 @@ void phydm_get_avg_phystatus_val(void *dm_void) break; } -#if 1 for (i = 0; i <= dm->num_rf_path; i++) phydm_avg_phy_val_nss(dm, i); -#else - /*@===[OFDM]===*/ - phydm_avg_phy_val_nss(dm, 0); - /*@===[1-SS]===*/ - phydm_avg_phy_val_nss(dm, 1); - /*@===[2-SS]===*/ - #if (defined(PHYDM_COMPILE_ABOVE_2SS)) - if (dm->support_ic_type & (PHYDM_IC_ABOVE_2SS)) - phydm_avg_phy_val_nss(dm, 2); - #endif - /*@===[3-SS]===*/ - #if (defined(PHYDM_COMPILE_ABOVE_3SS)) - if (dm->support_ic_type & (PHYDM_IC_ABOVE_3SS)) - phydm_avg_phy_val_nss(dm, 3); - #endif - /*@===[4-SS]===*/ - #if (defined(PHYDM_COMPILE_ABOVE_4SS)) - if (dm->support_ic_type & PHYDM_IC_ABOVE_4SS) - phydm_avg_phy_val_nss(dm, 4); - #endif -#endif } void phydm_get_phy_statistic(void *dm_void) @@ -2384,7 +2332,8 @@ void phydm_basic_dbg_msg_linked(void *dm_void) #ifdef ODM_IC_11N_SERIES_SUPPORT #ifdef PHYDM_PRIMARY_CCA if (((*dm->channel <= 14) && (*dm->band_width == CHANNEL_WIDTH_40)) && - (dm->support_ic_type & ODM_IC_11N_SERIES)) { + (dm->support_ic_type & ODM_IC_11N_SERIES) && + (dm->support_ability & ODM_BB_PRIMARY_CCA)) { PHYDM_DBG(dm, DBG_CMN, "Primary CCA at ((%s SB))\n", ((*dm->sec_ch_offset == SECOND_CH_AT_LSB) ? "U" : "L")); @@ -2493,6 +2442,13 @@ void phydm_basic_dbg_msg_linked(void *dm_void) (dbg_t->is_ldpc_pkt) ? "Y" : "N", (dbg_t->is_stbc_pkt) ? "Y" : "N"); #endif + +#if (RTL8822C_SUPPORT || RTL8723F_SUPPORT) + /*Beamformed pkt*/ + if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8723F)) + PHYDM_DBG(dm, DBG_CMN, "Beamformed=((%s))\n", + (dm->is_beamformed) ? "Y" : "N"); +#endif } void phydm_dm_summary(void *dm_void, u8 macid) @@ -2628,14 +2584,30 @@ void phydm_basic_dbg_message(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_fa_struct *fa_t = &dm->false_alm_cnt; + struct odm_phy_dbg_info *dbg = &dm->phy_dbg_info; + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + struct odm_phy_dbg_info *dbg_b = &dm->phy_dbg_info_win_bkp; + #endif #ifdef NHM_SUPPORT struct ccx_info *ccx = &dm->dm_ccx_info; - u8 nhm_valid = 0; #endif - if (!(dm->debug_components & DBG_CMN)) + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + /* backup memory*/ + odm_move_memory(dm, dbg_b, dbg, sizeof(struct odm_phy_dbg_info)); + #endif + + if (!(dm->debug_components & DBG_CMN)) { + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + /* reset rx rate distribution*/ + phydm_reset_rx_rate_distribution(dm); + /* cal & reset avg of rssi/snr/evm*/ + phydm_get_avg_phystatus_val(dm); + /* reset sum of rssi/snr/evm*/ + phydm_reset_phystatus_statistic(dm); + #endif return; - + } if (dm->cmn_dbg_msg_cnt >= dm->cmn_dbg_msg_period) { dm->cmn_dbg_msg_cnt = PHYDM_WATCH_DOG_PERIOD; @@ -2652,40 +2624,59 @@ void phydm_basic_dbg_message(void *dm_void) else PHYDM_DBG(dm, DBG_CMN, "No Link !!!\n"); + PHYDM_DBG(dm, DBG_CMN, + "[Tx cnt] {CCK_TxEN, CCK_TxON, OFDM_TxEN, OFDM_TxON} = {%d, %d, %d, %d}\n", + fa_t->cnt_cck_txen, fa_t->cnt_cck_txon, fa_t->cnt_ofdm_txen, + fa_t->cnt_ofdm_txon); PHYDM_DBG(dm, DBG_CMN, "[CCA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n", fa_t->cnt_cck_cca, fa_t->cnt_ofdm_cca, fa_t->cnt_cca_all); - PHYDM_DBG(dm, DBG_CMN, "[FA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n", fa_t->cnt_cck_fail, fa_t->cnt_ofdm_fail, fa_t->cnt_all); - PHYDM_DBG(dm, DBG_CMN, - "[OFDM FA Detail] Parity_Fail=%d, Rate_Illegal=%d, CRC8=%d, MCS_fail=%d, Fast_sync=%d, SB_Search_fail=%d\n", + "[FA duration(us)] {exp, ifs_clm, fahm} = {%d, %d, %d}\n", + fa_t->time_fa_exp, fa_t->time_fa_ifs_clm, + fa_t->time_fa_fahm); + PHYDM_DBG(dm, DBG_CMN, + "[OFDM FA] Parity=%d, Rate=%d, Fast_Fsync=%d, SBD=%d\n", fa_t->cnt_parity_fail, fa_t->cnt_rate_illegal, - fa_t->cnt_crc8_fail, fa_t->cnt_mcs_fail, fa_t->cnt_fast_fsync, fa_t->cnt_sb_search_fail); - + PHYDM_DBG(dm, DBG_CMN, "[HT FA] CRC8=%d, MCS=%d\n", + fa_t->cnt_crc8_fail, fa_t->cnt_mcs_fail); #if (ODM_IC_11AC_SERIES_SUPPORT || defined(PHYDM_IC_JGR3_SERIES_SUPPORT)) if (dm->support_ic_type & (ODM_IC_11AC_SERIES | ODM_IC_JGR3_SERIES)) { PHYDM_DBG(dm, DBG_CMN, - "[OFDM FA Detail VHT] CRC8_VHT-SIGA=%d, CRC8_VHT-SIGB=%d, MCS_Fail_VHT=%d\n", + "[VHT FA] SIGA_CRC8=%d, SIGB_CRC8=%d, MCS=%d\n", fa_t->cnt_crc8_fail_vhta, fa_t->cnt_crc8_fail_vhtb, fa_t->cnt_mcs_fail_vht); } #endif PHYDM_DBG(dm, DBG_CMN, - "is_linked = %d, Num_client = %d, rssi_min = %d, IGI = 0x%x, bNoisy=%d\n", - dm->is_linked, dm->number_linked_client, dm->rssi_min, - dm->dm_dig_table.cur_ig_value, dm->noisy_decision); + "[CRC32 OK Cnt] {CCK, OFDM, HT, VHT, Total} = {%d, %d, %d, %d, %d}\n", + fa_t->cnt_cck_crc32_ok, fa_t->cnt_ofdm_crc32_ok, + fa_t->cnt_ht_crc32_ok, fa_t->cnt_vht_crc32_ok, + fa_t->cnt_crc32_ok_all); + PHYDM_DBG(dm, DBG_CMN, + "[CRC32 Err Cnt] {CCK, OFDM, HT, VHT, Total} = {%d, %d, %d, %d, %d}\n", + fa_t->cnt_cck_crc32_error, fa_t->cnt_ofdm_crc32_error, + fa_t->cnt_ht_crc32_error, fa_t->cnt_vht_crc32_error, + fa_t->cnt_crc32_error_all); + + if (dm->support_ic_type & (ODM_IC_11N_SERIES | ODM_IC_11AC_SERIES)) + PHYDM_DBG(dm, DBG_CMN, + "is_linked = %d, Num_client = %d, rssi_min = %d, IGI = 0x%x, bNoisy=%d\n", + dm->is_linked, dm->number_linked_client, dm->rssi_min, + dm->dm_dig_table.cur_ig_value, dm->noisy_decision); + else + PHYDM_DBG(dm, DBG_CMN, + "is_linked = %d, Num_client = %d, rssi_min = %d, IGI = 0x%x\n", + dm->is_linked, dm->number_linked_client, dm->rssi_min, + dm->dm_dig_table.cur_ig_value); #ifdef NHM_SUPPORT if (dm->support_ability & ODM_BB_ENV_MONITOR) { - nhm_valid = (ccx->nhm_noise_pwr_point * 100) >> 8; - PHYDM_DBG(dm, DBG_CMN, - "[NHM] valid: %d percent, noise(RSSI) = %d, nhm_r[11](RSSI > %d)= %d\n\n", - nhm_valid, ccx->nhm_noise_pwr, - NTH_TH_2_RSSI(ccx->nhm_th[NHM_TH_NUM - 1]), - ccx->nhm_result[NHM_RPT_NUM - 1]); + "[NHM] valid: %d percent, noise(RSSI) = %d\n", + ccx->nhm_level_valid, ccx->nhm_level); } #endif } @@ -2857,6 +2848,14 @@ void phydm_basic_profile(void *dm_void, u32 *_used, char *output, u32 *_out_len) } #endif +#if (RTL8723F_SUPPORT) + else if (dm->support_ic_type == ODM_RTL8723F) { + ic_type = "RTL8723F"; + date = RELEASE_DATE_8723F; + commit_by = COMMIT_BY_8723F; + release_ver = RELEASE_VERSION_8723F; + } +#endif #if (RTL8812F_SUPPORT) else if (dm->support_ic_type == ODM_RTL8812F) { ic_type = "RTL8812F"; @@ -2926,7 +2925,7 @@ void phydm_basic_profile(void *dm_void, u32 *_used, char *output, u32 *_out_len) PDM_SNPF(out_len, used, output + used, out_len - used, " %-35s: %d\n", "RFE type", dm->rfe_type); PDM_SNPF(out_len, used, output + used, out_len - used, " %-35s: %s\n", - "Cut Ver", cut); + "CART_Ver", cut); PDM_SNPF(out_len, used, output + used, out_len - used, " %-35s: %d\n", "PHY Para Ver", odm_get_hw_img_version(dm)); PDM_SNPF(out_len, used, output + used, out_len - used, " %-35s: %d\n", @@ -2945,6 +2944,10 @@ void phydm_basic_profile(void *dm_void, u32 *_used, char *output, u32 *_out_len) "% PHYDM version %"); PDM_SNPF(out_len, used, output + used, out_len - used, " %-35s: %s\n", "Code base", PHYDM_CODE_BASE); +#ifdef PHYDM_SVN_REV + PDM_SNPF(out_len, used, output + used, out_len - used, " %-35s: %s\n", + "PHYDM SVN Ver", PHYDM_SVN_REV); +#endif PDM_SNPF(out_len, used, output + used, out_len - used, " %-35s: %s\n", "Release Date", PHYDM_RELEASE_DATE); PDM_SNPF(out_len, used, output + used, out_len - used, " %-35s: %s\n", @@ -3230,6 +3233,10 @@ void phydm_set_txagc(void *dm_void, u32 *const val, u32 *_used, pow = (val[3] & 0x3f); for (i = 0; i <= ODM_RATEMCS7; i++) rpt &= phydm_api_set_txagc(dm, pow, path, i, 0); + } else if (dm->support_ic_type &(ODM_RTL8723F)) { + pow = (val[3] & 0x7f); + for (i = 0; i <= ODM_RATEMCS7; i++) + rpt &= phydm_api_set_txagc(dm, pow, path, i, 0); } if (rpt) @@ -3339,7 +3346,7 @@ void phydm_shift_txagc(void *dm_void, u32 *const val, u32 *_used, char *output, } } else if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | - ODM_RTL8812F | ODM_RTL8197G)) { + ODM_RTL8812F | ODM_RTL8197G | ODM_RTL8723F)) { rpt &= phydm_api_shift_txagc(dm, val[3], path, 1); } } @@ -3371,10 +3378,8 @@ void phydm_set_txagc_dbg(void *dm_void, char input[][16], u32 *_used, u8 i = 0, input_idx = 0; for (i = 0; i < 5; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + input_idx++; } if ((strcmp(input[1], help) == 0)) { @@ -3443,6 +3448,33 @@ void phydm_set_txagc_dbg(void *dm_void, char input[][16], u32 *_used, *_out_len = out_len; } +void phydm_cmn_msg_setting(void *dm_void, u32 *val, u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 used = *_used; + u32 out_len = *_out_len; + + if (val[1] == 1) { + dm->cmn_dbg_msg_period = (u8)val[2]; + + if (dm->cmn_dbg_msg_period < PHYDM_WATCH_DOG_PERIOD) + dm->cmn_dbg_msg_period = PHYDM_WATCH_DOG_PERIOD; + + PDM_SNPF(out_len, used, output + used, out_len - used, + "cmn_dbg_msg_period=%d\n", dm->cmn_dbg_msg_period); + } + +#ifdef PHYDM_PHYSTAUS_AUTO_SWITCH + if (val[1] == 1) + phydm_physts_auto_switch_jgr3_set(dm, true, BIT(4) | BIT(1)); + else + phydm_physts_auto_switch_jgr3_set(dm, false, BIT(1)); +#endif + *_used = used; + *_out_len = out_len; +} + void phydm_debug_trace(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len) { @@ -3455,7 +3487,6 @@ void phydm_debug_trace(void *dm_void, char input[][16], u32 *_used, u8 i = 0; for (i = 0; i < 5; i++) { - if (input[i + 1]) PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); } comp = dm->debug_components; @@ -3577,15 +3608,8 @@ void phydm_debug_trace(void *dm_void, char input[][16], u32 *_used, dm->phy_dbg_info.show_phy_sts_all_pkt, dm->phy_dbg_info.show_phy_sts_max_cnt); - } else if ((BIT(val[0]) == DBG_CMN) && (val[1] == 1)) { - dm->cmn_dbg_msg_period = (u8)val[2]; - - if (dm->cmn_dbg_msg_period < PHYDM_WATCH_DOG_PERIOD) - dm->cmn_dbg_msg_period = PHYDM_WATCH_DOG_PERIOD; - - PDM_SNPF(out_len, used, output + used, out_len - used, - "cmn_dbg_msg_period=%d\n", - dm->cmn_dbg_msg_period); + } else if (BIT(val[0]) == DBG_CMN) { + phydm_cmn_msg_setting(dm, val, &used, output, &out_len); } } PDM_SNPF(out_len, used, output + used, out_len - used, @@ -3612,10 +3636,8 @@ void phydm_fw_debug_trace(void *dm_void, char input[][16], u32 *_used, u32 comp = 0; for (i = 0; i < 5; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); + input_idx++; } if (input_idx == 0) @@ -3693,7 +3715,7 @@ void phydm_dump_bb_reg_ac(void *dm_void, u32 *_used, char *output, } if (!(dm->support_ic_type & - (ODM_RTL8822B | ODM_RTL8814A | ODM_RTL8821C))) + (ODM_RTL8822B | ODM_RTL8814A | ODM_RTL8821C | ODM_RTL8195B))) goto rpt_reg; if (dm->rf_type > RF_2T2R) { @@ -3760,10 +3782,34 @@ void phydm_dump_bb_reg_jgr3(void *dm_void, u32 *_used, char *output, out_len - used, "0x%04x 0x%08x\n", addr, odm_get_bb_reg(dm, addr, MASKDWORD)); + #if (defined(RTL8723F_SUPPORT)) + if (dm->support_ic_type & ODM_RTL8723F) { + for (addr = 0x2a00; addr < 0x2a5c; addr += 4) { + PDM_VAST_SNPF(out_len, used, output + used, + out_len - used, "0x%04x 0x%08x\n", + addr, + odm_get_bb_reg(dm, addr, + MASKDWORD)); + } + } + #endif + for (addr = 0x4000; addr < 0x41ff; addr += 4) PDM_VAST_SNPF(out_len, used, output + used, out_len - used, "0x%04x 0x%08x\n", addr, odm_get_bb_reg(dm, addr, MASKDWORD)); + + #if (defined(RTL8723F_SUPPORT)) + if (dm->support_ic_type & ODM_RTL8723F) { + for (addr = 0x4300; addr < 0x43bf; addr += 4) { + PDM_VAST_SNPF(out_len, used, output + used, + out_len - used, "0x%04x 0x%08x\n", + addr, + odm_get_bb_reg(dm, addr, + MASKDWORD)); + } + } + #endif } *_used = used; *_out_len = out_len; @@ -3790,9 +3836,22 @@ void phydm_dump_bb_reg2_jgr3(void *dm_void, u32 *_used, char *output, } } #endif + /* @Do not change the order of page-2C/2D*/ PDM_VAST_SNPF(out_len, used, output + used, out_len - used, "------ BB report-register start ------\n"); + + #if (defined(RTL8723F_SUPPORT)) + if (dm->support_ic_type & ODM_RTL8723F) { + for (addr = 0x2aa0; addr < 0x2aff; addr += 4) { + PDM_VAST_SNPF(out_len, used, output + used, + out_len - used, "0x%04x 0x%08x\n", + addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + } + } + #endif + for (addr = 0x2c00; addr < 0x2dff; addr += 4) { PDM_VAST_SNPF(out_len, used, output + used, out_len - used, "0x%04x 0x%08x\n", @@ -3817,8 +3876,8 @@ void phydm_get_per_path_anapar_jgr3(void *dm_void, u8 path, u32 *_used, u32 dbgport_idx = 0; u32 dbgport_val = 0; - PDM_SNPF(out_len, used, output + used, out_len - used, "path-%d:\n", - path); + PDM_VAST_SNPF(out_len, used, output + used, out_len - used, + "path-%d:\n", path); if (path == RF_PATH_A) { reg_idx = R_0x1830; @@ -3843,14 +3902,16 @@ void phydm_get_per_path_anapar_jgr3(void *dm_void, u8 path, u32 *_used, dbgport_val = phydm_get_bb_dbg_port_val(dm); phydm_release_bb_dbg_port(dm); } else { - PDM_SNPF(out_len, used, output + used, out_len - used, - "state:0x%x = read dbg_port error!\n", state); + PDM_VAST_SNPF(out_len, used, output + used, + out_len - used, + "state:0x%x = read dbg_port error!\n", + state); } control_bb = (dbgport_val & 0xFFFF0) >> 4; control_pow = dbgport_val & 0xF; - PDM_SNPF(out_len, used, output + used, out_len - used, - "state:0x%x = control_bb:0x%x pow_bb:0x%x\n", - state, control_bb, control_pow); + PDM_VAST_SNPF(out_len, used, output + used, out_len - used, + "state:0x%x = control_bb:0x%x pow_bb:0x%x\n", + state, control_bb, control_pow); } odm_set_bb_reg(dm, reg_idx, 0xf00000, state_bp); odm_set_bb_reg(dm, reg_idx, 0x38000000, 0x6); /* @write en*/ @@ -3859,6 +3920,47 @@ void phydm_get_per_path_anapar_jgr3(void *dm_void, u8 path, u32 *_used, *_out_len = out_len; } +void phydm_get_csi_table_jgr3(void *dm_void, u32 *_used, char *output, + u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u8 table_idx = 0; + u8 table_val = 0; + u32 used = *_used; + u32 out_len = *_out_len; + u32 dbgport_idx = 0x39e; + u32 dbgport_val = 0; + + /*enable clk*/ + odm_set_bb_reg(dm, R_0x1ee8, 0x3, 0x3); + /*enable read table*/ + odm_set_bb_reg(dm, R_0x1d94, BIT(31) | BIT(30), 0x2); + + for (table_idx = 0; table_idx < 128; table_idx++) { + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, table_idx); + if (phydm_set_bb_dbg_port(dm, DBGPORT_PRI_3, dbgport_idx)) { + dbgport_val = phydm_get_bb_dbg_port_val(dm); + phydm_release_bb_dbg_port(dm); + } else { + PDM_VAST_SNPF(out_len, used, output + used, + out_len - used, + "table_idx:0x%x = read dbg_port error!\n", + table_idx); + } + table_val = dbgport_val >> 24; + PDM_VAST_SNPF(out_len, used, output + used, out_len - used, + "table_idx: 0x%x = 0x%x\n", + table_idx, table_val); + } + /*enable write table*/ + odm_set_bb_reg(dm, R_0x1d94, BIT(31) | BIT(30), 0x1); + /*disable clk*/ + odm_set_bb_reg(dm, R_0x1ee8, 0x3, 0x0); + + *_used = used; + *_out_len = out_len; +} + #endif void phydm_dump_bb_reg(void *dm_void, u32 *_used, char *output, u32 *_out_len) @@ -3998,8 +4100,7 @@ void phydm_dump_reg(void *dm_void, char input[][16], u32 *_used, char *output, u32 out_len = *_out_len; u32 addr = 0; - if (input[1]) - PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); if ((strcmp(input[1], help) == 0)) { #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT @@ -4077,7 +4178,7 @@ void phydm_show_rx_rate(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len) { #if (RTL8822B_SUPPORT || RTL8821C_SUPPORT || RTL8814B_SUPPORT ||\ - RTL8195B_SUPPORT || RTL8822C_SUPPORT) + RTL8195B_SUPPORT || RTL8822C_SUPPORT || RTL8723F_SUPPORT) struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_phy_dbg_info *dbg = &dm->phy_dbg_info; u32 used = *_used; @@ -4087,10 +4188,8 @@ void phydm_show_rx_rate(void *dm_void, char input[][16], u32 *_used, u8 i, input_idx = 0; for (i = 0; i < 5; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + input_idx++; } if (input_idx == 0) @@ -4180,8 +4279,7 @@ void phydm_per_tone_evm(void *dm_void, char input[][16], u32 *_used, } for (i = 0; i < 4; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); } avg_num = var1[0]; @@ -4402,8 +4500,7 @@ void phydm_bw_ch_adjust(void *dm_void, char input[][16], } for (i = 0; i < 4; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); } is_enable_dbg_mode = (boolean)var1[0]; @@ -4434,10 +4531,8 @@ void phydm_ext_rf_element_ctrl(void *dm_void, char input[][16], u32 *_used, u8 i = 0, input_idx = 0; for (i = 0; i < 5; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); + input_idx++; } if (input_idx == 0) @@ -4519,6 +4614,27 @@ void phydm_get_anapar_table(void *dm_void, u32 *_used, char *output, *_out_len = out_len; } +void phydm_get_csi_table(void *dm_void, u32 *_used, char *output, + u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 used = *_used; + u32 out_len = *_out_len; + +#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT + if (!(dm->support_ic_type & ODM_IC_JGR3_SERIES)) + return; + + PDM_VAST_SNPF(out_len, used, output + used, out_len - used, + "------ CSI Table Parsing start ------\n"); + + phydm_get_csi_table_jgr3(dm, &used, output, &out_len); +#endif + + *_used = used; + *_out_len = out_len; +} + void phydm_dd_dbg_dump(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len) { @@ -4860,8 +4976,7 @@ void phydm_reg_monitor(void *dm_void, char input[][16], u32 *_used, u8 i = 0; for (i = 0; i < 7; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); } if ((strcmp(input[1], help) == 0)) { @@ -4897,7 +5012,121 @@ void phydm_reg_monitor(void *dm_void, char input[][16], u32 *_used, *_out_len = out_len; } -#if RTL8814B_SUPPORT +#if (RTL8822C_SUPPORT) +u16 phydm_get_agc_rf_gain(void *dm_void, boolean is_mod, u8 tab, u8 mp_gain_i) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u16 rf_gain = 0x0; + + if (is_mod) + rf_gain = dm->agc_rf_gain[tab][mp_gain_i]; + else + rf_gain = dm->agc_rf_gain_ori[tab][mp_gain_i]; + + return rf_gain; +} +#endif + +void phydm_get_rxagc_table_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + char help[] = "-h"; + u32 var1[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u8 tab = 0; + boolean is_modified = false; + u8 mp_gain = 0; + u16 rf_gain = 0; + u8 i = 0; + +#if (RTL8822C_SUPPORT) + if (!(dm->support_ic_type & ODM_RTL8822C)) + return; + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "get rxagc table : {0:ori, 1:modified} {table:0~15} {mp_gain_idx:0~63, all:0xff}\n"); + } else { + for (i = 0; i < 3; i++) { + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + } + + is_modified = (boolean)var1[0]; + tab = (u8)var1[1]; + mp_gain = (u8)var1[2]; + + PDM_SNPF(out_len, used, output + used, out_len - used, + "agc_table_cnt:%d, is_agc_tab_pos_shift:%d, agc_table_shift:%d\n", + dm->agc_table_cnt, dm->is_agc_tab_pos_shift, + dm->agc_table_shift); + + if (mp_gain == 0xff) { + for (i = 0; i < 64; i++) { + rf_gain = phydm_get_agc_rf_gain(dm, is_modified, + tab, i); + + PDM_SNPF(out_len, used, output + used, + out_len - used, + "agc_table:%d, mp_gain_idx:0x%x, rf_gain_idx:0x%x\n", + tab, i, rf_gain); + } + } else { + rf_gain = phydm_get_agc_rf_gain(dm, is_modified, tab, + mp_gain); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "agc_table:%d, mp_gain_idx:0x%x, rf_gain_idx:0x%x\n", + tab, mp_gain, rf_gain); + } + } +#endif + *_used = used; + *_out_len = out_len; +} + +void phydm_shift_rxagc_table_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + char help[] = "-h"; + u32 var1[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u8 i = 0; + u16 value_db = 0; + +#if (RTL8822C_SUPPORT) + if (!(dm->support_ic_type & ODM_RTL8822C)) + return; + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "shift rxagc table : {0:-, 1:+} {value(0~63, unit:2dB)}\n"); + } else { + for (i = 0; i < 3; i++) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + } + + if ((u8)var1[1] > 63) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "Do not enter the value larger than 63!\n"); + } else { + phydm_shift_rxagc_table(dm, (boolean)var1[0], + (u8)var1[1]); + + value_db = (u8)var1[1] << 1; + PDM_SNPF(out_len, used, output + used, out_len - used, + "shift %s%d dB gain\n", + (((boolean)var1[0]) ? "+" : "-"), value_db); + } + } +#endif +} + +#if (RTL8814B_SUPPORT || RTL8198F_SUPPORT) void phydm_spur_detect_dbg(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len) { @@ -4910,40 +5139,57 @@ void phydm_spur_detect_dbg(void *dm_void, char input[][16], u32 *_used, if ((strcmp(input[1], help) == 0)) { PDM_SNPF(out_len, used, output + used, out_len - used, - "{0: Auto spur detect(NBI+CSI), 1:NBI only,"); + "{0: Auto spur detect(NBI+CSI), 1:NBI always ON/ CSI Auto,"); PDM_SNPF(out_len, used, output + used, out_len - used, - "2: CSI only, 3: Disable}\n"); + "2: CSI always On/ NBI Auto, 3: Disable, 4: CSI & NBI ON}\n"); PDM_SNPF(out_len, used, output + used, out_len - used, - "{NBI path(0~3) | CSI wgt (0~7)}\n"); + "{If CSI always ON (Mode 2 or 4) -> CSI wgt manual(0~7)}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "{5: Adjust CSI weight threshold} {0:-,1:+} {th offset}\n"); } else { for (i = 0; i < 10; i++) { if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); } - if (var1[0] == 1) + if (var1[0] == 1) { dm->dsde_sel = DET_NBI; - else if (var1[0] == 2) + } else if (var1[0] == 2) { dm->dsde_sel = DET_CSI; - else if (var1[0] == 3) + } else if (var1[0] == 3) { dm->dsde_sel = DET_DISABLE; - else + } else if (var1[0] == 4) { + dm->dsde_sel = DET_CSI_NBI_EN; + } else if (var1[0] == 0) { dm->dsde_sel = DET_AUTO; - - PDM_SNPF(out_len, used, output + used, out_len - used, - "spur detect mode = %d\n", dm->dsde_sel); - - if (dm->dsde_sel == DET_NBI) { - if (var1[1] < 4) { - dm->nbi_path_sel = (u8)var1[1]; + } else if (var1[0] == 5) { + if (var1[1] == 0) + for (i = 0; i < 5; i++) + dm->csi_wgt_th_db[i] -= (u8)var1[2]; + else if (var1[1] == 1) + for (i = 0; i < 5; i++) + dm->csi_wgt_th_db[i] += (u8)var1[2]; + PDM_SNPF(out_len, used, output + used, out_len - used, "current csi weight threshold:\n"); + for (i = 0; i < 5; i++) PDM_SNPF(out_len, used, output + used, - out_len - used, "NBI set path %d\n", - dm->nbi_path_sel); - } else { + out_len - used, "----%2d", + dm->csi_wgt_th_db[i]); + PDM_SNPF(out_len, used, output + used, out_len - used, "\n"); + for (i = 0; i < 5; i++) PDM_SNPF(out_len, used, output + used, - out_len - used, "path setting fail\n"); - } - } else if (dm->dsde_sel == DET_CSI) { + out_len - used, "--%d--|", i); + PDM_SNPF(out_len, used, output + used, out_len - used, "\n"); + } else { + PDM_SNPF(out_len, used, output + used, out_len - used, + "Spur detection mode invalid!\n"); + return; + } + if (var1[0] < 5) + PDM_SNPF(out_len, used, output + used, out_len - used, + "spur detect mode = %d\n", dm->dsde_sel); + + if (dm->dsde_sel == DET_CSI_NBI_EN) { if (var1[1] < 8) { dm->csi_wgt = (u8)var1[1]; PDM_SNPF(out_len, used, output + used, @@ -4952,7 +5198,8 @@ void phydm_spur_detect_dbg(void *dm_void, char input[][16], u32 *_used, } else { PDM_SNPF(out_len, used, output + used, out_len - used, - "CSI wgt setting fail\n"); + "CSI wgt setting invalid. Please set the correct wgt!\n"); + return; } } } @@ -5023,7 +5270,21 @@ enum PHYDM_CMD_ID { #if RTL8814B_SUPPORT PHYDM_SPUR_DETECT, #endif - PHYDM_PHY_STATUS + PHYDM_PHY_STATUS, + PHYDM_CRC32_CNT, + PHYDM_DCC, +#ifdef PHYDM_HW_IGI + PHYDM_HWIGI, +#endif +#ifdef PHYDM_HW_SWITCH_AGC_TAB + PHYDM_HW_AGCTAB, +#endif + PHYDM_PMAC_TX, + PHYDM_GET_RXAGC, + PHYDM_SHIFT_RXAGC, + PHYDM_IFS_CLM, + PHYDM_ENHANCE_MNTR, + PHYDM_CSI_DBG }; struct phydm_command phy_dm_ary[] = { @@ -5082,7 +5343,23 @@ struct phydm_command phy_dm_ary[] = { #if RTL8814B_SUPPORT {"spur_detect", PHYDM_SPUR_DETECT}, #endif - {"physts", PHYDM_PHY_STATUS} + {"physts", PHYDM_PHY_STATUS}, + {"crc32_cnt", PHYDM_CRC32_CNT}, +#ifdef PHYDM_PMAC_TX_SETTING_SUPPORT + {"pmac_tx", PHYDM_PMAC_TX}, +#endif +#ifdef PHYDM_HW_IGI + {"hwigi", PHYDM_HWIGI}, +#endif +#ifdef PHYDM_HW_SWITCH_AGC_TAB + {"hw_agctab", PHYDM_HW_AGCTAB}, +#endif + {"dcc", PHYDM_DCC}, + {"get_rxagc", PHYDM_GET_RXAGC}, + {"shift_rxagc", PHYDM_SHIFT_RXAGC}, + {"ifs_clm", PHYDM_IFS_CLM}, + {"enh_mntr", PHYDM_ENHANCE_MNTR}, + {"csi_dbg", PHYDM_CSI_DBG} }; #endif /*@#ifdef CONFIG_PHYDM_DEBUG_FUNCTION*/ @@ -5355,8 +5632,7 @@ void phydm_cmd_parser(struct dm_struct *dm, char input[][MAX_ARGV], break; case PHYDM_DIS_HTSTF_CONTROL: { - if (input[1]) - PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); if (var1[0] == 1) { /* setting being false is for debug */ @@ -5442,10 +5718,49 @@ void phydm_cmd_parser(struct dm_struct *dm, char input[][MAX_ARGV], phydm_spur_detect_dbg(dm, input, &used, output, &out_len); break; #endif + case PHYDM_CRC32_CNT: + phydm_crc32_cnt_dbg(dm, input, &used, output, &out_len); + break; case PHYDM_PHY_STATUS: phydm_physts_dbg(dm, input, &used, output, &out_len); break; - +#ifdef PHYDM_DCC_ENHANCE + case PHYDM_DCC: + phydm_dig_cckpd_coex_dbg(dm, input, &used, output, &out_len); + break; +#endif +#ifdef PHYDM_PMAC_TX_SETTING_SUPPORT + case PHYDM_PMAC_TX: + phydm_pmac_tx_dbg(dm, input, &used, output, &out_len); + break; +#endif +#ifdef PHYDM_HW_IGI + case PHYDM_HWIGI: + phydm_hwigi_dbg(dm, input, &used, output, &out_len); + break; +#endif +#ifdef PHYDM_HW_SWITCH_AGC_TAB + case PHYDM_HW_AGCTAB: + phydm_auto_agc_tab_debug(dm, input, &used, output, &out_len); + break; +#endif + case PHYDM_GET_RXAGC: + phydm_get_rxagc_table_dbg(dm, input, &used, output, &out_len); + break; + case PHYDM_SHIFT_RXAGC: + phydm_shift_rxagc_table_dbg(dm, input, &used, output, &out_len); + break; + case PHYDM_IFS_CLM: + #ifdef IFS_CLM_SUPPORT + phydm_ifs_clm_dbg(dm, input, &used, output, &out_len); + #endif + break; + case PHYDM_ENHANCE_MNTR: + phydm_enhance_mntr_dbg(dm, input, &used, output, &out_len); + break; + case PHYDM_CSI_DBG: + phydm_get_csi_table(dm, &used, output, &out_len); + break; default: PDM_SNPF(out_len, used, output + used, out_len - used, "Do not support this command\n"); @@ -5571,9 +5886,7 @@ void phydm_fw_trace_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) PHYDM_DBG(dm, DBG_FW_TRACE, "[FW DBG Msg] %s\n", dm->fw_debug_trace); -#if 0 - /*@dbg_print("[FW DBG Msg] %s\n", dm->fw_debug_trace);*/ -#endif + dm->c2h_cmd_start = 0; dm->fw_buff_is_enpty = true; } @@ -5816,12 +6129,6 @@ void phydm_fw_trace_handler_8051(void *dm_void, u8 *buffer, u8 cmd_len) { #ifdef CONFIG_PHYDM_DEBUG_FUNCTION struct dm_struct *dm = (struct dm_struct *)dm_void; -#if 0 - if (cmd_len >= 3) - cmd_buf[cmd_len - 1] = '\0'; - PHYDM_DBG(dm, DBG_FW_TRACE, "[FW DBG Msg] %s\n", &cmd_buf[3]); -#else - int i = 0; u8 extend_c2h_sub_id = 0, extend_c2h_dbg_len = 0; u8 extend_c2h_dbg_seq = 0; @@ -5866,7 +6173,5 @@ go_backfor_aggre_dbg_pkt: goto go_backfor_aggre_dbg_pkt; } } - -#endif #endif /*@#ifdef CONFIG_PHYDM_DEBUG_FUNCTION*/ } diff --git a/hal/phydm/phydm_debug.h b/hal/phydm/phydm_debug.h index fe3bc06..06e809b 100644 --- a/hal/phydm/phydm_debug.h +++ b/hal/phydm/phydm_debug.h @@ -31,8 +31,8 @@ /*#define DEBUG_VERSION "1.3"*/ /*2016.04.28 YuChen*/ /*#define DEBUG_VERSION "1.4"*/ /*2017.03.13 Dino*/ /*#define DEBUG_VERSION "2.0"*/ /*2018.01.10 Dino*/ -/* 2019.03.25 fix nhm_r[11] debug msg error*/ -#define DEBUG_VERSION "2.6" +/*2020.07.03 fix cck report bug due to 8723F coding error*/ +#define DEBUG_VERSION "4.6" /*@ * ============================================================ diff --git a/hal/phydm/phydm_dfs.c b/hal/phydm/phydm_dfs.c index 092d41b..0384148 100644 --- a/hal/phydm/phydm_dfs.c +++ b/hal/phydm/phydm_dfs.c @@ -73,7 +73,7 @@ void phydm_radar_detect_reset(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8822C | ODM_RTL8812F | - ODM_RTL8197G)) { + ODM_RTL8197G | ODM_RTL8723F)) { odm_set_bb_reg(dm, R_0xa40, BIT(15), 0); odm_set_bb_reg(dm, R_0xa40, BIT(15), 1); #if (RTL8721D_SUPPORT) @@ -100,7 +100,7 @@ void phydm_radar_detect_disable(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8822C | ODM_RTL8812F | - ODM_RTL8197G)) + ODM_RTL8197G | ODM_RTL8723F)) odm_set_bb_reg(dm, R_0xa40, BIT(15), 0); else if (dm->support_ic_type & (ODM_RTL8814B)) { if (dm->seg1_dfs_flag == 1) { @@ -635,7 +635,7 @@ void phydm_dfs_parameter_init(void *dm_void) /*@for dynamic dfs*/ dfs->pwdb_th = 8; - dfs->fa_mask_th = 30 * (dfs->dfs_polling_time / 100); + dfs->fa_mask_th = 30 * (dfs->dfs_polling_time) / 100; dfs->st_l2h_min = 0x20; dfs->st_l2h_max = 0x4e; dfs->pwdb_scalar_factor = 12; @@ -829,21 +829,18 @@ phydm_radar_detect_dm_check( struct _DFS_STATISTICS *dfs = &dm->dfs; u8 region_domain = dm->dfs_region_domain, index = 0; - u16 i = 0, j = 0, k = 0, fa_count_cur = 0, fa_count_inc = 0; - u16 total_fa_in_hist = 0, pre_post_now_acc_fa_in_hist = 0; - u16 max_fa_in_hist = 0, vht_crc_ok_cnt_cur = 0; - u16 vht_crc_ok_cnt_inc = 0, ht_crc_ok_cnt_cur = 0; - u16 ht_crc_ok_cnt_inc = 0, leg_crc_ok_cnt_cur = 0; - u16 leg_crc_ok_cnt_inc = 0; - u16 total_crc_ok_cnt_inc = 0, short_pulse_cnt_cur = 0; - u16 short_pulse_cnt_inc = 0, long_pulse_cnt_cur = 0; - u16 long_pulse_cnt_inc = 0, total_pulse_count_inc = 0; + u16 i = 0, j = 0, fa_count_cur = 0, fa_count_inc = 0; + u16 total_fa_in_hist = 0, total_pulse_count_inc = 0; + u16 short_pulse_cnt_inc = 0, short_pulse_cnt_cur = 0; + u16 long_pulse_cnt_inc = 0, long_pulse_cnt_cur = 0; u32 regf98_value = 0, reg918_value = 0, reg91c_value = 0; u32 reg920_value = 0, reg924_value = 0, radar_rpt_reg_value = 0; u32 regf54_value = 0, regf58_value = 0, regf5c_value = 0; u32 regdf4_value = 0, regf70_value = 0, regf74_value = 0; + #if (RTL8812F_SUPPORT || RTL8822C_SUPPORT || RTL8814B_SUPPORT) u32 rega40_value = 0, rega44_value = 0, rega48_value = 0; u32 rega4c_value = 0, rega50_value = 0, rega54_value = 0; + #endif #if (RTL8721D_SUPPORT) u32 reg908_value = 0, regdf4_value = 0; u32 regf54_value = 0, regf58_value = 0, regf5c_value = 0; @@ -852,7 +849,7 @@ phydm_radar_detect_dm_check( boolean tri_short_pulse = 0, tri_long_pulse = 0, radar_type = 0; boolean fault_flag_det = 0, fault_flag_psd = 0, fa_flag = 0; boolean radar_detected = 0; - u8 st_l2h_new = 0, fa_mask_th = 0, sum = 0; + u8 st_l2h_new = 0, fa_mask_th = 0, k = 0, sum = 0; u8 c_channel = *dm->channel; /*@Get FA count during past 100ms, R_0xf48 for AC series*/ @@ -893,116 +890,16 @@ phydm_radar_detect_dm_check( dfs->fa_inc_hist[dfs->mask_idx] = fa_count_inc; - for (i = 0; i < 5; i++) { + for (i = 0; i < 5; i++) total_fa_in_hist = total_fa_in_hist + dfs->fa_inc_hist[i]; - if (dfs->fa_inc_hist[i] > max_fa_in_hist) - max_fa_in_hist = dfs->fa_inc_hist[i]; - } + if (dfs->mask_idx >= 2) index = dfs->mask_idx - 2; else index = 5 + dfs->mask_idx - 2; - if (index == 0) { - pre_post_now_acc_fa_in_hist = dfs->fa_inc_hist[index] + - dfs->fa_inc_hist[index + 1] + - dfs->fa_inc_hist[4]; - } else if (index == 4) { - pre_post_now_acc_fa_in_hist = dfs->fa_inc_hist[index] + - dfs->fa_inc_hist[0] + - dfs->fa_inc_hist[index - 1]; - } else { - pre_post_now_acc_fa_in_hist = dfs->fa_inc_hist[index] + - dfs->fa_inc_hist[index + 1] + - dfs->fa_inc_hist[index - 1]; - } - - /*@Get VHT CRC32 ok count during past 100ms*/ - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) - vht_crc_ok_cnt_cur = (u16)odm_get_bb_reg(dm, R_0x2c0c, 0xffff); - #if (RTL8721D_SUPPORT) - else if (dm->support_ic_type & ODM_RTL8721D) - vht_crc_ok_cnt_cur = 0; - #endif - else - vht_crc_ok_cnt_cur = (u16)odm_get_bb_reg(dm, R_0xf0c, - 0x00003fff); - - if (vht_crc_ok_cnt_cur >= dfs->vht_crc_ok_cnt_pre) { - vht_crc_ok_cnt_inc = vht_crc_ok_cnt_cur - - dfs->vht_crc_ok_cnt_pre; - } else { - vht_crc_ok_cnt_inc = vht_crc_ok_cnt_cur; - } - dfs->vht_crc_ok_cnt_pre = vht_crc_ok_cnt_cur; - - /*@Get HT CRC32 ok count during past 100ms*/ - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) - ht_crc_ok_cnt_cur = (u16)odm_get_bb_reg(dm, R_0x2c10, 0xffff); - #if (RTL8721D_SUPPORT) - else if (dm->support_ic_type & (ODM_RTL8721D)) - ht_crc_ok_cnt_cur = (u16)odm_get_bb_reg(dm, R_0xf90, MASKLWORD); - #endif - else - ht_crc_ok_cnt_cur = (u16)odm_get_bb_reg(dm, R_0xf10, - 0x00003fff); - - if (ht_crc_ok_cnt_cur >= dfs->ht_crc_ok_cnt_pre) - ht_crc_ok_cnt_inc = ht_crc_ok_cnt_cur - dfs->ht_crc_ok_cnt_pre; - else - ht_crc_ok_cnt_inc = ht_crc_ok_cnt_cur; - dfs->ht_crc_ok_cnt_pre = ht_crc_ok_cnt_cur; - - /*@Get Legacy CRC32 ok count during past 100ms*/ - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) - leg_crc_ok_cnt_cur = (u16)odm_get_bb_reg(dm, R_0x2c14, 0xffff); - #if (RTL8721D_SUPPORT) - else if (dm->support_ic_type & ODM_RTL8721D) - leg_crc_ok_cnt_cur = (u16)odm_get_bb_reg(dm, - R_0xf94, MASKLWORD); - #endif - else - leg_crc_ok_cnt_cur = (u16)odm_get_bb_reg(dm, R_0xf14, - 0x00003fff); - - if (leg_crc_ok_cnt_cur >= dfs->leg_crc_ok_cnt_pre) - leg_crc_ok_cnt_inc = leg_crc_ok_cnt_cur - dfs->leg_crc_ok_cnt_pre; - else - leg_crc_ok_cnt_inc = leg_crc_ok_cnt_cur; - dfs->leg_crc_ok_cnt_pre = leg_crc_ok_cnt_cur; - - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - if (vht_crc_ok_cnt_cur == 0xffff || - ht_crc_ok_cnt_cur == 0xffff || - leg_crc_ok_cnt_cur == 0xffff) { - phydm_reset_bb_hw_cnt(dm); - } - #if (RTL8721D_SUPPORT) - } else if (dm->support_ic_type & (ODM_RTL8721D)) { - if (ht_crc_ok_cnt_cur == 0xffff || - leg_crc_ok_cnt_cur == 0xffff) { - odm_set_bb_reg(dm, R_0xf14, BIT(16), 1); - odm_set_bb_reg(dm, R_0xf14, BIT(16), 0); - } - #endif - } else { - if (vht_crc_ok_cnt_cur == 0x3fff || - ht_crc_ok_cnt_cur == 0x3fff || - leg_crc_ok_cnt_cur == 0x3fff) { - phydm_reset_bb_hw_cnt(dm); - } - } - - total_crc_ok_cnt_inc = vht_crc_ok_cnt_inc + - ht_crc_ok_cnt_inc + - leg_crc_ok_cnt_inc; if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8822C | ODM_RTL8812F | - ODM_RTL8197G)) { - /* if (phydm_set_bb_dbg_port(dm, DBGPORT_PRI_2, 0x3b0)) { - * odm_set_bb_reg(dm, 0x1e28, 0x03c00000, 8); - * dbgport2dbc_value = phydm_get_bb_dbg_port_val(dm); - * phydm_release_bb_dbg_port(dm); } - */ + ODM_RTL8197G| ODM_RTL8723F)) { radar_rpt_reg_value = odm_get_bb_reg(dm, R_0x2e00, 0xffffffff); short_pulse_cnt_cur = (u16)((radar_rpt_reg_value & 0x000ff800) >> 11); @@ -1041,7 +938,6 @@ phydm_radar_detect_dm_check( } /*@Get short pulse count, need carefully handle the counter overflow*/ - if (short_pulse_cnt_cur >= dfs->short_pulse_cnt_pre) { short_pulse_cnt_inc = short_pulse_cnt_cur - dfs->short_pulse_cnt_pre; @@ -1051,7 +947,6 @@ phydm_radar_detect_dm_check( dfs->short_pulse_cnt_pre = short_pulse_cnt_cur; /*@Get long pulse count, need carefully handle the counter overflow*/ - if (long_pulse_cnt_cur >= dfs->long_pulse_cnt_pre) { long_pulse_cnt_inc = long_pulse_cnt_cur - dfs->long_pulse_cnt_pre; @@ -1065,10 +960,7 @@ phydm_radar_detect_dm_check( if (dfs->det_print) { PHYDM_DBG(dm, DBG_DFS, "===============================================\n"); - PHYDM_DBG(dm, DBG_DFS, - "Total_CRC_OK_cnt_inc[%d] VHT_CRC_ok_cnt_inc[%d] HT_CRC_ok_cnt_inc[%d] LEG_CRC_ok_cnt_inc[%d] FA_count_inc[%d]\n", - total_crc_ok_cnt_inc, vht_crc_ok_cnt_inc, - ht_crc_ok_cnt_inc, leg_crc_ok_cnt_inc, fa_count_inc); + PHYDM_DBG(dm, DBG_DFS, "FA_count_inc[%d]\n", fa_count_inc); if (dm->support_ic_type & (ODM_RTL8721D)) { PHYDM_DBG(dm, DBG_DFS, "Init_Gain[%x] st_l2h_cur[%x] 0xdf4[%08x] short_pulse_cnt_inc[%d] long_pulse_cnt_inc[%d]\n", @@ -1089,6 +981,7 @@ phydm_radar_detect_dm_check( dfs->igi_cur, dfs->st_l2h_cur, radar_rpt_reg_value, short_pulse_cnt_inc, long_pulse_cnt_inc); + #if (RTL8812F_SUPPORT || RTL8822C_SUPPORT || RTL8814B_SUPPORT) rega40_value = odm_get_bb_reg(dm, R_0xa40, MASKDWORD); rega44_value = odm_get_bb_reg(dm, R_0xa44, MASKDWORD); rega48_value = odm_get_bb_reg(dm, R_0xa48, MASKDWORD); @@ -1099,6 +992,7 @@ phydm_radar_detect_dm_check( "0xa40[%08x] 0xa44[%08x] 0xa48[%08x] 0xa4c[%08x] 0xa50[%08x] 0xa54[%08x]\n", rega40_value, rega44_value, rega48_value, rega4c_value, rega50_value, rega54_value); + #endif } else { PHYDM_DBG(dm, DBG_DFS, "Init_Gain[%x] 0x91c[%x] 0xf98[%08x] short_pulse_cnt_inc[%d] long_pulse_cnt_inc[%d]\n", @@ -1163,11 +1057,8 @@ phydm_radar_detect_dm_check( } else { fa_mask_th = dfs->fa_mask_th; } - if (max_fa_in_hist >= fa_mask_th || - total_fa_in_hist >= fa_mask_th || - pre_post_now_acc_fa_in_hist >= fa_mask_th || - dfs->igi_cur >= 0x30) { - st_l2h_new = dfs->st_l2h_max; + if (total_fa_in_hist >= fa_mask_th || dfs->igi_cur >= 0x30) { + /* st_l2h_new = dfs->st_l2h_max; */ dfs->radar_det_mask_hist[index] = 1; if (dfs->pulse_flag_hist[index] == 1) { dfs->pulse_flag_hist[index] = 0; @@ -1194,9 +1085,8 @@ phydm_radar_detect_dm_check( for (i = 0; i < 5; i++) PHYDM_DBG(dm, DBG_DFS, "%d ", dfs->fa_inc_hist[i]); PHYDM_DBG(dm, DBG_DFS, - "\nfa_mask_th: %d max_fa_in_hist: %d total_fa_in_hist: %d pre_post_now_acc_fa_in_hist: %d ", - fa_mask_th, max_fa_in_hist, total_fa_in_hist, - pre_post_now_acc_fa_in_hist); + "\nfa_mask_th: %d, total_fa_in_hist: %d ", + fa_mask_th, total_fa_in_hist); } sum = 0; @@ -1291,6 +1181,7 @@ phydm_radar_detect_dm_check( return radar_detected; } +#if (RTL8814A_SUPPORT || RTL8822B_SUPPORT || RTL8821C_SUPPORT) void phydm_dfs_histogram_radar_distinguish( void *dm_void) { @@ -1309,43 +1200,18 @@ void phydm_dfs_histogram_radar_distinguish( u8 max_pri_cnt_fcc_g1_th = 0, max_pri_cnt_fcc_g3_th = 0; u8 safe_pri_pw_diff_th = 0, safe_pri_pw_diff_fcc_th = 0; u8 safe_pri_pw_diff_w53_th = 0, safe_pri_pw_diff_fcc_idle_th = 0; - u16 j = 0; - u32 dfs_hist1_peak_index = 0, dfs_hist2_peak_index = 0; + u8 j = 0; u32 dfs_hist1_pw = 0, dfs_hist2_pw = 0, g_pw[6] = {0}; - u32 g_peakindex[16] = {0}, g_mask_32 = 0, false_peak_hist1 = 0; - u32 false_peak_hist2_above10 = 0, false_peak_hist2_above0 = 0; u32 dfs_hist1_pri = 0, dfs_hist2_pri = 0, g_pri[6] = {0}; - u32 pw_sum_g0g5 = 0, pw_sum_g1g2g3g4 = 0; - u32 pri_sum_g0g5 = 0, pri_sum_g1g2g3g4 = 0; - u32 pw_sum_ss_g1g2g3g4 = 0, pri_sum_ss_g1g2g3g4 = 0; - u32 max_pri_cnt = 0, max_pw_cnt = 0; + u8 pw_sum_g0g5 = 0, pw_sum_g1g2g3g4 = 0; + u8 pri_sum_g0g5 = 0, pri_sum_g1g2g3g4 = 0; + u16 pw_sum_ss_g1g2g3g4 = 0, pri_sum_ss_g1g2g3g4 = 0; + u8 max_pri_cnt = 0, max_pw_cnt = 0; #if (RTL8721D_SUPPORT) if (dm->support_ic_type & (ODM_RTL8721D)) return; #endif - /*read peak index hist report*/ - odm_set_bb_reg(dm, 0x19e4, BIT(22) | BIT(23), 0x0); - dfs_hist1_peak_index = odm_get_bb_reg(dm, 0xf5c, 0xffffffff); - dfs_hist2_peak_index = odm_get_bb_reg(dm, 0xf74, 0xffffffff); - - g_peakindex[15] = ((dfs_hist1_peak_index & 0x0000000f) >> 0); - g_peakindex[14] = ((dfs_hist1_peak_index & 0x000000f0) >> 4); - g_peakindex[13] = ((dfs_hist1_peak_index & 0x00000f00) >> 8); - g_peakindex[12] = ((dfs_hist1_peak_index & 0x0000f000) >> 12); - g_peakindex[11] = ((dfs_hist1_peak_index & 0x000f0000) >> 16); - g_peakindex[10] = ((dfs_hist1_peak_index & 0x00f00000) >> 20); - g_peakindex[9] = ((dfs_hist1_peak_index & 0x0f000000) >> 24); - g_peakindex[8] = ((dfs_hist1_peak_index & 0xf0000000) >> 28); - g_peakindex[7] = ((dfs_hist2_peak_index & 0x0000000f) >> 0); - g_peakindex[6] = ((dfs_hist2_peak_index & 0x000000f0) >> 4); - g_peakindex[5] = ((dfs_hist2_peak_index & 0x00000f00) >> 8); - g_peakindex[4] = ((dfs_hist2_peak_index & 0x0000f000) >> 12); - g_peakindex[3] = ((dfs_hist2_peak_index & 0x000f0000) >> 16); - g_peakindex[2] = ((dfs_hist2_peak_index & 0x00f00000) >> 20); - g_peakindex[1] = ((dfs_hist2_peak_index & 0x0f000000) >> 24); - g_peakindex[0] = ((dfs_hist2_peak_index & 0xf0000000) >> 28); - /*read pulse width hist report*/ odm_set_bb_reg(dm, 0x19e4, BIT(22) | BIT(23), 0x1); dfs_hist1_pw = odm_get_bb_reg(dm, 0xf5c, 0xffffffff); @@ -1395,8 +1261,6 @@ void phydm_dfs_histogram_radar_distinguish( for (i = 0; i < 6; i++) { dfs->pw_hold_sum[i] = 0; dfs->pri_hold_sum[i] = 0; - dfs->pw_long_hold_sum[i] = 0; - dfs->pri_long_hold_sum[i] = 0; } if (dfs->idle_mode == 1) @@ -1410,49 +1274,27 @@ void phydm_dfs_histogram_radar_distinguish( /*@collect whole histogram report may take some time *so we add the counter of 2 time slots in FCC and ETSI */ - if (region_domain == 1 || region_domain == 3) { - dfs->pw_hold_sum[i] = dfs->pw_hold_sum[i] + - dfs->pw_hold[(dfs->hist_idx + 1) % 3][i] + - dfs->pw_hold[(dfs->hist_idx + 2) % 3][i]; - dfs->pri_hold_sum[i] = dfs->pri_hold_sum[i] + - dfs->pri_hold[(dfs->hist_idx + 1) % 3][i] + - dfs->pri_hold[(dfs->hist_idx + 2) % 3][i]; - } else{ - /*@collect whole histogram report may take some time, - *so we add the counter of 3 time slots in MKK or else - */ - dfs->pw_hold_sum[i] = dfs->pw_hold_sum[i] + - dfs->pw_hold[(dfs->hist_idx + 1) % 4][i] + - dfs->pw_hold[(dfs->hist_idx + 2) % 4][i] + - dfs->pw_hold[(dfs->hist_idx + 3) % 4][i]; - dfs->pri_hold_sum[i] = dfs->pri_hold_sum[i] + - dfs->pri_hold[(dfs->hist_idx + 1) % 4][i] + - dfs->pri_hold[(dfs->hist_idx + 2) % 4][i] + - dfs->pri_hold[(dfs->hist_idx + 3) % 4][i]; - } + dfs->pw_hold_sum[i] = dfs->pw_hold_sum[i] + + dfs->pw_hold[(dfs->hist_idx + 1) % 3][i] + + dfs->pw_hold[(dfs->hist_idx + 2) % 3][i]; + dfs->pri_hold_sum[i] = dfs->pri_hold_sum[i] + + dfs->pri_hold[(dfs->hist_idx + 1) % 3][i] + + dfs->pri_hold[(dfs->hist_idx + 2) % 3][i]; } /*@For long radar type*/ - for (i = 0; i < 6; i++) { - dfs->pw_long_hold[dfs->hist_long_idx][i] = (u8)g_pw[i]; - dfs->pri_long_hold[dfs->hist_long_idx][i] = (u8)g_pri[i]; - /*@collect whole histogram report may take some time, - *so we add the counter of 299 time slots for long radar - */ - for (j = 1; j < 300; j++) { + for (j = 1; j < 4; j++) { dfs->pw_long_hold_sum[i] = dfs->pw_long_hold_sum[i] + - dfs->pw_long_hold[(dfs->hist_long_idx + j) % 300][i]; + dfs->pw_hold[(dfs->hist_long_idx + j) % 4][i]; dfs->pri_long_hold_sum[i] = dfs->pri_long_hold_sum[i] + - dfs->pri_long_hold[(dfs->hist_long_idx + j) % 300][i]; - } + dfs->pri_hold[(dfs->hist_long_idx + j) % 4][i]; } + dfs->hist_idx++; - dfs->hist_long_idx++; - if (region_domain == 1 || region_domain == 3) { - if (dfs->hist_idx == 3) - dfs->hist_idx = 0; - } else if (dfs->hist_idx == 4) { + if (dfs->hist_idx == 3) dfs->hist_idx = 0; - } + dfs->hist_long_idx++; + if (dfs->hist_long_idx == 4) + dfs->hist_long_idx = 0; max_pri_cnt = 0; max_pri_idx = 0; @@ -1506,20 +1348,14 @@ void phydm_dfs_histogram_radar_distinguish( /*The value may less than the normal variance, *since the variable type is int (not float) */ - dfs->pw_std = (u16)(pw_sum_ss_g1g2g3g4 / 4); - dfs->pri_std = (u16)(pri_sum_ss_g1g2g3g4 / 4); + dfs->pw_std = (u8)(pw_sum_ss_g1g2g3g4 / 4); + dfs->pri_std = (u8)(pri_sum_ss_g1g2g3g4 / 4); if (region_domain == 1) { dfs->pri_type3_4_flag = 1; /*@ETSI flag*/ - /*PRI judgment conditions for short radar type*/ - /*ratio of reasonable group and illegal group && - *pri variation of short radar should be large (=6) - */ - if (max_pri_idx != 4 && dfs->pri_hold_sum[5] > 0) - dfs->pri_cond2 = 0; - else - dfs->pri_cond2 = 1; + /*(OTA) Cancel long PRI case*/ + dfs->pri_cond2 = 1; /*reasonable group shouldn't large*/ if ((pri_sum_g0g5 + pri_sum_g1g2g3g4) / pri_sum_g0g5 > 2 && @@ -1533,12 +1369,8 @@ void phydm_dfs_histogram_radar_distinguish( max_pri_cnt >= max_pri_cnt_fcc_g1_th) dfs->pri_cond4 = 1; - /*we set threshold = 7 (>4) for distinguishing type 3,4 (g3)*/ - if (max_pri_idx == 1 && dfs->pri_hold_sum[3] + - dfs->pri_hold_sum[4] + dfs->pri_hold_sum[5] > 0) - dfs->pri_cond5 = 0; - else - dfs->pri_cond5 = 1; + /*(OTA) Cancel the condition (type 3,4 distinction)*/ + dfs->pri_cond5 = 1; if (dfs->pri_cond1 && dfs->pri_cond2 && dfs->pri_cond3 && dfs->pri_cond4 && dfs->pri_cond5) @@ -1671,7 +1503,7 @@ void phydm_dfs_histogram_radar_distinguish( dfs->pri_cond3 = 1; /*@Cancel the condition that the abs between pri and pw*/ - dfs->pri_cond4 = 1; + dfs->pri_cond4 = 1; if (dfs->pri_hold_sum[5] <= dfs->pri_sum_g5_th) dfs->pri_cond5 = 1; @@ -1725,12 +1557,6 @@ void phydm_dfs_histogram_radar_distinguish( dfs_pri_thd4 = (u8)odm_get_bb_reg(dm, 0x19ec, 0x00ff0000); dfs_pri_thd5 = (u8)odm_get_bb_reg(dm, 0x19ec, 0xff000000); - PHYDM_DBG(dm, DBG_DFS, "peak index hist\n"); - PHYDM_DBG(dm, DBG_DFS, "dfs_hist_peak_index=%x %x\n", - dfs_hist1_peak_index, dfs_hist2_peak_index); - PHYDM_DBG(dm, DBG_DFS, "g_peak_index_hist = "); - for (i = 0; i < 16; i++) - PHYDM_DBG(dm, DBG_DFS, " %x", g_peakindex[i]); PHYDM_DBG(dm, DBG_DFS, "\ndfs_pw_thd=%d %d %d %d %d\n", dfs_pw_thd1, dfs_pw_thd2, dfs_pw_thd3, dfs_pw_thd4, dfs_pw_thd5); @@ -1785,13 +1611,6 @@ void phydm_dfs_histogram_radar_distinguish( PHYDM_DBG(dm, DBG_DFS, "idle_mode = %d\n", dfs->idle_mode); PHYDM_DBG(dm, DBG_DFS, "pw_standard = %d\n", dfs->pw_std); PHYDM_DBG(dm, DBG_DFS, "pri_standard = %d\n", dfs->pri_std); - for (j = 0; j < 4; j++) { - for (i = 0; i < 6; i++) { - PHYDM_DBG(dm, DBG_DFS, "pri_hold = %d ", - dfs->pri_hold[j][i]); - } - PHYDM_DBG(dm, DBG_DFS, "\n"); - } PHYDM_DBG(dm, DBG_DFS, "\n"); PHYDM_DBG(dm, DBG_DFS, "pri_cond1 = %d, pri_cond2 = %d, pri_cond3 = %d, pri_cond4 = %d, pri_cond5 = %d\n", @@ -1803,7 +1622,7 @@ void phydm_dfs_histogram_radar_distinguish( safe_pri_pw_diff_th); } } - +#endif boolean phydm_dfs_hist_log(void *dm_void, u8 index) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -1949,22 +1768,6 @@ boolean phydm_dfs_hist_log(void *dm_void, u8 index) PHYDM_DBG(dm, DBG_DFS, "\n"); PHYDM_DBG(dm, DBG_DFS, "idle_mode = %d\n", dfs->idle_mode); - PHYDM_DBG(dm, DBG_DFS, - "long_radar_pw_hold_sum = %d %d %d %d %d %d\n", - dfs->pw_long_hold_sum[0], - dfs->pw_long_hold_sum[1], - dfs->pw_long_hold_sum[2], - dfs->pw_long_hold_sum[3], - dfs->pw_long_hold_sum[4], - dfs->pw_long_hold_sum[5]); - PHYDM_DBG(dm, DBG_DFS, - "long_radar_pri_hold_sum = %d %d %d %d %d %d\n", - dfs->pri_long_hold_sum[0], - dfs->pri_long_hold_sum[1], - dfs->pri_long_hold_sum[2], - dfs->pri_long_hold_sum[3], - dfs->pri_long_hold_sum[4], - dfs->pri_long_hold_sum[5]); } /* @Long radar should satisfy three conditions */ if (dfs->long_radar_flag == 1) { @@ -1993,7 +1796,6 @@ boolean phydm_radar_detect(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct _DFS_STATISTICS *dfs = &dm->dfs; - boolean enable_DFS = false; boolean radar_detected = false; if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { @@ -2032,38 +1834,18 @@ boolean phydm_radar_detect(void *dm_void) odm_set_bb_reg(dm, R_0x918, 0x00001f00, dfs->pwdb_th_cur); } - dfs->igi_pre = dfs->igi_cur; phydm_dfs_dynamic_setting(dm); + #if (RTL8814A_SUPPORT || RTL8822B_SUPPORT || RTL8821C_SUPPORT) if (dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8821C)) phydm_dfs_histogram_radar_distinguish(dm); + #endif radar_detected = phydm_radar_detect_dm_check(dm); - if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8822C | ODM_RTL8812F | - ODM_RTL8197G)) { - if (odm_get_bb_reg(dm, R_0xa40, BIT(15))) - enable_DFS = true; - #if (RTL8721D_SUPPORT) - } else if (dm->support_ic_type & (ODM_RTL8721D)) { - if (odm_get_bb_reg(dm, R_0xf58, BIT(29))) - enable_DFS = true; - #endif - } else if (dm->support_ic_type & (ODM_RTL8814B)) { - if (dm->seg1_dfs_flag == 1) { - if (odm_get_bb_reg(dm, R_0xa6c, BIT(15))) - enable_DFS = true; - } else if (odm_get_bb_reg(dm, R_0xa40, BIT(15))) - enable_DFS = true; - } else { - if (odm_get_bb_reg(dm, R_0x924, BIT(15))) - enable_DFS = true; - } - - if (enable_DFS && radar_detected) { + if (radar_detected) { PHYDM_DBG(dm, DBG_DFS, - "Radar detect: enable_DFS:%d, radar_detected:%d\n", - enable_DFS, radar_detected); + "Radar detect: %d\n", radar_detected); phydm_radar_detect_reset(dm); if (dfs->dbg_mode == 1) { PHYDM_DBG(dm, DBG_DFS, @@ -2072,13 +1854,13 @@ boolean phydm_radar_detect(void *dm_void) } } - if (enable_DFS && dfs->sw_trigger_mode == 1) { + if (dfs->sw_trigger_mode) { radar_detected = 1; PHYDM_DBG(dm, DBG_DFS, "Radar is detected in DFS SW trigger mode.\n"); } - return enable_DFS && radar_detected; + return radar_detected; } void phydm_dfs_hist_dbg(void *dm_void, char input[][16], u32 *_used, @@ -2087,7 +1869,7 @@ void phydm_dfs_hist_dbg(void *dm_void, char input[][16], u32 *_used, struct dm_struct *dm = (struct dm_struct *)dm_void; struct _DFS_STATISTICS *dfs = &dm->dfs; char help[] = "-h"; - u32 argv[30] = {0}; + u32 argv[5] = {0}; u32 used = *_used; u32 out_len = *_out_len; u8 i; @@ -2167,10 +1949,9 @@ void phydm_dfs_hist_dbg(void *dm_void, char input[][16], u32 *_used, } else { PHYDM_SSCANF(input[1], DCMD_DECIMAL, &argv[0]); - for (i = 1; i < 30; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, - &argv[i]); + for (i = 1; i < 5; i++) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &argv[i]); } if (argv[0] == 0) { dfs->pri_hist_th = (u8)argv[1]; @@ -2329,10 +2110,8 @@ void phydm_dfs_debug(void *dm_void, char input[][16], u32 *_used, u8 i, input_idx = 0; for (i = 0; i < 7; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &argv[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &argv[i]); + input_idx++; } if (input_idx == 0) @@ -2351,34 +2130,6 @@ void phydm_dfs_debug(void *dm_void, char input[][16], u32 *_used, dfs->dbg_mode, dfs->sw_trigger_mode, dfs->force_TP_mode, dfs->det_print, dfs->det_print2, dfs->print_hist_rpt, dfs->hist_cond_on); - - /*switch (argv[0]) { - case 1: -#if defined(CONFIG_PHYDM_DFS_MASTER) - set dbg parameters for radar detection instead of the default value - if (argv[1] == 1) { - dm->radar_detect_reg_918 = argv[2]; - dm->radar_detect_reg_91c = argv[3]; - dm->radar_detect_reg_920 = argv[4]; - dm->radar_detect_reg_924 = argv[5]; - dm->radar_detect_dbg_parm_en = 1; - - PDM_SNPF((output + used, out_len - used, "Radar detection with dbg parameter\n")); - PDM_SNPF((output + used, out_len - used, "reg918:0x%08X\n", dm->radar_detect_reg_918)); - PDM_SNPF((output + used, out_len - used, "reg91c:0x%08X\n", dm->radar_detect_reg_91c)); - PDM_SNPF((output + used, out_len - used, "reg920:0x%08X\n", dm->radar_detect_reg_920)); - PDM_SNPF((output + used, out_len - used, "reg924:0x%08X\n", dm->radar_detect_reg_924)); - } else { - dm->radar_detect_dbg_parm_en = 0; - PDM_SNPF((output + used, out_len - used, "Radar detection with default parameter\n")); - } - phydm_radar_detect_enable(dm); -#endif defined(CONFIG_PHYDM_DFS_MASTER) - - break; - default: - break; - }*/ } u8 phydm_dfs_polling_time(void *dm_void) diff --git a/hal/phydm/phydm_dfs.h b/hal/phydm/phydm_dfs.h index 7f201d2..fabc640 100644 --- a/hal/phydm/phydm_dfs.h +++ b/hal/phydm/phydm_dfs.h @@ -47,9 +47,6 @@ struct _DFS_STATISTICS { u8 st_l2h_cur; u16 fa_count_pre; u16 fa_inc_hist[5]; - u16 vht_crc_ok_cnt_pre; - u16 ht_crc_ok_cnt_pre; - u16 leg_crc_ok_cnt_pre; u16 short_pulse_cnt_pre; u16 long_pulse_cnt_pre; u8 pwdb_th; @@ -62,10 +59,10 @@ struct _DFS_STATISTICS { u8 three_peak_opt; u8 three_peak_th2; u8 fa_mask_th; - u8 det_flag_offset; u8 st_l2h_max; u8 st_l2h_min; - u8 mask_hist_checked; + u8 dfs_polling_time; + u8 mask_hist_checked : 3; boolean pulse_flag_hist[5]; boolean pulse_type_hist[5]; boolean radar_det_mask_hist[5]; @@ -76,10 +73,9 @@ struct _DFS_STATISTICS { boolean det_print; boolean det_print2; boolean radar_type; - u8 dfs_polling_time; - /*@dfs histogram*/ boolean print_hist_rpt; boolean hist_cond_on; + /*@dfs histogram*/ boolean pri_cond1; boolean pri_cond2; boolean pri_cond3; @@ -97,47 +93,45 @@ struct _DFS_STATISTICS { boolean pri_flag; boolean pri_type3_4_flag; /*@for ETSI*/ boolean long_radar_flag; - u16 pri_hold_sum[6]; - u16 pw_hold_sum[6]; - u16 pri_long_hold_sum[6]; - u16 pw_long_hold_sum[6]; + u8 pri_hold_sum[6]; + u8 pw_hold_sum[6]; + u8 pri_long_hold_sum[6]; + u8 pw_long_hold_sum[6]; u8 hist_idx; u8 hist_long_idx; u8 pw_hold[4][6]; u8 pri_hold[4][6]; - u8 pw_long_hold[300][6]; - u8 pri_long_hold[300][6]; - u16 pw_std; /*@The std(var) of reasonable num of pw group*/ - u16 pri_std;/*@The std(var) of reasonable num of pri group*/ + u8 pw_std; /*@The std(var) of reasonable num of pw group*/ + u8 pri_std;/*@The std(var) of reasonable num of pri group*/ /*@dfs histogram threshold*/ - u8 pri_hist_th; - u8 pri_sum_g1_th; - u8 pri_sum_g5_th; - u8 pri_sum_g1_fcc_th; - u8 pri_sum_g3_fcc_th; - u8 pri_sum_safe_fcc_th; - u8 pri_sum_type4_th; - u8 pri_sum_type6_th; - u8 pri_sum_safe_th; - u8 pri_sum_g5_under_g1_th; - u8 pri_pw_diff_th; - u8 pri_pw_diff_fcc_th; - u8 pri_pw_diff_fcc_idle_th; - u8 pri_pw_diff_w53_th; - u8 pri_type1_low_fcc_th; - u8 pri_type1_upp_fcc_th; - u8 pri_type1_cen_fcc_th; - u8 pw_g0_th; - u8 pw_long_lower_20m_th; - u8 pw_long_lower_th; - u8 pri_long_upper_th; - u8 pw_long_sum_upper_th; - u8 pw_std_th; - u8 pw_std_idle_th; - u8 pri_std_th; - u8 pri_std_idle_th; - u8 type4_pw_max_cnt; - u8 type4_safe_pri_sum_th; + u8 pri_hist_th : 3; + u8 pri_sum_g1_th : 4; + u8 pri_sum_g5_th : 4; + u8 pri_sum_g1_fcc_th : 3; + u8 pri_sum_g3_fcc_th : 3; + u8 pri_sum_safe_fcc_th : 7; + u8 pri_sum_type4_th : 5; + u8 pri_sum_type6_th : 5; + u8 pri_sum_safe_th : 6; + u8 pri_sum_g5_under_g1_th : 3; + u8 pri_pw_diff_th : 3; + u8 pri_pw_diff_fcc_th : 4; + u8 pri_pw_diff_fcc_idle_th : 2; + u8 pri_pw_diff_w53_th : 4; + u8 pri_type1_low_fcc_th : 7; + u8 pri_type1_upp_fcc_th : 7; + u8 pri_type1_cen_fcc_th : 7; + u8 pw_g0_th : 4; + u8 pw_long_lower_20m_th : 4; + u8 pw_long_lower_th : 3; + u8 pri_long_upper_th : 6; + u8 pw_long_sum_upper_th : 7; + u8 pw_std_th : 4; + u8 pw_std_idle_th : 4; + u8 pri_std_th : 4; + u8 pri_std_idle_th : 4; + u8 type4_pw_max_cnt : 4; + u8 type4_safe_pri_sum_th : 3; }; /*@ diff --git a/hal/phydm/phydm_dig.c b/hal/phydm/phydm_dig.c index 5826edf..59637b3 100644 --- a/hal/phydm/phydm_dig.c +++ b/hal/phydm/phydm_dig.c @@ -44,7 +44,7 @@ void phydm_dig_recorder_reset(void *dm_void) } void phydm_dig_recorder(void *dm_void, u8 igi_curr, - u32 fa_cnt) + u32 fa_metrics) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_dig_struct *dig_t = &dm->dm_dig_table; @@ -60,7 +60,7 @@ void phydm_dig_recorder(void *dm_void, u8 igi_curr, if (dm->first_connect) { phydm_dig_recorder_reset(dm); dig_rc->igi_history[0] = igi_curr; - dig_rc->fa_history[0] = fa_cnt; + dig_rc->fa_history[0] = fa_metrics; return; } @@ -79,7 +79,7 @@ void phydm_dig_recorder(void *dm_void, u8 igi_curr, dig_rc->fa_history[3] = dig_rc->fa_history[2]; dig_rc->fa_history[2] = dig_rc->fa_history[1]; dig_rc->fa_history[1] = dig_rc->fa_history[0]; - dig_rc->fa_history[0] = fa_cnt; + dig_rc->fa_history[0] = fa_metrics; PHYDM_DBG(dm, DBG_DIG, "igi_history[3:0] = {0x%x, 0x%x, 0x%x, 0x%x}\n", dig_rc->igi_history[3], dig_rc->igi_history[2], @@ -195,86 +195,13 @@ void phydm_dig_damping_chk(void *dm_void) } #endif -boolean -phydm_dig_go_up_check(void *dm_void) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct ccx_info *ccx_info = &dm->dm_ccx_info; - struct phydm_dig_struct *dig_t = &dm->dm_dig_table; - u8 cur_ig_value = dig_t->cur_ig_value; - u8 max_cover_bond = 0; - u8 rx_gain_range_max = dig_t->rx_gain_range_max; - u8 i = 0, j = 0; - u8 total_nhm_cnt = ccx_info->nhm_rpt_sum; - u32 dig_cnt = 0; - u32 over_dig_cnt = 0; - boolean ret = true; - - if (*dm->bb_op_mode == PHYDM_PERFORMANCE_MODE) - return ret; - - max_cover_bond = DIG_MAX_BALANCE_MODE - dig_t->upcheck_init_val; - - if (cur_ig_value < max_cover_bond - 6) - dig_t->go_up_chk_lv = DIG_GOUPCHECK_LEVEL_0; - else if (cur_ig_value <= DIG_MAX_BALANCE_MODE) - dig_t->go_up_chk_lv = DIG_GOUPCHECK_LEVEL_1; - else /* @cur_ig_value > DM_DIG_MAX_AP, foolproof */ - dig_t->go_up_chk_lv = DIG_GOUPCHECK_LEVEL_2; - - PHYDM_DBG(dm, DBG_DIG, "check_lv = %d, max_cover_bond = 0x%x\n", - dig_t->go_up_chk_lv, max_cover_bond); - - if (total_nhm_cnt == 0) - return true; - - if (dig_t->go_up_chk_lv == DIG_GOUPCHECK_LEVEL_0) { - for (i = 3; i <= 11; i++) - dig_cnt += ccx_info->nhm_result[i]; - - if ((dig_t->lv0_ratio_reciprocal * dig_cnt) >= total_nhm_cnt) - ret = true; - else - ret = false; - - } else if (dig_t->go_up_chk_lv == DIG_GOUPCHECK_LEVEL_1) { - /* search index */ - for (i = 0; i <= 10; i++) { - if ((max_cover_bond * 2) == ccx_info->nhm_th[i]) { - for (j = (i + 1); j <= 11; j++) - over_dig_cnt += ccx_info->nhm_result[j]; - break; - } - } - - if (dig_t->lv1_ratio_reciprocal * over_dig_cnt < total_nhm_cnt) - ret = true; - else - ret = false; - - if (!ret) { - /* update dig_t->rx_gain_range_max */ - if (rx_gain_range_max + 6 >= max_cover_bond) - dig_t->rx_gain_range_max = max_cover_bond - 6; - else - dig_t->rx_gain_range_max = rx_gain_range_max; - - PHYDM_DBG(dm, DBG_DIG, - "Noise pwr over DIG can filter, lock rx_gain_range_max to 0x%x\n", - dig_t->rx_gain_range_max); - } - } else if (dig_t->go_up_chk_lv == DIG_GOUPCHECK_LEVEL_2) { - /* @cur_ig_value > DM_DIG_MAX_AP, foolproof */ - ret = true; - } - - return ret; -} - void phydm_fa_threshold_check(void *dm_void, boolean is_dfs_band) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_dig_struct *dig_t = &dm->dm_dig_table; + u8 i = 0; + + dig_t->dm_dig_fa_th1 = DM_DIG_FA_TH1; if (dig_t->is_dbg_fa_th) { PHYDM_DBG(dm, DBG_DIG, "Manual Fix FA_th\n"); @@ -306,6 +233,13 @@ void phydm_fa_threshold_check(void *dm_void, boolean is_dfs_band) } } + if ((dig_t->fa_source >= 1) && (dig_t->fa_source <= 3)) { + for (i = 0; i < 3; i++) + dig_t->fa_th[i] *= OFDM_FA_EXP_DURATION; + + dig_t->dm_dig_fa_th1 *= OFDM_FA_EXP_DURATION; + } + PHYDM_DBG(dm, DBG_DIG, "FA_th={%d,%d,%d}\n", dig_t->fa_th[0], dig_t->fa_th[1], dig_t->fa_th[2]); } @@ -404,14 +338,16 @@ void phydm_fa_cnt_statistics_jgr3(void *dm_void) struct phydm_fa_struct *fa_t = &dm->false_alm_cnt; u32 ret_value = 0; u32 cck_enable = 0; - u16 ofdm_tx_counter = 0; - u16 cck_tx_counter = 0; if (!(dm->support_ic_type & ODM_IC_JGR3_SERIES)) return; - ofdm_tx_counter = (u16)odm_get_bb_reg(dm, R_0x2de0, MASKLWORD); - cck_tx_counter = (u16)odm_get_bb_reg(dm, R_0x2de4, MASKLWORD); + ret_value = odm_get_bb_reg(dm, R_0x2de4, MASKDWORD); + fa_t->cnt_cck_txen = (ret_value & 0xffff); + fa_t->cnt_cck_txon = ((ret_value & 0xffff0000) >> 16); + ret_value = odm_get_bb_reg(dm, R_0x2de0, MASKDWORD); + fa_t->cnt_ofdm_txen = (ret_value & 0xffff); + fa_t->cnt_ofdm_txon = ((ret_value & 0xffff0000) >> 16); ret_value = odm_get_bb_reg(dm, R_0x2d20, MASKDWORD); fa_t->cnt_fast_fsync = ret_value & 0xffff; @@ -428,7 +364,10 @@ void phydm_fa_cnt_statistics_jgr3(void *dm_void) fa_t->cnt_mcs_fail = ret_value & 0xffff; /* read CCK CRC32 counter */ - ret_value = odm_get_bb_reg(dm, R_0x2c04, MASKDWORD); + if (dm->support_ic_type & ODM_RTL8723F) + ret_value = odm_get_bb_reg(dm, R_0x2aac, MASKDWORD); + else + ret_value = odm_get_bb_reg(dm, R_0x2c04, MASKDWORD); fa_t->cnt_cck_crc32_ok = ret_value & 0xffff; fa_t->cnt_cck_crc32_error = (ret_value & 0xffff0000) >> 16; @@ -437,19 +376,34 @@ void phydm_fa_cnt_statistics_jgr3(void *dm_void) fa_t->cnt_ofdm_crc32_ok = ret_value & 0xffff; fa_t->cnt_ofdm_crc32_error = (ret_value & 0xffff0000) >> 16; + /* read OFDM2 CRC32 counter */ + ret_value = odm_get_bb_reg(dm, R_0x2c1c, MASKDWORD); + fa_t->cnt_ofdm2_crc32_ok = ret_value & 0xffff; + fa_t->cnt_ofdm2_crc32_error = (ret_value & 0xffff0000) >> 16; + /* read HT CRC32 counter */ ret_value = odm_get_bb_reg(dm, R_0x2c10, MASKDWORD); fa_t->cnt_ht_crc32_ok = ret_value & 0xffff; fa_t->cnt_ht_crc32_error = (ret_value & 0xffff0000) >> 16; - /* @for VHT part */ + /* read HT2 CRC32 counter */ + ret_value = odm_get_bb_reg(dm, R_0x2c18, MASKDWORD); + fa_t->cnt_ht2_crc32_ok = ret_value & 0xffff; + fa_t->cnt_ht2_crc32_error = (ret_value & 0xffff0000) >> 16; + + /*for VHT part */ if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8812F | ODM_RTL8814B)) { - /* @read VHT CRC32 counter */ + /*read VHT CRC32 counter */ ret_value = odm_get_bb_reg(dm, R_0x2c0c, MASKDWORD); fa_t->cnt_vht_crc32_ok = ret_value & 0xffff; fa_t->cnt_vht_crc32_error = (ret_value & 0xffff0000) >> 16; + /*read VHT2 CRC32 counter */ + ret_value = odm_get_bb_reg(dm, R_0x2c54, MASKDWORD); + fa_t->cnt_vht2_crc32_ok = ret_value & 0xffff; + fa_t->cnt_vht2_crc32_error = (ret_value & 0xffff0000) >> 16; + ret_value = odm_get_bb_reg(dm, R_0x2d10, MASKDWORD); fa_t->cnt_mcs_fail_vht = (ret_value & 0xffff0000) >> 16; @@ -459,6 +413,8 @@ void phydm_fa_cnt_statistics_jgr3(void *dm_void) } else { fa_t->cnt_vht_crc32_error = 0; fa_t->cnt_vht_crc32_ok = 0; + fa_t->cnt_vht2_crc32_error = 0; + fa_t->cnt_vht2_crc32_ok = 0; fa_t->cnt_mcs_fail_vht = 0; fa_t->cnt_crc8_fail_vhta = 0; fa_t->cnt_crc8_fail_vhtb = 0; @@ -471,32 +427,33 @@ void phydm_fa_cnt_statistics_jgr3(void *dm_void) fa_t->cnt_mcs_fail_vht + fa_t->cnt_crc8_fail_vhta; /* Read CCK FA counter */ - fa_t->cnt_cck_fail = odm_get_bb_reg(dm, R_0x1a5c, MASKLWORD); + if (dm->support_ic_type & ODM_RTL8723F){ + ret_value= odm_get_bb_reg(dm, R_0x2aa8, MASKLWORD); + fa_t->cnt_cck_fail=(ret_value&0xffff)+((ret_value&0xffff0000)>>16); + } + else + fa_t->cnt_cck_fail = odm_get_bb_reg(dm, R_0x1a5c, MASKLWORD); /* read CCK/OFDM CCA counter */ ret_value = odm_get_bb_reg(dm, R_0x2c08, MASKDWORD); fa_t->cnt_ofdm_cca = ((ret_value & 0xffff0000) >> 16); + if (dm->support_ic_type & ODM_RTL8723F) + ret_value = odm_get_bb_reg(dm, R_0x2aa0, MASKDWORD); fa_t->cnt_cck_cca = ret_value & 0xffff; /* @CCK RxIQ weighting = 1 => 0x1a14[9:8]=0x0 */ - cck_enable = odm_get_bb_reg(dm, R_0x1a14, 0x300); + if (dm->support_ic_type & ODM_RTL8723F) + cck_enable = odm_get_bb_reg(dm, R_0x2a24, BIT(13)); + else + cck_enable = odm_get_bb_reg(dm, R_0x1a14, 0x300); + if (cck_enable == 0x0) { /* @if(*dm->band_type == ODM_BAND_2_4G) */ fa_t->cnt_all = fa_t->cnt_ofdm_fail + fa_t->cnt_cck_fail; fa_t->cnt_cca_all = fa_t->cnt_cck_cca + fa_t->cnt_ofdm_cca; - PHYDM_DBG(dm, DBG_FA_CNT, "ac3 OFDM FA = %d, CCK FA = %d\n", - fa_t->cnt_ofdm_fail, fa_t->cnt_cck_fail); } else { fa_t->cnt_all = fa_t->cnt_ofdm_fail; fa_t->cnt_cca_all = fa_t->cnt_ofdm_cca; - PHYDM_DBG(dm, DBG_FA_CNT, "ac3 CCK disable OFDM FA = %d\n", - fa_t->cnt_ofdm_fail); } - - PHYDM_DBG(dm, DBG_FA_CNT, - "ac3 [OFDM FA Detail] Parity_fail=((%d)), Rate_Illegal=((%d)), CRC8_fail=((%d)), Mcs_fail=((%d)), Fast_Fsync=((%d)), SBD_fail=((%d))\n", - fa_t->cnt_parity_fail, fa_t->cnt_rate_illegal, - fa_t->cnt_crc8_fail, fa_t->cnt_mcs_fail, fa_t->cnt_fast_fsync, - fa_t->cnt_sb_search_fail); } #endif @@ -555,6 +512,16 @@ void phydm_write_dig_reg(void *dm_void, u8 igi) } #endif + if (igi == dig_t->cur_ig_value) + dig_t->igi_trend = DIG_STABLE; + else if (igi > dig_t->cur_ig_value) + dig_t->igi_trend = DIG_INCREASING; + else + dig_t->igi_trend = DIG_DECREASING; + + PHYDM_DBG(dm, DBG_DIG, "Update IGI:0x%x -> 0x%x\n", + dig_t->cur_ig_value, igi); + dig_t->cur_ig_value = igi; } @@ -601,23 +568,29 @@ void odm_write_dig(void *dm_void, u8 new_igi) #endif /*@Add by YuChen for USB IO too slow issue*/ - if (!(dm->support_ic_type & ODM_IC_PWDB_EDCCA)) { - if (*dm->edcca_mode == PHYDM_EDCCA_ADAPT_MODE && - new_igi < dig_t->cur_ig_value) { - dig_t->cur_ig_value = new_igi; - phydm_adaptivity(dm); - } - } else { - if (*dm->edcca_mode == PHYDM_EDCCA_ADAPT_MODE && - new_igi > dig_t->cur_ig_value) { - dig_t->cur_ig_value = new_igi; - phydm_adaptivity(dm); + if (*dm->edcca_mode == PHYDM_EDCCA_ADAPT_MODE) { + if (!(dm->support_ic_type & ODM_IC_PWDB_EDCCA)) { + if (new_igi < dig_t->cur_ig_value || + dm->is_pause_dig) { + dig_t->cur_ig_value = new_igi; + phydm_adaptivity(dm); + } + } else { + if (new_igi > dig_t->cur_ig_value) { + dig_t->cur_ig_value = new_igi; + phydm_adaptivity(dm); + } } } phydm_write_dig_reg(dm, new_igi); + } else { + dig_t->igi_trend = DIG_STABLE; } - PHYDM_DBG(dm, DBG_DIG, "New_igi=((0x%x))\n\n", new_igi); + PHYDM_DBG(dm, DBG_DIG, "[%s]New_igi=((0x%x))\n\n", + ((dig_t->igi_trend == DIG_STABLE) ? "=" : + ((dig_t->igi_trend == DIG_INCREASING) ? "+" : "-")), + new_igi); } u8 phydm_get_igi_reg_val(void *dm_void, enum bb_path path) @@ -695,12 +668,14 @@ void odm_pause_dig(void *dm_void, enum phydm_pause_type type, switch (type) { case PHYDM_PAUSE: case PHYDM_PAUSE_NO_SET: { + dm->is_pause_dig = true; rpt = phydm_pause_func(dm, F00_DIG, PHYDM_PAUSE, lv, 1, &igi); break; } case PHYDM_RESUME: { rpt = phydm_pause_func(dm, F00_DIG, PHYDM_RESUME, lv, 1, &igi); + dm->is_pause_dig = false; break; } default: @@ -737,6 +712,11 @@ phydm_dig_abort(void *dm_void) return true; } + if (dm->dm_dig_table.fw_dig_enable) { + PHYDM_DBG(dm, DBG_DIG, "Return: FW DIG enable\n"); + return true; + } + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) #if OS_WIN_FROM_WIN7(OS_VERSION) if (IsAPModeExist(adapter) && ((PADAPTER)(adapter))->bInHctTest) { @@ -749,6 +729,274 @@ phydm_dig_abort(void *dm_void) return false; } +#ifdef PHYDM_HW_IGI +#ifdef BB_RAM_SUPPORT +void phydm_rd_hwigi_pre_setting(void *dm_void, u32 *_used, char *output, + u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 used = *_used; + u32 out_len = *_out_len; + u8 igi_ofst = 0x0; + u32 t1, t2, t3 = 0x0; + + igi_ofst = (u8)odm_get_bb_reg(dm, R_0x1e80, MASKBYTE0); + t1 = odm_get_bb_reg(dm, R_0x1e80, MASKBYTE1) * 400; + t2 = odm_get_bb_reg(dm, R_0x1e80, MASKBYTE2) * 400; + t3 = odm_get_bb_reg(dm, R_0x1e80, MASKBYTE3) * 400; + + PDM_SNPF(out_len, used, output + used, out_len - used, + "igi_offset:0x%x, t1:%d(ns), t2:%d(ns), t3:%d(ns)\n", + igi_ofst, t1, t2, t3); +} + +void phydm_set_hwigi_pre_setting(void *dm_void, u8 igi_ofst, u8 t1, u8 t2, + u8 t3) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 reg_0x1e80 = 0; + + reg_0x1e80 = igi_ofst + (t1 << 8) + (t2 << 16) + (t3 << 24); + odm_set_bb_reg(dm, R_0x1e80, MASKDWORD, reg_0x1e80); +} + +void phydm_rd_hwigi_table(void *dm_void, u8 macid, u32 *_used, char *output, + u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 used = *_used; + u32 out_len = *_out_len; + boolean hwigi_en = false; + u8 hwigi = 0x0; + u8 hwigi_rx_offset = 0x0; + u32 reg_0x1e84 = 0x0; + + reg_0x1e84 |= (macid & 0x3f) << 24; /*macid*/ + reg_0x1e84 |= BIT(31); /*read_en*/ + odm_set_bb_reg(dm, R_0x1e84, MASKDWORD, reg_0x1e84); + + hwigi_en = (boolean)odm_get_bb_reg(dm, R_0x2de8, BIT(15)); + hwigi = (u8)odm_get_bb_reg(dm, R_0x2de8, 0x7f00); + odm_set_bb_reg(dm, R_0x1e84, MASKDWORD, 0x0); /* disable rd/wt*/ + + PDM_SNPF(out_len, used, output + used, out_len - used, + "(macid:%d) hwigi_en:%d, hwigi:0x%x\n", macid, hwigi_en, + hwigi); + + *_used = used; + *_out_len = out_len; +} + +void phydm_wt_hwigi_table(void *dm_void, u8 macid, boolean hwigi_en, u8 hwigi) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_bb_ram_per_sta *dm_ram_per_sta = NULL; + u32 reg_0x1e84 = 0; + + if (macid > 63) + macid = 63; + + dm_ram_per_sta = &dm->p_bb_ram_ctrl.pram_sta_ctrl[macid]; + dm_ram_per_sta->hw_igi_en = hwigi_en; + dm_ram_per_sta->hw_igi = hwigi; + + reg_0x1e84 = (dm_ram_per_sta->tx_pwr_offset0_en << 15) + + ((dm_ram_per_sta->tx_pwr_offset0 & 0x7f) << 8) + + (dm_ram_per_sta->tx_pwr_offset1_en << 23) + + ((dm_ram_per_sta->tx_pwr_offset1 & 0x7f) << 16); + + reg_0x1e84 |= (hwigi_en << 7) + (hwigi & 0x7f); + reg_0x1e84 |= (macid & 0x3f) << 24;/*macid*/ + reg_0x1e84 |= BIT(30); /*write_en*/ + odm_set_bb_reg(dm, R_0x1e84, MASKDWORD, reg_0x1e84); + odm_set_bb_reg(dm, R_0x1e84, MASKDWORD, 0x80000000); /*read_en*/ + odm_set_bb_reg(dm, R_0x1e84, MASKDWORD, 0x0); /*disable rd/wt*/ +} + +void phydm_rst_hwigi(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_bb_ram_per_sta *dm_ram_per_sta = NULL; + u32 reg_0x1e84 = 0; + u8 i = 0; + + PHYDM_DBG(dm, DBG_DIG, "reset hwigi!\n"); + + for (i = 0; i < 64; i++) { + dm_ram_per_sta = &dm->p_bb_ram_ctrl.pram_sta_ctrl[i]; + dm_ram_per_sta->hw_igi_en = false; + dm_ram_per_sta->hw_igi = 0x0; + + reg_0x1e84 = (dm_ram_per_sta->tx_pwr_offset0_en << 15) + + ((dm_ram_per_sta->tx_pwr_offset0 & 0x7f) << 8) + + (dm_ram_per_sta->tx_pwr_offset1_en << 23) + + ((dm_ram_per_sta->tx_pwr_offset1 & 0x7f) << 16); + + reg_0x1e84 |= (i & 0x3f) << 24; + reg_0x1e84 |= BIT(30); + odm_set_bb_reg(dm, R_0x1e84, MASKDWORD, reg_0x1e84); + } + + odm_set_bb_reg(dm, R_0x1e84, MASKDWORD, 0x80000000); + odm_set_bb_reg(dm, R_0x1e84, MASKDWORD, 0x0); +} + +void phydm_hwigi_init(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_bb_ram_ctrl *bb_ctrl = &dm->p_bb_ram_ctrl; + u8 igi_ofst = 0x0; + u8 t1 = 0x0; + u8 t2 = 0x0; + u8 t3 = 0x0; + + t1 = 0x55; /*34 us*/ + t3 = 0x55; /*34 us*/ + + bb_ctrl->hwigi_watchdog_en = false; + phydm_set_hwigi_pre_setting(dm, igi_ofst, t1, t2, t3); +} + +void phydm_hwigi(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct cmn_sta_info *sta = NULL; + struct phydm_bb_ram_per_sta *dm_ram_per_sta = NULL; + struct rssi_info *rssi = NULL; + struct phydm_dig_struct *dig_t = &dm->dm_dig_table; + struct phydm_bb_ram_ctrl *bb_ctrl = &dm->p_bb_ram_ctrl; + u8 sta_cnt = 0; + u8 i = 0; + u8 hwigi = 0x0; + u8 macid = 0; + u8 macid_cnt = 0; + u64 macid_cur = 0; + u64 macid_diff = 0; + u64 macid_mask = 0; + + if (!(bb_ctrl->hwigi_watchdog_en)) { + return; + } + + for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { + sta = dm->phydm_sta_info[i]; + if (is_sta_active(sta)) { + sta_cnt++; + + if (sta->mac_id > 63) + macid = 63; + else + macid = sta->mac_id; + + dm_ram_per_sta = &bb_ctrl->pram_sta_ctrl[macid]; + rssi = &sta->rssi_stat; + macid_mask = (u64)BIT(sta->mac_id); + bb_ctrl->hwigi_macid_is_linked |= macid_mask; + macid_cur |= macid_mask; + PHYDM_DBG(dm, DBG_DIG, + "STA_id=%d, MACID=%d, RSSI=%d, hwigi_en=%d, hwigi=0x%x\n", + i, sta->mac_id, rssi->rssi, + dm_ram_per_sta->hw_igi_en, + dm_ram_per_sta->hw_igi); + + hwigi = MAX_2((u8)(rssi->rssi + 10), + dig_t->cur_ig_value); + + if (hwigi > DIG_MAX_PERFORMANCE_MODE) + hwigi = DIG_MAX_PERFORMANCE_MODE; + else if (hwigi < DIG_MIN_PERFORMANCE) + hwigi = DIG_MIN_PERFORMANCE; + + if (dm_ram_per_sta->hw_igi == hwigi) { + PHYDM_DBG(dm, DBG_DIG, + "hwigi not change!\n"); + } else { + + PHYDM_DBG(dm, DBG_DIG, + "hwigi update: ((0x%x)) -> ((0x%x))\n", + dm_ram_per_sta->hw_igi, hwigi); + + phydm_wt_hwigi_table(dm, sta->mac_id, true, hwigi); + } + + if (sta_cnt == dm->number_linked_client) + break; + } + } + macid_diff = bb_ctrl->hwigi_macid_is_linked ^ macid_cur; + if (macid_diff) + bb_ctrl->hwigi_macid_is_linked &= ~macid_diff; + while (macid_diff) { + if (macid_diff & 0x1) + phydm_wt_hwigi_table(dm, macid_cnt, false, 0x0); + macid_cnt++; + macid_diff >>= 1; + } +} + +void phydm_hwigi_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_bb_ram_ctrl *bb_ctrl = &dm->p_bb_ram_ctrl; + char help[] = "-h"; + u32 used = *_used; + u32 out_len = *_out_len; + u32 var1[7] = {0}; + u8 i = 0; + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "Disable/Enable watchdog : {0/1}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Set hwigi pre-setting: {2} {IGI offset} {T1(after data tx)} {T2(after Rx)} {T3(after rsp tx)}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Set hwigi table: {3} {en} {value} {macid}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Read hwigi : {4} {macid(0~63), 255:all}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Reset all hwigi : {5}\n"); + } else { + for (i = 0; i < 7; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + } + switch (var1[0]) { + case 0: + case 1: + bb_ctrl->hwigi_watchdog_en = (var1[0]) ? true : false; + break; + case 2: + phydm_set_hwigi_pre_setting(dm, (u8)var1[1], + (u8)var1[2], (u8)var1[3], + (u8)var1[4]); + break; + case 3: + phydm_wt_hwigi_table(dm, (u8)var1[3], (boolean)var1[1], + (boolean)var1[2]); + break; + case 4: + phydm_rd_hwigi_pre_setting(dm, &used, output, &out_len); + if ((u8)var1[1] == 0xff) + for (i = 0; i < 64; i++) + phydm_rd_hwigi_table(dm, i, &used, + output, &out_len); + else + phydm_rd_hwigi_table(dm, (u8)var1[1], &used, + output, &out_len); + break; + case 5: + phydm_rst_hwigi(dm); + break; + } + } + *_used = used; + *_out_len = out_len; +} +#endif +#endif + void phydm_dig_init(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -768,7 +1016,12 @@ void phydm_dig_init(void *dm_void) dig_t->fa_th[0] = 250; dig_t->fa_th[1] = 500; dig_t->fa_th[2] = 750; + dig_t->dm_dig_fa_th1 = DM_DIG_FA_TH1; dig_t->is_dbg_fa_th = false; + dig_t->igi_dyn_up_hit = false; + dig_t->fw_dig_enable = false; + dig_t->fa_source = 0; + #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) /* @For RTL8881A */ false_alm_cnt->cnt_ofdm_fail_pre = 0; @@ -778,18 +1031,19 @@ void phydm_dig_init(void *dm_void) dig_t->rx_gain_range_min = dig_t->cur_ig_value; #if (RTL8822B_SUPPORT || RTL8197F_SUPPORT || RTL8192F_SUPPORT) - dig_t->enable_adjust_big_jump = 1; - if (dm->support_ic_type & ODM_RTL8822B) - ret_value = odm_get_bb_reg(dm, R_0x8c8, MASKLWORD); - else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8192F)) - ret_value = odm_get_bb_reg(dm, R_0xc74, MASKLWORD); - - dig_t->big_jump_step1 = (u8)(ret_value & 0xe) >> 1; - dig_t->big_jump_step2 = (u8)(ret_value & 0x30) >> 4; - dig_t->big_jump_step3 = (u8)(ret_value & 0xc0) >> 6; - if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8192F)) { + dig_t->enable_adjust_big_jump = 1; + + if (dm->support_ic_type & ODM_RTL8822B) + ret_value = odm_get_bb_reg(dm, R_0x8c8, MASKLWORD); + else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8192F)) + ret_value = odm_get_bb_reg(dm, R_0xc74, MASKLWORD); + + dig_t->big_jump_step1 = (u8)(ret_value & 0xe) >> 1; + dig_t->big_jump_step2 = (u8)(ret_value & 0x30) >> 4; + dig_t->big_jump_step3 = (u8)(ret_value & 0xc0) >> 6; + for (i = 0; i < sizeof(dig_t->big_jump_lmt); i++) { if (dig_t->big_jump_lmt[i] == 0) dig_t->big_jump_lmt[i] = 0x64; @@ -804,28 +1058,43 @@ void phydm_dig_init(void *dm_void) dm->tdma_dig_state_number = DIG_NUM_OF_TDMA_STATES; dm->tdma_dig_timer_ms = DIG_TIMER_MS; #endif + dig_t->tdma_force_l_igi = 0xff; + dig_t->tdma_force_h_igi = 0xff; #endif #ifdef CFG_DIG_DAMPING_CHK phydm_dig_recorder_reset(dm); dig_t->dig_dl_en = 1; #endif + +#ifdef PHYDM_HW_IGI + phydm_hwigi_init(dm); +#endif } void phydm_dig_abs_boundary_decision(struct dm_struct *dm, boolean is_dfs_band) { struct phydm_dig_struct *dig_t = &dm->dm_dig_table; struct phydm_adaptivity_struct *adapt = &dm->adaptivity; - if (!dm->is_linked) { - dig_t->dm_dig_max = DIG_MAX_COVERAGR; - dig_t->dm_dig_min = DIG_MIN_COVERAGE; - } else if (is_dfs_band) { - if (*dm->band_width == CHANNEL_WIDTH_20) - dig_t->dm_dig_min = DIG_MIN_DFS + 2; + if (is_dfs_band) { + if (*dm->band_width == CHANNEL_WIDTH_20){ + if (dm->support_ic_type & + (ODM_RTL8814A | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8822B)){ + if (odm_get_bb_reg(dm, R_0x8d8, BIT(27)) == 1) + dig_t->dm_dig_min = DIG_MIN_DFS + 2; + else + dig_t->dm_dig_min = DIG_MIN_DFS; + } + else + dig_t->dm_dig_min = DIG_MIN_DFS; + } else dig_t->dm_dig_min = DIG_MIN_DFS; - dig_t->dig_max_of_min = DIG_MAX_OF_MIN_BALANCE_MODE; + dig_t->dig_max_of_min = DIG_MIN_DFS; dig_t->dm_dig_max = DIG_MAX_BALANCE_MODE; + } else if (!dm->is_linked) { + dig_t->dm_dig_max = DIG_MAX_COVERAGR; + dig_t->dm_dig_min = DIG_MIN_COVERAGE; } else { if (*dm->bb_op_mode == PHYDM_BALANCE_MODE) { /*service > 2 devices*/ @@ -862,7 +1131,7 @@ void phydm_dig_abs_boundary_decision(struct dm_struct *dm, boolean is_dfs_band) dig_t->dm_dig_max, dig_t->dm_dig_min, dig_t->dig_max_of_min); } -void phydm_dig_dym_boundary_decision(struct dm_struct *dm) +void phydm_dig_dym_boundary_decision(struct dm_struct *dm, boolean is_dfs_band) { struct phydm_dig_struct *dig_t = &dm->dm_dig_table; #ifdef CFG_DIG_DAMPING_CHK @@ -886,7 +1155,9 @@ void phydm_dig_dym_boundary_decision(struct dm_struct *dm) PHYDM_DBG(dm, DBG_DIG, "rssi_min=%d, ofst=%d\n", dm->rssi_min, offset); /* @DIG lower bound */ - if (dm->rssi_min > dig_t->dig_max_of_min) + if (is_dfs_band) + dig_t->rx_gain_range_min = dig_t->dm_dig_min; + else if (dm->rssi_min > dig_t->dig_max_of_min) dig_t->rx_gain_range_min = dig_t->dig_max_of_min; else if (dm->rssi_min < dig_t->dm_dig_min) dig_t->rx_gain_range_min = dig_t->dm_dig_min; @@ -953,26 +1224,22 @@ void phydm_dig_abnormal_case(struct dm_struct *dm) dig_t->rx_gain_range_max, dig_t->rx_gain_range_min); } -u8 phydm_new_igi_by_fa(struct dm_struct *dm, u8 igi, u32 fa_cnt, u8 *step_size) +u8 phydm_new_igi_by_fa(struct dm_struct *dm, u8 igi, u32 fa_metrics, + u8 *step_size) { - boolean dig_go_up_check = true; struct phydm_dig_struct *dig_t = &dm->dm_dig_table; -#if 0 - /*@dig_go_up_check = phydm_dig_go_up_check(dm);*/ -#endif - - if (fa_cnt > dig_t->fa_th[2] && dig_go_up_check) + if (fa_metrics > dig_t->fa_th[2]) igi = igi + step_size[0]; - else if ((fa_cnt > dig_t->fa_th[1]) && dig_go_up_check) + else if (fa_metrics > dig_t->fa_th[1]) igi = igi + step_size[1]; - else if (fa_cnt < dig_t->fa_th[0]) + else if (fa_metrics < dig_t->fa_th[0]) igi = igi - step_size[2]; return igi; } -u8 phydm_get_new_igi(struct dm_struct *dm, u8 igi, u32 fa_cnt, +u8 phydm_get_new_igi(struct dm_struct *dm, u8 igi, u32 fa_metrics, boolean is_dfs_band) { struct phydm_dig_struct *dig_t = &dm->dm_dig_table; @@ -1023,17 +1290,18 @@ u8 phydm_get_new_igi(struct dm_struct *dm, u8 igi, u32 fa_cnt, /* @4 Abnormal # beacon case */ #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) if (dm->phy_dbg_info.num_qry_beacon_pkt < 5 && - fa_cnt < DM_DIG_FA_TH1 && dm->bsta_state && - dm->support_ic_type != ODM_RTL8723D) { + fa_metrics < dig_t->dm_dig_fa_th1 && dm->bsta_state && + dm->support_ic_type != ODM_RTL8723D && + dm->support_ic_type != ODM_RTL8822C) { dig_t->rx_gain_range_min = 0x1c; igi = dig_t->rx_gain_range_min; PHYDM_DBG(dm, DBG_DIG, "Beacon_num=%d,force igi=0x%x\n", dm->phy_dbg_info.num_qry_beacon_pkt, igi); } else { - igi = phydm_new_igi_by_fa(dm, igi, fa_cnt, step); + igi = phydm_new_igi_by_fa(dm, igi, fa_metrics, step); } #else - igi = phydm_new_igi_by_fa(dm, igi, fa_cnt, step); + igi = phydm_new_igi_by_fa(dm, igi, fa_metrics, step); #endif } else { /* @2 Before link */ @@ -1045,9 +1313,9 @@ u8 phydm_get_new_igi(struct dm_struct *dm, u8 igi, u32 fa_cnt, "First disconnect:foce IGI to lower bound\n"); } else { PHYDM_DBG(dm, DBG_DIG, "Pre_IGI=((0x%x)), FA=((%d))\n", - igi, fa_cnt); + igi, fa_metrics); - igi = phydm_new_igi_by_fa(dm, igi, fa_cnt, step); + igi = phydm_new_igi_by_fa(dm, igi, fa_metrics, step); } } @@ -1055,11 +1323,17 @@ u8 phydm_get_new_igi(struct dm_struct *dm, u8 igi, u32 fa_cnt, if (igi < dig_t->rx_gain_range_min) igi = dig_t->rx_gain_range_min; - if (igi > dig_t->rx_gain_range_max) + if (igi >= dig_t->rx_gain_range_max) { igi = dig_t->rx_gain_range_max; + dig_t->igi_dyn_up_hit = true; + } else { + dig_t->igi_dyn_up_hit = false; + } + PHYDM_DBG(dm, DBG_DIG, "igi_dyn_up_hit=%d\n", + dig_t->igi_dyn_up_hit); - PHYDM_DBG(dm, DBG_DIG, "fa_cnt = %d, IGI: 0x%x -> 0x%x\n", - fa_cnt, dig_t->cur_ig_value, igi); + PHYDM_DBG(dm, DBG_DIG, "fa_metrics = %d, IGI: 0x%x -> 0x%x\n", + fa_metrics, dig_t->cur_ig_value, igi); return igi; } @@ -1082,35 +1356,85 @@ boolean phydm_dig_dfs_mode_en(void *dm_void) return dfs_mode_en; } +void phydm_dig_fa_source(void *dm_void, u8 fa_source, u32 *fa_metrics) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_fa_struct *fa = &dm->false_alm_cnt; + + switch (fa_source) { + case 1: + *fa_metrics = fa->time_fa_exp; + break; + #ifdef IFS_CLM_SUPPORT + case 2: + if (fa->time_fa_ifs_clm) { + *fa_metrics = fa->time_fa_ifs_clm; + } else { + fa_source = 1; + *fa_metrics = fa->time_fa_exp; + } + break; + #endif + #ifdef FAHM_SUPPORT + case 3: + if (fa->time_fa_fahm) { + *fa_metrics = fa->time_fa_fahm; + } else { + fa_source = 1; + *fa_metrics = fa->time_fa_exp; + } + break; + #endif + default: + break; + } + + PHYDM_DBG(dm, DBG_DIG, + "fa_source:%d, fa_cnt=%d ,time_fa_exp=%d, fa_metrics=%d\n", + fa_source, fa->cnt_all, fa->time_fa_exp, *fa_metrics); +} + void phydm_dig(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_dig_struct *dig_t = &dm->dm_dig_table; - struct phydm_fa_struct *falm_cnt = &dm->false_alm_cnt; + struct phydm_fa_struct *fa = &dm->false_alm_cnt; #ifdef PHYDM_TDMA_DIG_SUPPORT struct phydm_fa_acc_struct *falm_cnt_acc = &dm->false_alm_cnt_acc; #endif u8 igi = dig_t->cur_ig_value; u8 new_igi = 0x20; - u32 fa_cnt = falm_cnt->cnt_all; + u32 fa_metrics = fa->cnt_all; boolean dfs_mode_en = false; -#ifdef PHYDM_TDMA_DIG_SUPPORT + PHYDM_DBG(dm, DBG_DIG, "%s Start===>\n", __func__); + + #ifdef PHYDM_DCC_ENHANCE + if (dm->dm_dcc_info.dcc_en) { + fa_metrics = fa->cnt_ofdm_fail; /*OFDM FA only*/ + dig_t->fa_source = 0; + } + #endif + + #ifdef PHYDM_TDMA_DIG_SUPPORT if (!(dm->original_dig_restore)) { if (dig_t->cur_ig_value_tdma == 0) dig_t->cur_ig_value_tdma = dig_t->cur_ig_value; igi = dig_t->cur_ig_value_tdma; - fa_cnt = falm_cnt_acc->cnt_all_1sec; + fa_metrics = falm_cnt_acc->cnt_all_1sec; + dig_t->fa_source = 0; } -#endif + #endif if (phydm_dig_abort(dm)) { dig_t->cur_ig_value = phydm_get_igi(dm, BB_PATH_A); return; } - PHYDM_DBG(dm, DBG_DIG, "%s Start===>\n", __func__); + if (dig_t->fa_source) + phydm_dig_fa_source(dm, dig_t->fa_source, &fa_metrics); + PHYDM_DBG(dm, DBG_DIG, "is_linked=%d, RSSI=%d, 1stConnect=%d, 1stDisconnect=%d\n", dm->is_linked, dm->rssi_min, @@ -1124,7 +1448,7 @@ void phydm_dig(void *dm_void) #ifdef CFG_DIG_DAMPING_CHK /*Record IGI History*/ - phydm_dig_recorder(dm, igi, fa_cnt); + phydm_dig_recorder(dm, igi, fa_metrics); /*@DIG Damping Check*/ phydm_dig_damping_chk(dm); @@ -1134,7 +1458,7 @@ void phydm_dig(void *dm_void) phydm_dig_abs_boundary_decision(dm, dfs_mode_en); /*@Dynamic Boundary Decision*/ - phydm_dig_dym_boundary_decision(dm); + phydm_dig_dym_boundary_decision(dm, dfs_mode_en); /*@Abnormal case check*/ phydm_dig_abnormal_case(dm); @@ -1143,7 +1467,7 @@ void phydm_dig(void *dm_void) phydm_fa_threshold_check(dm, dfs_mode_en); /*Select new IGI by FA */ - new_igi = phydm_get_new_igi(dm, igi, fa_cnt, dfs_mode_en); + new_igi = phydm_get_new_igi(dm, igi, fa_metrics, dfs_mode_en); /* @1 Update status */ #ifdef PHYDM_TDMA_DIG_SUPPORT @@ -1211,6 +1535,31 @@ void phydm_dig_by_rssi_lps(void *dm_void) #endif } +void phydm_get_dig_coverage(void *dm_void, u8 *max, u8 *min) +{ + *min = DIG_MIN_COVERAGE; + *max = DIG_MAX_PERFORMANCE_MODE; +} + +u8 phydm_get_igi_for_target_pin_scan(void *dm_void, u8 rssi) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u8 igi = 0; + u8 max = 0; + u8 min = 0; + + igi = rssi + 10; + + phydm_get_dig_coverage(dm, &max, &min); + + if (igi > max) + igi = max; + else if (igi < min) + igi = min; + + return igi; +} + /* @3============================================================ * 3 FASLE ALARM CHECK * 3============================================================ @@ -1239,6 +1588,11 @@ void phydm_false_alarm_counter_reg_reset(void *dm_void) #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + if (dm->support_ic_type & ODM_RTL8723F) { + /* @reset CCK FA and CCA counter */ + odm_set_bb_reg(dm, R_0x2a44, BIT(21), 0); + odm_set_bb_reg(dm, R_0x2a44, BIT(21), 1); + } else { /* @reset CCK FA counter */ odm_set_bb_reg(dm, R_0x1a2c, BIT(15) | BIT(14), 0); odm_set_bb_reg(dm, R_0x1a2c, BIT(15) | BIT(14), 2); @@ -1246,7 +1600,7 @@ void phydm_false_alarm_counter_reg_reset(void *dm_void) /* @reset CCK CCA counter */ odm_set_bb_reg(dm, R_0x1a2c, BIT(13) | BIT(12), 0); odm_set_bb_reg(dm, R_0x1a2c, BIT(13) | BIT(12), 2); - + } /* @Disable common rx clk gating => WLANBB-1106*/ odm_set_bb_reg(dm, R_0x1d2c, BIT(31), 0); /* @reset OFDM CCA counter, OFDM FA counter*/ @@ -1315,6 +1669,9 @@ void phydm_false_alarm_counter_reg_hold(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; + if (dm->support_ic_type & ODM_RTL8723F) + return; + if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { /* @hold cck counter */ odm_set_bb_reg(dm, R_0x1a2c, BIT(12), 1); @@ -1345,6 +1702,13 @@ void phydm_fa_cnt_statistics_n(void *dm_void) /* @hold ofdm & cck counter */ phydm_false_alarm_counter_reg_hold(dm); + reg = odm_get_bb_reg(dm, R_0x9d0, MASKDWORD); + fa_t->cnt_cck_txon = (reg & 0xffff); + fa_t->cnt_cck_txen = ((reg & 0xffff0000) >> 16); + reg = odm_get_bb_reg(dm, R_0x9cc, MASKDWORD); + fa_t->cnt_ofdm_txon = (reg & 0xffff); + fa_t->cnt_ofdm_txen = ((reg & 0xffff0000) >> 16); + reg = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE1_11N, MASKDWORD); fa_t->cnt_fast_fsync = (reg & 0xffff); fa_t->cnt_sb_search_fail = ((reg & 0xffff0000) >> 16); @@ -1374,11 +1738,21 @@ void phydm_fa_cnt_statistics_n(void *dm_void) fa_t->cnt_ofdm_crc32_error = (reg & 0xffff0000) >> 16; fa_t->cnt_ofdm_crc32_ok = reg & 0xffff; + /* read OFDM2 CRC32 counter */ + reg = odm_get_bb_reg(dm, R_0xf9c, MASKDWORD); + fa_t->cnt_ofdm_crc32_error = (reg & 0xffff0000) >> 16; + fa_t->cnt_ofdm2_crc32_ok = reg & 0xffff; + /* read HT CRC32 counter */ reg = odm_get_bb_reg(dm, ODM_REG_HT_CRC32_CNT_11N, MASKDWORD); fa_t->cnt_ht_crc32_error = (reg & 0xffff0000) >> 16; fa_t->cnt_ht_crc32_ok = reg & 0xffff; + /* read HT2 CRC32 counter */ + reg = odm_get_bb_reg(dm, R_0xf98, MASKDWORD); + fa_t->cnt_ht_crc32_error = (reg & 0xffff0000) >> 16; + fa_t->cnt_ht2_crc32_ok = reg & 0xffff; + /* read VHT CRC32 counter */ fa_t->cnt_vht_crc32_error = 0; fa_t->cnt_vht_crc32_ok = 0; @@ -1420,12 +1794,6 @@ void phydm_fa_cnt_statistics_n(void *dm_void) fa_t->cnt_cck_fail; fa_t->cnt_cca_all = fa_t->cnt_ofdm_cca + fa_t->cnt_cck_cca; - - PHYDM_DBG(dm, DBG_FA_CNT, - "[OFDM FA Detail] Parity_Fail=((%d)), Rate_Illegal=((%d)), CRC8_fail=((%d)), Mcs_fail=((%d)), Fast_Fsync=(( %d )), SBD_fail=((%d))\n", - fa_t->cnt_parity_fail, fa_t->cnt_rate_illegal, - fa_t->cnt_crc8_fail, fa_t->cnt_mcs_fail, fa_t->cnt_fast_fsync, - fa_t->cnt_sb_search_fail); } #endif @@ -1440,6 +1808,12 @@ void phydm_fa_cnt_statistics_ac(void *dm_void) if (!(dm->support_ic_type & ODM_IC_11AC_SERIES)) return; + ret_value = odm_get_bb_reg(dm, R_0xf50, MASKDWORD); + fa_t->cnt_cck_txen = (ret_value & 0xffff); + fa_t->cnt_ofdm_txen = ((ret_value & 0xffff0000) >> 16); + fa_t->cnt_cck_txon = (u16)odm_get_bb_reg(dm, R_0xfcc, MASKLWORD); + fa_t->cnt_ofdm_txon = (u16)odm_get_bb_reg(dm, R_0xfc8, MASKHWORD); + ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE1_11AC, MASKDWORD); fa_t->cnt_fast_fsync = (ret_value & 0xffff0000) >> 16; @@ -1482,16 +1856,31 @@ void phydm_fa_cnt_statistics_ac(void *dm_void) fa_t->cnt_ofdm_crc32_error = (ret_value & 0xffff0000) >> 16; fa_t->cnt_ofdm_crc32_ok = ret_value & 0xffff; + /* read OFDM2 CRC32 counter */ + ret_value = odm_get_bb_reg(dm, R_0xf1c, MASKDWORD); + fa_t->cnt_ofdm2_crc32_ok = ret_value & 0xffff; + fa_t->cnt_ofdm2_crc32_error = (ret_value & 0xffff0000) >> 16; + /* read HT CRC32 counter */ ret_value = odm_get_bb_reg(dm, ODM_REG_HT_CRC32_CNT_11AC, MASKDWORD); fa_t->cnt_ht_crc32_error = (ret_value & 0xffff0000) >> 16; fa_t->cnt_ht_crc32_ok = ret_value & 0xffff; + /* read HT2 CRC32 counter */ + ret_value = odm_get_bb_reg(dm, R_0xf18, MASKDWORD); + fa_t->cnt_ht2_crc32_ok = ret_value & 0xffff; + fa_t->cnt_ht2_crc32_error = (ret_value & 0xffff0000) >> 16; + /* read VHT CRC32 counter */ ret_value = odm_get_bb_reg(dm, ODM_REG_VHT_CRC32_CNT_11AC, MASKDWORD); fa_t->cnt_vht_crc32_error = (ret_value & 0xffff0000) >> 16; fa_t->cnt_vht_crc32_ok = ret_value & 0xffff; + /*read VHT2 CRC32 counter */ + ret_value = odm_get_bb_reg(dm, R_0xf54, MASKDWORD); + fa_t->cnt_vht2_crc32_ok = ret_value & 0xffff; + fa_t->cnt_vht2_crc32_error = (ret_value & 0xffff0000) >> 16; + #if (RTL8881A_SUPPORT) if (dm->support_ic_type == ODM_RTL8881A) { u32 tmp = 0; @@ -1522,19 +1911,13 @@ void phydm_fa_cnt_statistics_ac(void *dm_void) } #endif -void phydm_get_dbg_port_info(void *dm_void) +u32 phydm_get_edcca_report(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_fa_struct *fa_t = &dm->false_alm_cnt; u32 dbg_port = dm->adaptivity.adaptivity_dbg_port; u32 val = 0; - /*set debug port to 0x0*/ - if (phydm_set_bb_dbg_port(dm, DBGPORT_PRI_1, 0x0)) { - fa_t->dbg_port0 = phydm_get_bb_dbg_port_val(dm); - phydm_release_bb_dbg_port(dm); - } - if (dm->support_ic_type & ODM_RTL8723D) { val = odm_get_bb_reg(dm, R_0x9a0, BIT(29)); } else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { @@ -1547,16 +1930,151 @@ void phydm_get_dbg_port_info(void *dm_void) phydm_release_bb_dbg_port(dm); } - fa_t->edcca_flag = (boolean)val; + return val; +} - PHYDM_DBG(dm, DBG_FA_CNT, "FA_Cnt: Dbg port 0x0 = 0x%x, EDCCA = %d\n\n", +void phydm_get_dbg_port_info(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_fa_struct *fa_t = &dm->false_alm_cnt; + + if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + fa_t->dbg_port0 = odm_get_bb_reg(dm, R_0x2db4, MASKDWORD); + } else { + /*set debug port to 0x0*/ + if (phydm_set_bb_dbg_port(dm, DBGPORT_PRI_1, 0x0)) { + fa_t->dbg_port0 = phydm_get_bb_dbg_port_val(dm); + phydm_release_bb_dbg_port(dm); + } + } + + fa_t->edcca_flag = (boolean)phydm_get_edcca_report(dm); + + PHYDM_DBG(dm, DBG_FA_CNT, "FA_Cnt: Dbg port 0x0 = 0x%x, EDCCA = %d\n", fa_t->dbg_port0, fa_t->edcca_flag); } +void phydm_set_crc32_cnt2_rate(void *dm_void, u8 rate_idx) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_fa_struct *fa_t = &dm->false_alm_cnt; + boolean is_ofdm_rate = phydm_is_ofdm_rate(dm, rate_idx); + boolean is_ht_rate = phydm_is_ht_rate(dm, rate_idx); + boolean is_vht_rate = phydm_is_vht_rate(dm, rate_idx); + u32 reg_addr = 0x0; + u32 ofdm_rate_bitmask = 0x0; + u32 ht_mcs_bitmask = 0x0; + u32 vht_mcs_bitmask = 0x0; + u32 vht_ss_bitmask = 0x0; + u8 rate = 0x0; + u8 ss = 0x0; + + if (!is_ofdm_rate && !is_ht_rate && !is_vht_rate) + PHYDM_DBG(dm, DBG_FA_CNT, + "[FA CNT] rate_idx = (0x%x) is not supported !\n", + rate_idx); + + switch (dm->ic_ip_series) { + case PHYDM_IC_N: + reg_addr = R_0xf04; + ofdm_rate_bitmask = 0x0000f000; + ht_mcs_bitmask = 0x007f0000; + break; + case PHYDM_IC_AC: + reg_addr = R_0xb04; + ofdm_rate_bitmask = 0x0000f000; + ht_mcs_bitmask = 0x007f0000; + vht_mcs_bitmask = 0x0f000000; + vht_ss_bitmask = 0x30000000; + break; + case PHYDM_IC_JGR3: + reg_addr = R_0x1eb8; + ofdm_rate_bitmask = 0x00000f00; + ht_mcs_bitmask = 0x007f0000; + vht_mcs_bitmask = 0x0000f000; + vht_ss_bitmask = 0x000000c0; + break; + default: + break; + } + + if (is_ofdm_rate) { + rate = phydm_legacy_rate_2_spec_rate(dm, rate_idx); + + odm_set_bb_reg(dm, reg_addr, ofdm_rate_bitmask, rate); + fa_t->ofdm2_rate_idx = rate_idx; + } else if (is_ht_rate) { + rate = phydm_rate_2_rate_digit(dm, rate_idx); + + odm_set_bb_reg(dm, reg_addr, ht_mcs_bitmask, rate); + fa_t->ht2_rate_idx = rate_idx; + } else if (is_vht_rate) { + rate = phydm_rate_2_rate_digit(dm, rate_idx); + ss = phydm_rate_to_num_ss(dm, rate_idx); + + odm_set_bb_reg(dm, reg_addr, vht_mcs_bitmask, rate); + odm_set_bb_reg(dm, reg_addr, vht_ss_bitmask, ss - 1); + fa_t->vht2_rate_idx = rate_idx; + } +} + +void phydm_fa_cnt_cal_fa_duration(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + struct phydm_fa_struct *fa_t = &dm->false_alm_cnt; + u8 norm = 0; /*normalization*/ + boolean fahm_chk = false; + + fa_t->time_fa_all = fa_t->cnt_fast_fsync * 12 + + fa_t->cnt_sb_search_fail * 12 + + fa_t->cnt_parity_fail * 28 + + fa_t->cnt_rate_illegal * 28 + + fa_t->cnt_crc8_fail * 20 + + fa_t->cnt_crc8_fail_vhta * 28 + + fa_t->cnt_mcs_fail_vht * 36 + + fa_t->cnt_mcs_fail * 32 + + fa_t->cnt_cck_fail * 80; + + fa_t->time_fa_exp = fa_t->cnt_ofdm_fail * OFDM_FA_EXP_DURATION + + fa_t->cnt_cck_fail * CCK_FA_EXP_DURATION; + + fa_t->time_fa_ifs_clm = 0; + fa_t->time_fa_fahm = 0; + + #ifdef IFS_CLM_SUPPORT + if (ccx->ccx_watchdog_result & IFS_CLM_SUCCESS) { + norm = (u8)PHYDM_DIV(PHYDM_WATCH_DOG_PERIOD * S_TO_US, + ccx->ifs_clm_period); + fa_t->time_fa_ifs_clm = (ccx->ifs_clm_cckfa + + ccx->ifs_clm_ofdmfa) * norm; + } + #endif + + #ifdef FAHM_SUPPORT + if (ccx->ccx_watchdog_result & FAHM_SUCCESS) { + if (fa_t->cnt_cck_fail) { + if (ccx->fahm_inclu_cck) + fahm_chk = true; + } else { + fahm_chk = true; + } + } + + if (fahm_chk) { + norm = (u8)PHYDM_DIV(PHYDM_WATCH_DOG_PERIOD * S_TO_US, + ccx->fahm_period); + fa_t->time_fa_fahm = ccx->fahm_result_sum * norm; + } + #endif +} + void phydm_false_alarm_counter_statistics(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_fa_struct *fa_t = &dm->false_alm_cnt; + char dbg_buf[PHYDM_SNPRINT_SIZE] = {0}; + u32 tmp = 0; if (!(dm->support_ability & ODM_BB_FA_CNT)) return; @@ -1580,15 +2098,7 @@ void phydm_false_alarm_counter_statistics(void *dm_void) phydm_get_dbg_port_info(dm); phydm_false_alarm_counter_reg_reset(dm_void); - fa_t->time_fa_all = fa_t->cnt_fast_fsync * 12 + - fa_t->cnt_sb_search_fail * 12 + - fa_t->cnt_parity_fail * 28 + - fa_t->cnt_rate_illegal * 28 + - fa_t->cnt_crc8_fail * 20 + - fa_t->cnt_crc8_fail_vhta * 28 + - fa_t->cnt_mcs_fail_vht * 36 + - fa_t->cnt_mcs_fail * 32 + - fa_t->cnt_cck_fail * 80; + phydm_fa_cnt_cal_fa_duration(dm); fa_t->cnt_crc32_error_all = fa_t->cnt_vht_crc32_error + fa_t->cnt_ht_crc32_error + @@ -1601,30 +2111,131 @@ void phydm_false_alarm_counter_statistics(void *dm_void) fa_t->cnt_cck_crc32_ok; PHYDM_DBG(dm, DBG_FA_CNT, - "[OFDM FA Detail-1] Parity=((%d)), Rate_Illegal=((%d)), HT_CRC8=((%d)), HT_MCS=((%d))\n", - fa_t->cnt_parity_fail, fa_t->cnt_rate_illegal, - fa_t->cnt_crc8_fail, fa_t->cnt_mcs_fail); - PHYDM_DBG(dm, DBG_FA_CNT, - "[OFDM FA Detail-2] Fast_Fsync=((%d)), SBD=((%d)), VHT_SIGA_CRC8=((%d)), VHT_SIGB_CRC8=((%d)), VHT_MCS=((%d))\n", - fa_t->cnt_fast_fsync, fa_t->cnt_sb_search_fail, - fa_t->cnt_crc8_fail_vhta, fa_t->cnt_crc8_fail_vhtb, - fa_t->cnt_mcs_fail_vht); + "[Tx cnt] {CCK_TxEN, CCK_TxON, OFDM_TxEN, OFDM_TxON} = {%d, %d, %d, %d}\n", + fa_t->cnt_cck_txen, fa_t->cnt_cck_txon, fa_t->cnt_ofdm_txen, + fa_t->cnt_ofdm_txon); PHYDM_DBG(dm, DBG_FA_CNT, "[CCA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n", fa_t->cnt_cck_cca, fa_t->cnt_ofdm_cca, fa_t->cnt_cca_all); PHYDM_DBG(dm, DBG_FA_CNT, "[FA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n", fa_t->cnt_cck_fail, fa_t->cnt_ofdm_fail, fa_t->cnt_all); - PHYDM_DBG(dm, DBG_FA_CNT, "[CCK] CRC32 {error, ok}= {%d, %d}\n", - fa_t->cnt_cck_crc32_error, fa_t->cnt_cck_crc32_ok); - PHYDM_DBG(dm, DBG_FA_CNT, "[OFDM]CRC32 {error, ok}= {%d, %d}\n", - fa_t->cnt_ofdm_crc32_error, fa_t->cnt_ofdm_crc32_ok); - PHYDM_DBG(dm, DBG_FA_CNT, "[ HT ] CRC32 {error, ok}= {%d, %d}\n", - fa_t->cnt_ht_crc32_error, fa_t->cnt_ht_crc32_ok); - PHYDM_DBG(dm, DBG_FA_CNT, "[VHT] CRC32 {error, ok}= {%d, %d}\n", - fa_t->cnt_vht_crc32_error, fa_t->cnt_vht_crc32_ok); - PHYDM_DBG(dm, DBG_FA_CNT, "[TOTAL] CRC32 {error, ok}= {%d, %d}\n", - fa_t->cnt_crc32_error_all, fa_t->cnt_crc32_ok_all); + PHYDM_DBG(dm, DBG_FA_CNT, + "[FA duration(us)] {exp, ifs_clm, fahm} = {%d, %d, %d}\n", + fa_t->time_fa_exp, fa_t->time_fa_ifs_clm, + fa_t->time_fa_fahm); + PHYDM_DBG(dm, DBG_FA_CNT, + "[OFDM FA] Parity=%d, Rate=%d, Fast_Fsync=%d, SBD=%d\n", + fa_t->cnt_parity_fail, fa_t->cnt_rate_illegal, + fa_t->cnt_fast_fsync, fa_t->cnt_sb_search_fail); + PHYDM_DBG(dm, DBG_FA_CNT, "[HT FA] CRC8=%d, MCS=%d\n", + fa_t->cnt_crc8_fail, fa_t->cnt_mcs_fail); +#if (ODM_IC_11AC_SERIES_SUPPORT || defined(PHYDM_IC_JGR3_SERIES_SUPPORT)) + if (dm->support_ic_type & (ODM_IC_11AC_SERIES | ODM_IC_JGR3_SERIES)) { + PHYDM_DBG(dm, DBG_FA_CNT, + "[VHT FA] SIGA_CRC8=%d, SIGB_CRC8=%d, MCS=%d\n", + fa_t->cnt_crc8_fail_vhta, fa_t->cnt_crc8_fail_vhtb, + fa_t->cnt_mcs_fail_vht); + } +#endif + + PHYDM_DBG(dm, DBG_FA_CNT, + "[CRC32 OK Cnt] {CCK, OFDM, HT, VHT, Total} = {%d, %d, %d, %d, %d}\n", + fa_t->cnt_cck_crc32_ok, fa_t->cnt_ofdm_crc32_ok, + fa_t->cnt_ht_crc32_ok, fa_t->cnt_vht_crc32_ok, + fa_t->cnt_crc32_ok_all); + PHYDM_DBG(dm, DBG_FA_CNT, + "[CRC32 Err Cnt] {CCK, OFDM, HT, VHT, Total} = {%d, %d, %d, %d, %d}\n", + fa_t->cnt_cck_crc32_error, fa_t->cnt_ofdm_crc32_error, + fa_t->cnt_ht_crc32_error, fa_t->cnt_vht_crc32_error, + fa_t->cnt_crc32_error_all); + + if (fa_t->ofdm2_rate_idx) { + tmp = fa_t->cnt_ofdm2_crc32_error + fa_t->cnt_ofdm2_crc32_ok; + fa_t->ofdm2_pcr = (u8)PHYDM_DIV(fa_t->cnt_ofdm2_crc32_ok * 100, + tmp); + phydm_print_rate_2_buff(dm, fa_t->ofdm2_rate_idx, dbg_buf, + PHYDM_SNPRINT_SIZE); + PHYDM_DBG(dm, DBG_FA_CNT, + "[OFDM:%s CRC32 Cnt] {error, ok}= {%d, %d} (%d percent)\n", + dbg_buf, fa_t->cnt_ofdm2_crc32_error, + fa_t->cnt_ofdm2_crc32_ok, fa_t->ofdm2_pcr); + } else { + phydm_set_crc32_cnt2_rate(dm, ODM_RATE6M); + } + + if (fa_t->ht2_rate_idx) { + tmp = fa_t->cnt_ht2_crc32_error + fa_t->cnt_ht2_crc32_ok; + fa_t->ht2_pcr = (u8)PHYDM_DIV(fa_t->cnt_ht2_crc32_ok * 100, + tmp); + phydm_print_rate_2_buff(dm, fa_t->ht2_rate_idx, dbg_buf, + PHYDM_SNPRINT_SIZE); + PHYDM_DBG(dm, DBG_FA_CNT, + "[HT:%s CRC32 Cnt] {error, ok}= {%d, %d} (%d percent)\n", + dbg_buf, fa_t->cnt_ht2_crc32_error, + fa_t->cnt_ht2_crc32_ok, fa_t->ht2_pcr); + } else { + phydm_set_crc32_cnt2_rate(dm, ODM_RATEMCS0); + } + +#if (ODM_IC_11AC_SERIES_SUPPORT || defined(PHYDM_IC_JGR3_SERIES_SUPPORT)) + if (dm->support_ic_type & (ODM_IC_11AC_SERIES | ODM_IC_JGR3_SERIES)) { + if (fa_t->vht2_rate_idx) { + tmp = fa_t->cnt_vht2_crc32_error + + fa_t->cnt_vht2_crc32_ok; + fa_t->vht2_pcr = (u8)PHYDM_DIV(fa_t->cnt_vht2_crc32_ok * + 100, tmp); + phydm_print_rate_2_buff(dm, fa_t->vht2_rate_idx, + dbg_buf, PHYDM_SNPRINT_SIZE); + PHYDM_DBG(dm, DBG_FA_CNT, + "[VHT:%s CRC32 Cnt] {error, ok}= {%d, %d} (%d percent)\n", + dbg_buf, fa_t->cnt_vht2_crc32_error, + fa_t->cnt_vht2_crc32_ok, fa_t->vht2_pcr); + } else { + phydm_set_crc32_cnt2_rate(dm, ODM_RATEVHTSS1MCS0); + } + } +#endif +} + +void phydm_fill_fw_dig_info(void *dm_void, boolean *enable, + u8 *para4, u8 *para8) { + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_dig_struct *dig_t = &dm->dm_dig_table; + + dig_t->fw_dig_enable = *enable; + para8[0] = dig_t->rx_gain_range_max; + para8[1] = dig_t->rx_gain_range_min; + para8[2] = dm->number_linked_client; + para4[0] = (u8)DIG_LPS_MODE; +} + +void phydm_crc32_cnt_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_dig_struct *dig_t = &dm->dm_dig_table; + char help[] = "-h"; + u32 var1[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u8 i = 0; + u8 rate = 0x0; + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "[CRC32 Cnt] {rate_idx}\n"); + } else { + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + rate = (u8)var1[0]; + + PDM_SNPF(out_len, used, output + used, out_len - used, + "{rate}={0x%x}", rate); + + phydm_set_crc32_cnt2_rate(dm, rate); + } + *_used = used; + *_out_len = out_len; } #ifdef PHYDM_TDMA_DIG_SUPPORT @@ -1682,7 +2293,7 @@ void phydm_tdma_dig_timer_check(void *dm_void) if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B | ODM_RTL8812F | ODM_RTL8822B | ODM_RTL8192F | ODM_RTL8821C | ODM_RTL8197G | ODM_RTL8822C | - ODM_RTL8723D)) { + ODM_RTL8723D| ODM_RTL8723F)) { PHYDM_DBG(dm, DBG_DIG, "Check fail, Restart timer\n\n"); phydm_false_alarm_counter_reset(dm); @@ -2117,6 +2728,30 @@ u8 get_new_igi_bound(struct dm_struct *dm, u8 igi, u32 fa_cnt, u8 *rx_gain_max, return igi; } +void phydm_write_tdma_dig(void *dm_void, u8 new_igi) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_dig_struct *dig_t = &dm->dm_dig_table; + struct phydm_adaptivity_struct *adaptivity = &dm->adaptivity; + + PHYDM_DBG(dm, DBG_DIG, "%s===>\n", __func__); +#if 0 + /* @1 Check IGI by upper bound */ + if (adaptivity->igi_lmt_en && + new_igi > adaptivity->adapt_igi_up && dm->is_linked) { + new_igi = adaptivity->adapt_igi_up; + + PHYDM_DBG(dm, DBG_DIG, "Force Adaptivity Up-bound=((0x%x))\n", + new_igi); + } +#endif + phydm_write_dig_reg(dm, new_igi); + + PHYDM_DBG(dm, DBG_DIG, "New %s-IGI=((0x%x))\n", + (dig_t->tdma_dig_state == TDMA_DIG_LOW_STATE) ? "L" : "H", + new_igi); +} + void phydm_tdma_dig_new(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -2263,9 +2898,9 @@ void phydm_tdma_dig_cbk(void *dm_void) */ if (dig_t->tdma_dig_state == TDMA_DIG_LOW_STATE) - odm_write_dig(dm, dig_t->low_ig_value); + phydm_write_tdma_dig(dm, dig_t->low_ig_value); else if (dig_t->tdma_dig_state >= TDMA_DIG_HIGH_STATE) - odm_write_dig(dm, dig_t->cur_ig_value_tdma); + phydm_write_tdma_dig(dm, dig_t->cur_ig_value_tdma); odm_set_timer(dm, &dm->tdma_dig_timer, dm->tdma_dig_timer_ms); } @@ -2429,9 +3064,18 @@ void phydm_tdma_low_dig(void *dm_void) dig_t->dm_dig_min = DIG_MIN_PERFORMANCE; //0x20 dig_t->dig_max_of_min = DIG_MAX_OF_MIN_COVERAGE; //0x22 - if (dfs_mode_en) { - if (*dm->band_width == CHANNEL_WIDTH_20) - dig_t->dm_dig_min = DIG_MIN_DFS + 2; + if (dm->is_dfs_band) { + if (*dm->band_width == CHANNEL_WIDTH_20){ + if (dm->support_ic_type & + (ODM_RTL8814A | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8822B)){ + if (odm_get_bb_reg(dm, R_0x8d8, BIT(27)) == 1) + dig_t->dm_dig_min = DIG_MIN_DFS + 2; + else + dig_t->dm_dig_min = DIG_MIN_DFS; + } + else + dig_t->dm_dig_min = DIG_MIN_DFS; + } else dig_t->dm_dig_min = DIG_MIN_DFS; @@ -2462,7 +3106,8 @@ void phydm_tdma_low_dig(void *dm_void) /* @DIG lower bound in L-state*/ tdma_l_dym_min = dig_t->dm_dig_min; - + if (dm->is_dfs_band) + tdma_l_dym_min = DIG_MIN_DFS; /*@ *#ifdef CFG_DIG_DAMPING_CHK *@Limit Dyn min by damping @@ -2532,7 +3177,10 @@ void phydm_tdma_low_dig(void *dm_void) /*Update status*/ if (!(dm->original_dig_restore)) { - dig_t->low_ig_value = tdma_l_igi; + if (dig_t->tdma_force_l_igi == 0xff) + dig_t->low_ig_value = tdma_l_igi; + else + dig_t->low_ig_value = dig_t->tdma_force_l_igi; dig_t->tdma_rx_gain_min[TDMA_DIG_LOW_STATE] = tdma_l_dym_min; dig_t->tdma_rx_gain_max[TDMA_DIG_LOW_STATE] = tdma_l_dym_max; #if 0 @@ -2585,9 +3233,18 @@ void phydm_tdma_high_dig(void *dm_void) if (!dm->is_linked) { dig_t->dm_dig_max = DIG_MAX_COVERAGR; dig_t->dm_dig_min = DIG_MIN_PERFORMANCE; // 0x20 - } else if (dfs_mode_en) { - if (*dm->band_width == CHANNEL_WIDTH_20) - dig_t->dm_dig_min = DIG_MIN_DFS + 2; + } else if (dm->is_dfs_band) { + if (*dm->band_width == CHANNEL_WIDTH_20){ + if (dm->support_ic_type & + (ODM_RTL8814A | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8822B)){ + if (odm_get_bb_reg(dm, R_0x8d8, BIT(27)) == 1) + dig_t->dm_dig_min = DIG_MIN_DFS + 2; + else + dig_t->dm_dig_min = DIG_MIN_DFS; + } + else + dig_t->dm_dig_min = DIG_MIN_DFS; + } else dig_t->dm_dig_min = DIG_MIN_DFS; @@ -2634,7 +3291,9 @@ void phydm_tdma_high_dig(void *dm_void) dm->rssi_min, offset); /* @DIG lower bound in H-state*/ - if (rssi_min < dig_t->dm_dig_min) + if (dm->is_dfs_band) + tdma_h_dym_min = DIG_MIN_DFS; + else if (rssi_min < dig_t->dm_dig_min) tdma_h_dym_min = dig_t->dm_dig_min; else tdma_h_dym_min = rssi_min; // turbo not considered yet @@ -2706,7 +3365,10 @@ void phydm_tdma_high_dig(void *dm_void) /*Update status*/ if (!(dm->original_dig_restore)) { - dig_t->cur_ig_value_tdma = tdma_h_igi; + if (dig_t->tdma_force_h_igi == 0xff) + dig_t->cur_ig_value_tdma = tdma_h_igi; + else + dig_t->cur_ig_value_tdma = dig_t->tdma_force_h_igi; dig_t->tdma_rx_gain_min[TDMA_DIG_HIGH_STATE] = tdma_h_dym_min; dig_t->tdma_rx_gain_max[TDMA_DIG_HIGH_STATE] = tdma_h_dym_max; #if 0 @@ -2833,7 +3495,14 @@ void phydm_dig_debug(void *dm_void, char input[][16], u32 *_used, char *output, PDM_SNPF(out_len, used, output + used, out_len - used, "{4} {tdma_dig_state_number = %d}\n", dm->tdma_dig_state_number); + PDM_SNPF(out_len, used, output + used, out_len - used, + "{5} {0:L-state,1:H-state} {force IGI} (L,H)=(%2x,%2x)\n", + dig_t->tdma_force_l_igi, dig_t->tdma_force_h_igi); #endif + PDM_SNPF(out_len, used, output + used, out_len - used, + "{6} {fw_dig_en}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "{7} FA source:{0:original/1:Experimental duration/2:IFS_CLM/3:FAHM}\n"); } else { PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); @@ -2843,9 +3512,9 @@ void phydm_dig_debug(void *dm_void, char input[][16], u32 *_used, char *output, if (var1[0] == 0) { if (var1[1] == 1) { dig_t->is_dbg_fa_th = true; - dig_t->fa_th[0] = (u16)var1[2]; - dig_t->fa_th[1] = (u16)var1[3]; - dig_t->fa_th[2] = (u16)var1[4]; + dig_t->fa_th[0] = (u32)var1[2]; + dig_t->fa_th[1] = (u32)var1[3]; + dig_t->fa_th[2] = (u32)var1[4]; PDM_SNPF(out_len, used, output + used, out_len - used, @@ -2875,6 +3544,21 @@ void phydm_dig_debug(void *dm_void, char input[][16], u32 *_used, char *output, PDM_SNPF(out_len, used, output + used, out_len - used, "tdma_dig_state_number = %d\n", dm->tdma_dig_state_number); + } else if (var1[0] == 5) { + PHYDM_SSCANF(input[3], DCMD_HEX, &var1[2]); + if (var1[1] == 0) { + dig_t->tdma_force_l_igi = (u8)var1[2]; + PDM_SNPF(out_len, used, output + used, + out_len - used, + "force L-state IGI = %2x\n", + dig_t->tdma_force_l_igi); + } else if (var1[1] == 1) { + dig_t->tdma_force_h_igi = (u8)var1[2]; + PDM_SNPF(out_len, used, output + used, + out_len - used, + "force H-state IGI = %2x\n", + dig_t->tdma_force_h_igi); + } #endif } @@ -2884,13 +3568,22 @@ void phydm_dig_debug(void *dm_void, char input[][16], u32 *_used, char *output, /*@*/ } #endif + else if (var1[0] == 6) { + phydm_fw_dm_ctrl_en(dm, F00_DIG, (boolean)var1[1]); + PDM_SNPF(out_len, used, output + used, out_len - used, + "fw_dig_enable = %2x\n", dig_t->fw_dig_enable); + } else if (var1[0] == 7) { + dig_t->fa_source = (u8)var1[1]; + PDM_SNPF(out_len, used, output + used, out_len - used, + "FA source = %d\n", dig_t->fa_source); + } } *_used = used; *_out_len = out_len; } #ifdef CONFIG_MCC_DM -#if (RTL8822B_SUPPORT || RTL8822C_SUPPORT) +#if (RTL8822B_SUPPORT || RTL8822C_SUPPORT|| RTL8723F_SUPPORT) void phydm_mcc_igi_clr(void *dm_void, u8 clr_port) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -2933,13 +3626,26 @@ void phydm_mcc_igi_cal(void *dm_void) phydm_mcc_igi_chk(dm); igi_val0 = mcc_dm->mcc_rssi[0] - shift; igi_val1 = mcc_dm->mcc_rssi[1] - shift; + + if (igi_val0 < DIG_MIN_PERFORMANCE) + igi_val0 = DIG_MIN_PERFORMANCE; + + if (igi_val1 < DIG_MIN_PERFORMANCE) + igi_val1 = DIG_MIN_PERFORMANCE; + + switch (dm->ic_ip_series) { #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT - phydm_fill_mcccmd(dm, 0, R_0x1d70, igi_val0, igi_val1); - phydm_fill_mcccmd(dm, 1, R_0x1d70 + 1, igi_val0, igi_val1); - #else - phydm_fill_mcccmd(dm, 0, 0xc50, igi_val0, igi_val1); - phydm_fill_mcccmd(dm, 1, 0xe50, igi_val0, igi_val1); + case PHYDM_IC_JGR3: + phydm_fill_mcccmd(dm, 0, R_0x1d70, igi_val0, igi_val1); + phydm_fill_mcccmd(dm, 1, R_0x1d70 + 1, igi_val0, igi_val1); + break; #endif + default: + phydm_fill_mcccmd(dm, 0, R_0xc50, igi_val0, igi_val1); + phydm_fill_mcccmd(dm, 1, R_0xe50, igi_val0, igi_val1); + break; + } + PHYDM_DBG(dm, DBG_COMP_MCC, "RSSI_min: %d %d, MCC_igi: %d %d\n", mcc_dm->mcc_rssi[0], mcc_dm->mcc_rssi[1], mcc_dm->mcc_dm_val[0][0], mcc_dm->mcc_dm_val[0][1]); diff --git a/hal/phydm/phydm_dig.h b/hal/phydm/phydm_dig.h index 739294e..1ccfaa7 100644 --- a/hal/phydm/phydm_dig.h +++ b/hal/phydm/phydm_dig.h @@ -26,10 +26,11 @@ #ifndef __PHYDMDIG_H__ #define __PHYDMDIG_H__ -#define DIG_VERSION "2.5" /* @Add new fa_cnt for VHT-SIGA/VHT-SIGB*/ +/* 2020.08.13 Add IFS-CLM/FAHM in dig fa source for more accurate fa info*/ +#define DIG_VERSION "3.9" #define DIG_HW 0 -#define DIG_LIMIT_PERIOD 60 /*@60 sec*/ +#define DIG_LIMIT_PERIOD 60 /*60 sec*/ /*@--------------------Define ---------------------------------------*/ @@ -80,18 +81,29 @@ #define RSSI_OFFSET_DIG_LPS 5 #define DIG_RECORD_NUM 4 -/*@--------------------Enum-----------------------------------*/ -enum dig_goupcheck_level { - DIG_GOUPCHECK_LEVEL_0, - DIG_GOUPCHECK_LEVEL_1, - DIG_GOUPCHECK_LEVEL_2 -}; +/*==== [FA duration] =======================================*/ +/*[PHYDM-406]*/ +#define OFDM_FA_EXP_DURATION 12 /*us*/ +#define CCK_FA_EXP_DURATION 175 /*us*/ +/*@--------------------Enum-----------------------------------*/ enum phydm_dig_mode { PHYDM_DIG_PERFORAMNCE_MODE = 0, PHYDM_DIG_COVERAGE_MODE = 1, }; +enum phydm_dig_trend { + DIG_STABLE = 0, + DIG_INCREASING = 1, + DIG_DECREASING = 2 +}; + +enum phydm_fw_dig_mode_e { + DIG_PERFORMANCE_MODE = 0, + DIG_COVERAGE_MODE = 1, + DIG_LPS_MODE = 2 +}; + #ifdef PHYDM_TDMA_DIG_SUPPORT enum upd_type { ENABLE_TDMA, @@ -141,8 +153,11 @@ struct phydm_dig_struct { struct phydm_dig_recorder_strcut dig_recorder_t; u8 dig_dl_en; /*@damping limit function enable*/ #endif + boolean fw_dig_enable; boolean is_dbg_fa_th; u8 cur_ig_value; + boolean igi_dyn_up_hit; + u8 igi_trend; u32 rvrt_val; /*all rvrt_val for pause API must set to u32*/ u8 igi_backup; u8 rx_gain_range_max; /*@dig_dynamic_max*/ @@ -152,12 +167,14 @@ struct phydm_dig_struct { u8 dig_max_of_min; /*@Absolutly max of min*/ u32 ant_div_rssi_max; u8 *is_p2p_in_process; - enum dig_goupcheck_level go_up_chk_lv; - u16 fa_th[3]; + u32 fa_th[3]; + u32 dm_dig_fa_th1; + u8 fa_source; #if (RTL8822B_SUPPORT || RTL8197F_SUPPORT || RTL8821C_SUPPORT ||\ RTL8198F_SUPPORT || RTL8192F_SUPPORT || RTL8195B_SUPPORT ||\ RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8721D_SUPPORT ||\ - RTL8710C_SUPPORT || RTL8812F_SUPPORT || RTL8197G_SUPPORT) + RTL8710C_SUPPORT || RTL8812F_SUPPORT || RTL8197G_SUPPORT ||\ + RTL8723F_SUPPORT) u8 rf_gain_idx; u8 agc_table_idx; u8 big_jump_lmt[16]; @@ -173,7 +190,7 @@ struct phydm_dig_struct { u8 cur_ig_value_tdma; u8 low_ig_value; u8 tdma_dig_state; /*@To distinguish which state is now.(L-sate or H-state)*/ - u32 tdma_dig_cnt; /*@for phydm_tdma_dig_timer_check use*/ + u8 tdma_dig_cnt; /*@for phydm_tdma_dig_timer_check use*/ u8 pre_tdma_dig_cnt; u8 sec_factor; u32 cur_timestamp; @@ -189,6 +206,8 @@ struct phydm_dig_struct { u8 tdma_rx_gain_min[DIG_NUM_OF_TDMA_STATES]; /*To distinguish current state(L-sate or H-state)*/ #endif + u8 tdma_force_l_igi; + u8 tdma_force_h_igi; #endif }; @@ -226,10 +245,29 @@ struct phydm_fa_struct { u32 cnt_crc32_error_all; u32 cnt_crc32_ok_all; u32 time_fa_all; + u32 time_fa_exp; /*FA duration, [PHYDM-406]*/ + u32 time_fa_ifs_clm; /*FA duration, [PHYDM-406]*/ + u32 time_fa_fahm; /*FA duration, [PHYDM-406]*/ boolean cck_block_enable; boolean ofdm_block_enable; u32 dbg_port0; boolean edcca_flag; + u8 ofdm2_rate_idx; + u32 cnt_ofdm2_crc32_error; + u32 cnt_ofdm2_crc32_ok; + u8 ofdm2_pcr; + u8 ht2_rate_idx; + u32 cnt_ht2_crc32_error; + u32 cnt_ht2_crc32_ok; + u8 ht2_pcr; + u8 vht2_rate_idx; + u32 cnt_vht2_crc32_error; + u32 cnt_vht2_crc32_ok; + u8 vht2_pcr; + u32 cnt_cck_txen; + u32 cnt_cck_txon; + u32 cnt_ofdm_txen; + u32 cnt_ofdm_txon; }; #ifdef PHYDM_TDMA_DIG_SUPPORT @@ -277,6 +315,13 @@ void phydm_set_dig_val(void *dm_void, u32 *val_buf, u8 val_len); void odm_pause_dig(void *dm_void, enum phydm_pause_type pause_type, enum phydm_pause_level pause_level, u8 igi_value); +#ifdef PHYDM_HW_IGI +void phydm_hwigi(void *dm_void); + +void phydm_hwigi_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); +#endif + void phydm_dig_init(void *dm_void); void phydm_dig(void *dm_void); @@ -285,8 +330,14 @@ void phydm_dig_lps_32k(void *dm_void); void phydm_dig_by_rssi_lps(void *dm_void); +void phydm_get_dig_coverage(void *dm_void, u8 *max, u8 *min); + +u8 phydm_get_igi_for_target_pin_scan(void *dm_void, u8 rssi); + void phydm_false_alarm_counter_statistics(void *dm_void); +u32 phydm_get_edcca_report(void * dm_void); + #ifdef PHYDM_TDMA_DIG_SUPPORT void phydm_set_tdma_dig_timer(void *dm_void); @@ -329,9 +380,14 @@ void phydm_set_ofdm_agc_tab(void *dm_void, u8 tab_sel); void phydm_dig_debug(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len); +void phydm_fill_fw_dig_info(void *dm_void, boolean *enable, + u8 *para4, u8 *para8); + +void phydm_crc32_cnt_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); + #ifdef CONFIG_MCC_DM void phydm_mcc_igi_cal(void *dm_void); #endif - #endif diff --git a/hal/phydm/phydm_direct_bf.c b/hal/phydm/phydm_direct_bf.c index f9f6f3c..55dd2f8 100644 --- a/hal/phydm/phydm_direct_bf.c +++ b/hal/phydm/phydm_direct_bf.c @@ -94,7 +94,7 @@ void phydm_iq_gen_en(void *dm_void) odm_set_rf_reg(dm, RF_PATH_B, RF_0x30, 0xfffff, 0x18000); odm_set_rf_reg(dm, RF_PATH_B, RF_0x31, 0xfffff, 0x000cf); odm_set_rf_reg(dm, RF_PATH_B, RF_0x32, 0xfffff, 0x71fc2); - odm_set_rf_reg(dm, RF_PATH_B, RF_0x30, 0xfffff, 0x18000); + odm_set_rf_reg(dm, RF_PATH_B, RF_0x30, 0xfffff, 0x08000); odm_set_rf_reg(dm, RF_PATH_B, RF_0x31, 0xfffff, 0x000ef); odm_set_rf_reg(dm, RF_PATH_B, RF_0x32, 0xfffff, 0x01042); odm_set_rf_reg(dm, RF_PATH_B, RF_0xef, 0x80000, 0x0); diff --git a/hal/phydm/phydm_dynamictxpower.c b/hal/phydm/phydm_dynamictxpower.c index 97be99a..2ccbd1a 100644 --- a/hal/phydm/phydm_dynamictxpower.c +++ b/hal/phydm/phydm_dynamictxpower.c @@ -135,7 +135,7 @@ void phydm_wt_ram_pwr(void *dm_void, u8 macid, boolean is_ofst1, dm_ram_per_sta->tx_pwr_offset1 = pwr_ofst; pwr_ofst_ano_en = dm_ram_per_sta->tx_pwr_offset0_en; - pwr_ofst_ano = dm_ram_per_sta->tx_pwr_offset1; + pwr_ofst_ano = dm_ram_per_sta->tx_pwr_offset0; reg_0x1e84 |= (pwr_ofst_ano_en << 15) + ((pwr_ofst_ano & 0x7f) << 8) + @@ -199,29 +199,24 @@ void phydm_pwr_lv_ctrl(void *dm_void, u8 macid, u8 tx_pwr_lv) pwr_offset = PHYDM_BBRAM_OFFSET_ZERO; phydm_wt_ram_pwr(dm, macid, RAM_PWR_OFST0, true, pwr_offset); - /* still need to check with SD7*/ - #if (RTL8822C_SUPPORT) - if (dm->support_ic_type & ODM_RTL8822C) - phydm_wt_ram_pwr(dm, 127, RAM_PWR_OFST0, true, pwr_offset); - #endif } -void phydm_dtp_fill_cmninfo_2nd(void *dm_void, u8 macid, u8 dtp_lvl) +void phydm_dtp_fill_cmninfo_2nd(void *dm_void, u8 sta_id, u8 dtp_lvl) { struct dm_struct *dm = (struct dm_struct *)dm_void; - struct cmn_sta_info *sta = dm->phydm_sta_info[macid]; + struct cmn_sta_info *sta = dm->phydm_sta_info[sta_id]; struct dtp_info *dtp = NULL; if (!is_sta_active(sta)) return; - dtp = &dm->phydm_sta_info[macid]->dtp_stat; + dtp = &dm->phydm_sta_info[sta_id]->dtp_stat; dtp->dyn_tx_power = phydm_pwr_lv_mapping_2nd(dtp_lvl); - phydm_pwr_lv_ctrl(dm, macid, dtp_lvl); + phydm_pwr_lv_ctrl(dm, sta->mac_id, dtp_lvl); PHYDM_DBG(dm, DBG_DYN_TXPWR, - "Fill cmninfo TxPwr: macid=(%d), PwrLv (%d)\n", macid, - dtp->dyn_tx_power); + "Fill cmninfo TxPwr: sta_id=(%d), macid=(%d), PwrLv (%d)\n", + sta_id, sta->mac_id, dtp->dyn_tx_power); } void phydm_dtp_init_2nd(void *dm_void) @@ -231,8 +226,8 @@ void phydm_dtp_init_2nd(void *dm_void) if (!(dm->support_ability & ODM_BB_DYNAMIC_TXPWR)) return; - #if (RTL8822C_SUPPORT) - if (dm->support_ic_type & ODM_RTL8822C) { + #if (RTL8822C_SUPPORT || RTL8812F_SUPPORT) + if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8812F)) { phydm_rst_ram_pwr(dm); /* rsp tx use type 0*/ odm_set_mac_reg(dm, R_0x6d8, BIT(19) | BIT(18), RAM_PWR_OFST0); @@ -323,15 +318,14 @@ phydm_check_paths(void *dm_void) return max_path; } -#ifndef PHYDM_COMMON_API_SUPPORT +#ifdef PHYDM_COMMON_API_NOT_SUPPORT u8 phydm_dtp_get_txagc(void *dm_void, enum rf_path path, u8 hw_rate) { struct dm_struct *dm = (struct dm_struct *)dm_void; u8 ret = 0xff; -#if (RTL8192E_SUPPORT) ret = config_phydm_read_txagc_n(dm, path, hw_rate); -#endif + return ret; } #endif @@ -342,21 +336,27 @@ u8 phydm_search_min_power_index(void *dm_void) enum rf_path path; enum rf_path max_path; u8 min_gain_index = 0x3f; - u8 gain_index; - u8 rate_idx; + u8 gain_index = 0; + u8 i; PHYDM_DBG(dm, DBG_DYN_TXPWR, "%s\n", __func__); max_path = phydm_check_paths(dm); for (path = 0; path <= max_path; path++) - for (rate_idx = 0; rate_idx < 84; rate_idx++) - if (phydm_check_rates(dm, rate_idx)) { -#ifdef PHYDM_COMMON_API_SUPPORT - /*This is for API support IC : 97F,8822B,92F,8821C*/ - gain_index = phydm_api_get_txagc(dm, path, rate_idx); -#else - /*This is for API non-support IC : 92E */ - gain_index = phydm_dtp_get_txagc(dm, path, rate_idx); -#endif + for (i = 0; i < 84; i++) + if (phydm_check_rates(dm, i)) { + + if (dm->support_ic_type & PHYDM_COMMON_API_IC) { + #ifdef PHYDM_COMMON_API_SUPPORT + /*97F,8822B,92F,8821C*/ + gain_index = phydm_api_get_txagc(dm, path, i); + #endif + } else { + /*92E*/ + #ifdef PHYDM_COMMON_API_NOT_SUPPORT + gain_index = phydm_dtp_get_txagc(dm, path, i); + #endif + } + if (gain_index == 0xff) { min_gain_index = 0x20; PHYDM_DBG(dm, DBG_DYN_TXPWR, @@ -366,7 +366,7 @@ u8 phydm_search_min_power_index(void *dm_void) } PHYDM_DBG(dm, DBG_DYN_TXPWR, "Support Rate: ((%d)) -> Gain idx: ((%d))\n", - rate_idx, gain_index); + i, gain_index); if (gain_index < min_gain_index) min_gain_index = gain_index; } @@ -423,34 +423,45 @@ void phydm_noisy_enhance_hp_th(void *dm_void, u8 noisy_state) dm->enhance_pwr_th[2]); } -u8 phydm_pwr_lvl_check(void *dm_void, u8 input_rssi) +u8 phydm_pwr_lvl_check(void *dm_void, u8 input_rssi, u8 last_pwr_lv) { struct dm_struct *dm = (struct dm_struct *)dm_void; - u8 th0, th1, th2; + u8 th[DTP_POWER_LEVEL_SIZE]; + u8 i; if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - th2 = dm->set_pwr_th[2]; - th1 = dm->set_pwr_th[1]; - th0 = dm->set_pwr_th[0]; + for (i = 0; i < DTP_POWER_LEVEL_SIZE; i++) + th[i] = dm->set_pwr_th[i]; + PHYDM_DBG(dm, DBG_DYN_TXPWR, - "DTP th: Lv1_th = %d, Lv2_th = %d, Lv3_th = %d\n", - th0, th1, th2); + "Ori-DTP th: Lv1_th = %d, Lv2_th = %d, Lv3_th = %d\n", + th[0], th[1], th[2]); + + for (i = 0; i < DTP_POWER_LEVEL_SIZE; i++) { + if (i >= (last_pwr_lv)) + th[i] += DTP_FLOOR_UP_GAP; + } + + PHYDM_DBG(dm, DBG_DYN_TXPWR, + "Mod-DTP th: Lv1_th = %d, Lv2_th = %d, Lv3_th = %d\n", + th[0], th[1], th[2]); } else { - th2 = dm->enhance_pwr_th[2]; - th1 = dm->enhance_pwr_th[1]; - th0 = dm->enhance_pwr_th[0]; + for (i = 0; i < DTP_POWER_LEVEL_SIZE; i++) + th[i] = dm->enhance_pwr_th[i]; + for (i = 0; i < DTP_POWER_LEVEL_SIZE; i++) { + if (i >= (last_pwr_lv)) + th[i] += DTP_FLOOR_UP_GAP; + } } - if (input_rssi >= th2) + if (input_rssi >= th[2]) return tx_high_pwr_level_level3; - else if (input_rssi < (th2 - 3) && input_rssi >= th1) + else if (input_rssi < th[2] && input_rssi >= th[1]) return tx_high_pwr_level_level2; - else if (input_rssi < (th1 - 3) && input_rssi >= th0) + else if (input_rssi < th[1] && input_rssi >= th[0]) return tx_high_pwr_level_level1; - else if (input_rssi < (th0 - 3)) - return tx_high_pwr_level_normal; else - return tx_high_pwr_level_unchange; + return tx_high_pwr_level_normal; } u8 phydm_pwr_lv_mapping(u8 tx_pwr_lv) @@ -473,8 +484,7 @@ void phydm_dynamic_response_power(void *dm_void) if (!(dm->support_ability & ODM_BB_DYNAMIC_TXPWR)) return; - if (dm->dynamic_tx_high_power_lvl == tx_high_pwr_level_unchange) { - dm->dynamic_tx_high_power_lvl = dm->last_dtp_lvl; + if (dm->dynamic_tx_high_power_lvl == dm->last_dtp_lvl) { PHYDM_DBG(dm, DBG_DYN_TXPWR, "RespPwr not change\n"); return; } @@ -489,10 +499,10 @@ void phydm_dynamic_response_power(void *dm_void) dm->dynamic_tx_high_power_lvl); } -void phydm_dtp_fill_cmninfo(void *dm_void, u8 macid, u8 dtp_lvl) +void phydm_dtp_fill_cmninfo(void *dm_void, u8 sta_id, u8 dtp_lvl) { struct dm_struct *dm = (struct dm_struct *)dm_void; - struct cmn_sta_info *sta = dm->phydm_sta_info[macid]; + struct cmn_sta_info *sta = dm->phydm_sta_info[sta_id]; struct dtp_info *dtp = NULL; if (!is_sta_active(sta)) @@ -501,61 +511,97 @@ void phydm_dtp_fill_cmninfo(void *dm_void, u8 macid, u8 dtp_lvl) dtp = &sta->dtp_stat; dtp->dyn_tx_power = phydm_pwr_lv_mapping(dtp_lvl); PHYDM_DBG(dm, DBG_DYN_TXPWR, - "Fill cmninfo TxPwr: macid=(%d), PwrLv (%d)\n", macid, - dtp->dyn_tx_power); + "Fill cmninfo TxPwr: sta_id=(%d), macid=(%d), PwrLv (%d)\n", + sta_id, sta->mac_id, dtp->dyn_tx_power); } -void phydm_dtp_per_sta(void *dm_void, u8 macid) +void phydm_dtp_per_sta(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; - struct cmn_sta_info *sta = dm->phydm_sta_info[macid]; + struct cmn_sta_info *sta = NULL; struct dtp_info *dtp = NULL; struct rssi_info *rssi = NULL; + struct phydm_bb_ram_ctrl *bb_ctrl = &dm->p_bb_ram_ctrl; + u8 sta_cnt = 0; + u8 i = 0; + u8 curr_pwr_lv = 0; + u8 last_pwr_lv = 0; + u8 mac_id_cnt = 0; + u64 macid_cur = 0; + u64 macid_diff = 0; + u64 macid_mask = 0; - if (is_sta_active(sta)) { - dtp = &sta->dtp_stat; - rssi = &sta->rssi_stat; - dtp->sta_tx_high_power_lvl = phydm_pwr_lvl_check(dm, - rssi->rssi); - PHYDM_DBG(dm, DBG_DYN_TXPWR, - "STA=%d , RSSI: %d , GetPwrLv: %d\n", macid, - rssi->rssi, dtp->sta_tx_high_power_lvl); + for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { + sta = dm->phydm_sta_info[i]; + if (is_sta_active(sta)) { + sta_cnt++; - if (dtp->sta_tx_high_power_lvl == tx_high_pwr_level_unchange - || dtp->sta_tx_high_power_lvl == dtp->sta_last_dtp_lvl) { - dtp->sta_tx_high_power_lvl = dtp->sta_last_dtp_lvl; + dtp = &sta->dtp_stat; + rssi = &sta->rssi_stat; + macid_mask = (u64)BIT(sta->mac_id); + if (!(bb_ctrl->macid_is_linked & macid_mask)) + dtp->sta_last_dtp_lvl = tx_high_pwr_level_normal; + + last_pwr_lv = dtp->sta_last_dtp_lvl; + curr_pwr_lv = phydm_pwr_lvl_check(dm, rssi->rssi, + last_pwr_lv); + dtp->sta_tx_high_power_lvl = curr_pwr_lv; PHYDM_DBG(dm, DBG_DYN_TXPWR, - "DTP_lv not change: ((%d))\n", - dtp->sta_tx_high_power_lvl); - return; - } - - PHYDM_DBG(dm, DBG_DYN_TXPWR, - "DTP_lv update: ((%d)) -> ((%d))\n", - dtp->sta_last_dtp_lvl, dtp->sta_tx_high_power_lvl); - - dtp->sta_last_dtp_lvl = dtp->sta_tx_high_power_lvl; - - switch (dm->ic_ip_series) { - #ifdef BB_RAM_SUPPORT - case PHYDM_IC_JGR3: - phydm_dtp_fill_cmninfo_2nd(dm, macid, - dtp->sta_tx_high_power_lvl); - break; - #endif - default: - phydm_dtp_fill_cmninfo(dm, macid, - dtp->sta_tx_high_power_lvl); - break; + "STA_id=%d, MACID=%d , RSSI: %d , GetPwrLv: %d\n", + i, sta->mac_id, rssi->rssi, curr_pwr_lv); + + bb_ctrl->macid_is_linked |= macid_mask; + macid_cur |= macid_mask; + PHYDM_DBG(dm, DBG_DYN_TXPWR, + "macid_is_linked: (0x%llx), macid_cur: (0x%llx)\n", + bb_ctrl->macid_is_linked, macid_cur); + + if (curr_pwr_lv == last_pwr_lv && dtp->sta_is_alive) { + dtp->sta_tx_high_power_lvl = last_pwr_lv; + PHYDM_DBG(dm, DBG_DYN_TXPWR, + "DTP_lv not change: ((%d))\n", + curr_pwr_lv); + } else { + PHYDM_DBG(dm, DBG_DYN_TXPWR, + "DTP_lv update: ((%d)) -> ((%d))\n", + last_pwr_lv, curr_pwr_lv); + + dtp->sta_last_dtp_lvl = curr_pwr_lv; + + switch (dm->ic_ip_series) { + #ifdef BB_RAM_SUPPORT + case PHYDM_IC_JGR3: + phydm_dtp_fill_cmninfo_2nd(dm, i, curr_pwr_lv); + break; + #endif + default: + phydm_dtp_fill_cmninfo(dm, i, curr_pwr_lv); + break; + } + if(!dtp->sta_is_alive) + dtp->sta_is_alive = true; + } + + if (sta_cnt == dm->number_linked_client) + break; } + } + macid_diff = bb_ctrl->macid_is_linked ^ macid_cur; + if (macid_diff) + bb_ctrl->macid_is_linked &= ~macid_diff; + while (macid_diff) { + if (macid_diff & 0x1) + phydm_pwr_lv_ctrl(dm, mac_id_cnt, tx_high_pwr_level_normal); + mac_id_cnt++; + macid_diff >>= 1; } } -void odm_set_dyntxpwr(void *dm_void, u8 *desc, u8 macid) +void odm_set_dyntxpwr(void *dm_void, u8 *desc, u8 sta_id) { struct dm_struct *dm = (struct dm_struct *)dm_void; - struct cmn_sta_info *sta = dm->phydm_sta_info[macid]; + struct cmn_sta_info *sta = dm->phydm_sta_info[sta_id]; struct dtp_info *dtp = NULL; if (!is_sta_active(sta)) @@ -671,7 +717,7 @@ void phydm_dynamic_tx_power(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct cmn_sta_info *sta = NULL; u8 i = 0; - u8 cnt = 0; + u8 rssi_min = dm->rssi_min; u8 rssi_tmp = 0; @@ -685,16 +731,12 @@ void phydm_dynamic_tx_power(void *dm_void) phydm_noisy_enhance_hp_th(dm, dm->noisy_decision); /* Response Power */ dm->dynamic_tx_high_power_lvl = phydm_pwr_lvl_check(dm, - rssi_min); + rssi_min, + dm->last_dtp_lvl); phydm_dynamic_response_power(dm); } /* Per STA Tx power */ - for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { - phydm_dtp_per_sta(dm, i); - cnt++; - if (cnt >= dm->number_linked_client) - break; - } + phydm_dtp_per_sta(dm); } #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) diff --git a/hal/phydm/phydm_dynamictxpower.h b/hal/phydm/phydm_dynamictxpower.h index a9ece02..88be431 100644 --- a/hal/phydm/phydm_dynamictxpower.h +++ b/hal/phydm/phydm_dynamictxpower.h @@ -32,8 +32,10 @@ * ============================================================ */ -/* 2019.2.12, refine code structure and set macid 127 only for 22C*/ -#define DYNAMIC_TXPWR_VERSION "1.8" +/* 2020.6.23, Let gain_idx be initialized to 0 for linux compile warning*/ +#define DYNAMIC_TXPWR_VERSION "2.1" + +#define DTP_POWER_LEVEL_SIZE 3 #if (DM_ODM_SUPPORT_TYPE == ODM_AP) #define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 @@ -48,9 +50,9 @@ #endif #if (DM_ODM_SUPPORT_TYPE == ODM_AP) -#define TX_PWR_NEAR_FIELD_TH_JGR3_LVL3 255 -#define TX_PWR_NEAR_FIELD_TH_JGR3_LVL2 74 -#define TX_PWR_NEAR_FIELD_TH_JGR3_LVL1 60 +#define TX_PWR_NEAR_FIELD_TH_JGR3_LVL3 80 +#define TX_PWR_NEAR_FIELD_TH_JGR3_LVL2 63 +#define TX_PWR_NEAR_FIELD_TH_JGR3_LVL1 55 #elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) #define TX_PWR_NEAR_FIELD_TH_JGR3_LVL3 90 #define TX_PWR_NEAR_FIELD_TH_JGR3_LVL2 85 @@ -66,6 +68,7 @@ #define tx_high_pwr_level_level2 2 #define tx_high_pwr_level_level3 3 #define tx_high_pwr_level_unchange 4 +#define DTP_FLOOR_UP_GAP 3 /* @============================================================ * enumrate @@ -122,6 +125,15 @@ void phydm_dynamic_tx_power_init(void *dm_void); void phydm_dtp_debug(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len); +void phydm_rd_reg_pwr(void *dm_void, u32 *_used, char *output, u32 *_out_len); + +void phydm_wt_reg_pwr(void *dm_void, boolean is_ofst1, boolean pwr_ofst_en, + s8 pwr_ofst); + +void phydm_wt_ram_pwr(void *dm_void, u8 macid, boolean is_ofst1, + boolean pwr_ofst_en, s8 pwr_ofst); + + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) void odm_dynamic_tx_power_win(void *dm_void); #endif diff --git a/hal/phydm/phydm_features.h b/hal/phydm/phydm_features.h index bad902b..bbbc9ed 100644 --- a/hal/phydm/phydm_features.h +++ b/hal/phydm/phydm_features.h @@ -33,8 +33,12 @@ ODM_RTL8821C | \ ODM_RTL8822B | \ ODM_RTL8721D | \ + ODM_RTL8723D | \ ODM_RTL8710C) #define ODM_RECEIVER_BLOCKING_SUPPORT (ODM_RTL8188E | ODM_RTL8192E) +#define ODM_DYM_BW_INDICATION_SUPPORT (ODM_RTL8821C | \ + ODM_RTL8822B | \ + ODM_RTL8822C) /*@20170103 YuChen add for FW API*/ #define PHYDM_FW_API_ENABLE_8822B 1 @@ -53,6 +57,8 @@ #define PHYDM_FW_API_FUNC_ENABLE_8812F 1 #define PHYDM_FW_API_ENABLE_8197G 1 #define PHYDM_FW_API_FUNC_ENABLE_8197G 1 +#define PHYDM_FW_API_ENABLE_8723F 1 +#define PHYDM_FW_API_FUNC_ENABLE_8723F 1 #define CONFIG_POWERSAVING 0 diff --git a/hal/phydm/phydm_features_ap.h b/hal/phydm/phydm_features_ap.h index fc1c12a..38a0eeb 100644 --- a/hal/phydm/phydm_features_ap.h +++ b/hal/phydm/phydm_features_ap.h @@ -19,7 +19,7 @@ #if (RTL8814A_SUPPORT || RTL8821C_SUPPORT || RTL8822B_SUPPORT ||\ RTL8197F_SUPPORT || RTL8192F_SUPPORT || RTL8198F_SUPPORT ||\ RTL8822C_SUPPORT || RTL8812F_SUPPORT || RTL8814B_SUPPORT ||\ - RTL8197G_SUPPORT) + RTL8197G_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_LA_MODE_SUPPORT 1 #else #define PHYDM_LA_MODE_SUPPORT 0 @@ -30,9 +30,14 @@ #define DYN_ANT_WEIGHTING_SUPPORT #endif -#if (RTL8822B_SUPPORT || RTL8821C_SUPPORT) +#if (RTL8822B_SUPPORT || RTL8198F_SUPPORT || RTL8814B_SUPPORT ||\ + RTL8197G_SUPPORT || RTL8812F_SUPPORT || RTL8723F_SUPPORT) #define FAHM_SUPPORT #endif + +#if (RTL8197G_SUPPORT || RTL8812F_SUPPORT || RTL8723F_SUPPORT) + #define IFS_CLM_SUPPORT +#endif #define NHM_SUPPORT #define CLM_SUPPORT @@ -45,7 +50,7 @@ #endif #if (RTL8198F_SUPPORT || RTL8814B_SUPPORT || RTL8812F_SUPPORT ||\ - RTL8197G_SUPPORT) + RTL8197G_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_TDMA_DIG_SUPPORT 1 #ifdef PHYDM_TDMA_DIG_SUPPORT #define IS_USE_NEW_TDMA /*new tdma dig test*/ @@ -76,12 +81,12 @@ #endif #if (RTL8814B_SUPPORT || RTL8198F_SUPPORT || RTL8822C_SUPPORT ||\ - RTL8812F_SUPPORT || RTL8197G_SUPPORT) + RTL8812F_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_PMAC_TX_SETTING_SUPPORT #endif #if (RTL8814B_SUPPORT || RTL8198F_SUPPORT || RTL8822C_SUPPORT ||\ - RTL8812F_SUPPORT || RTL8197G_SUPPORT) + RTL8812F_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_MP_SUPPORT #endif @@ -119,9 +124,18 @@ #define CONFIG_DIRECTIONAL_BF #endif -#ifdef CONFIG_SUPPORT_DYNAMIC_TXPWR -#define CONFIG_DYNAMIC_TX_TWR +#if (RTL8197G_SUPPORT || RTL8812F_SUPPORT || RTL8814B_SUPPORT) + #define CONFIG_DYNAMIC_TX_TWR #endif + +#if (RTL8197G_SUPPORT || RTL8812F_SUPPORT) + #define PHYDM_HW_IGI +#endif + +#if (RTL8197G_SUPPORT || RTL8812F_SUPPORT) + #define CONFIG_DYNAMIC_TXCOLLISION_TH +#endif + /*#define CONFIG_PSD_TOOL*/ #define PHYDM_SUPPORT_CCKPD #define PHYDM_SUPPORT_ADAPTIVITY @@ -143,7 +157,7 @@ #endif #endif -#if defined(CONFIG_RTL_8881A_ANT_SWITCH) || defined(CONFIG_SLOT_0_ANT_SWITCH) || defined(CONFIG_SLOT_1_ANT_SWITCH) || defined(CONFIG_RTL_8197F_ANT_SWITCH) +#if defined(CONFIG_RTL_8881A_ANT_SWITCH) || defined(CONFIG_SLOT_0_ANT_SWITCH) || defined(CONFIG_SLOT_1_ANT_SWITCH) || defined(CONFIG_RTL_8197F_ANT_SWITCH) || defined(CONFIG_RTL_8197G_ANT_SWITCH) #define CONFIG_PHYDM_ANTENNA_DIVERSITY #define ODM_EVM_ENHANCE_ANTDIV /*#define SKIP_EVM_ANTDIV_TRAINING_PATCH*/ @@ -157,6 +171,15 @@ #define CONFIG_2G_CG_TRX_DIVERSITY #endif + /*----------*/ + #ifdef CONFIG_NO_2G_DIVERSITY_8197G + #define CONFIG_NO_2G_DIVERSITY + #elif defined(CONFIG_2G_CGCS_RX_DIVERSITY_8197G) + #define CONFIG_2G_CGCS_RX_DIVERSITY + #elif defined(CONFIG_2G_CG_TRX_DIVERSITY_8197G) + #define CONFIG_2G_CG_TRX_DIVERSITY + #endif + #if (!defined(CONFIG_NO_2G_DIVERSITY) && !defined(CONFIG_2G5G_CG_TRX_DIVERSITY_8881A) && !defined(CONFIG_2G_CGCS_RX_DIVERSITY) && !defined(CONFIG_2G_CG_TRX_DIVERSITY) && !defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY)) #define CONFIG_NO_2G_DIVERSITY #endif diff --git a/hal/phydm/phydm_features_ce.h b/hal/phydm/phydm_features_ce.h index ee06e0c..24f3772 100644 --- a/hal/phydm/phydm_features_ce.h +++ b/hal/phydm/phydm_features_ce.h @@ -28,7 +28,7 @@ #if (RTL8814A_SUPPORT || RTL8821C_SUPPORT || RTL8822B_SUPPORT ||\ RTL8197F_SUPPORT || RTL8192F_SUPPORT || RTL8198F_SUPPORT ||\ - RTL8822C_SUPPORT) + RTL8822C_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_LA_MODE_SUPPORT 1 #else #define PHYDM_LA_MODE_SUPPORT 0 @@ -39,9 +39,14 @@ #define DYN_ANT_WEIGHTING_SUPPORT #endif -#if (RTL8822B_SUPPORT || RTL8821C_SUPPORT) +#if (RTL8822B_SUPPORT || RTL8821C_SUPPORT || RTL8822C_SUPPORT ||\ + RTL8814B_SUPPORT || RTL8723F_SUPPORT) #define FAHM_SUPPORT #endif + +#if (RTL8822C_SUPPORT || RTL8723F_SUPPORT) + #define IFS_CLM_SUPPORT +#endif #define NHM_SUPPORT #define CLM_SUPPORT @@ -56,7 +61,7 @@ /*@#define PHYDM_TDMA_DIG_SUPPORT*/ #if (RTL8822B_SUPPORT || RTL8192F_SUPPORT || RTL8821C_SUPPORT ||\ - RTL8822C_SUPPORT || RTL8723D_SUPPORT) + RTL8822C_SUPPORT || RTL8723D_SUPPORT ) #ifdef CONFIG_TDMADIG #define PHYDM_TDMA_DIG_SUPPORT #ifdef PHYDM_TDMA_DIG_SUPPORT @@ -90,15 +95,15 @@ #endif #endif -#if (RTL8822B_SUPPORT || RTL8192F_SUPPORT) +#if (RTL8822B_SUPPORT || RTL8192F_SUPPORT || RTL8723D_SUPPORT) #define PHYDM_POWER_TRAINING_SUPPORT #endif -#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT) +#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_PMAC_TX_SETTING_SUPPORT #endif -#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT) +#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_MP_SUPPORT #endif @@ -127,6 +132,10 @@ #define CONFIG_RECEIVER_BLOCKING #endif +#if (RTL8821C_SUPPORT || RTL8822C_SUPPORT || RTL8822B_SUPPORT) + #define CONFIG_BW_INDICATION +#endif + #if (RTL8192F_SUPPORT) /*#define CONFIG_8912F_SPUR_CALIBRATION*/ #endif @@ -138,6 +147,9 @@ #ifdef CONFIG_SUPPORT_DYNAMIC_TXPWR #define CONFIG_DYNAMIC_TX_TWR #endif +#if (RTL8822C_SUPPORT) +#define PHYDM_HW_IGI +#endif #define PHYDM_SUPPORT_CCKPD #define PHYDM_SUPPORT_ADAPTIVITY @@ -149,7 +161,7 @@ #if (RTL8723B_SUPPORT || RTL8821A_SUPPORT ||\ RTL8188F_SUPPORT || RTL8821C_SUPPORT ||\ - RTL8723D_SUPPORT) + RTL8723D_SUPPORT||RTL8723F_SUPPORT) #define CONFIG_S0S1_SW_ANTENNA_DIVERSITY #endif @@ -226,4 +238,8 @@ #define CONFIG_DIRECTIONAL_BF #endif +#if (RTL8822C_SUPPORT) + #define CONFIG_MU_RSOML +#endif + #endif diff --git a/hal/phydm/phydm_features_iot.h b/hal/phydm/phydm_features_iot.h index 59afe79..ce8793e 100644 --- a/hal/phydm/phydm_features_iot.h +++ b/hal/phydm/phydm_features_iot.h @@ -114,10 +114,14 @@ #ifdef CONFIG_PHYDM_ANTENNA_DIVERSITY #if (RTL8723B_SUPPORT || RTL8821A_SUPPORT ||\ - RTL8188F_SUPPORT || RTL8821C_SUPPORT) + RTL8188F_SUPPORT || RTL8821C_SUPPORT || RTL8195B_SUPPORT) #define CONFIG_S0S1_SW_ANTENNA_DIVERSITY #endif - + + #if (RTL8710C_SUPPORT) + //#define CONFIG_S0S1_SW_ANTENNA_DIVERSITY + #endif + #if (RTL8821A_SUPPORT) /*#define CONFIG_HL_SMART_ANTENNA_TYPE1*/ #endif @@ -150,7 +154,9 @@ /*#define CONFIG_PATH_DIVERSITY*/ /*#define CONFIG_RA_DYNAMIC_RTY_LIMIT*/ //#define CONFIG_BB_TXBF_API +#if DBG #define CONFIG_PHYDM_DEBUG_FUNCTION +#endif #ifdef CONFIG_BT_COEXIST #define ODM_CONFIG_BT_COEXIST diff --git a/hal/phydm/phydm_features_win.h b/hal/phydm/phydm_features_win.h index 122a00b..824699e 100644 --- a/hal/phydm/phydm_features_win.h +++ b/hal/phydm/phydm_features_win.h @@ -18,7 +18,7 @@ #if (RTL8814A_SUPPORT || RTL8821C_SUPPORT || RTL8822B_SUPPORT ||\ RTL8197F_SUPPORT || RTL8192F_SUPPORT || RTL8198F_SUPPORT ||\ - RTL8822C_SUPPORT || RTL8814B_SUPPORT) + RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_LA_MODE_SUPPORT 1 #else #define PHYDM_LA_MODE_SUPPORT 0 @@ -29,9 +29,14 @@ #define DYN_ANT_WEIGHTING_SUPPORT #endif -#if (RTL8822B_SUPPORT || RTL8821C_SUPPORT) +#if (RTL8822B_SUPPORT || RTL8821C_SUPPORT || RTL8822C_SUPPORT ||\ + RTL8814B_SUPPORT || RTL8723F_SUPPORT) #define FAHM_SUPPORT #endif + +#if (RTL8822C_SUPPORT || RTL8723F_SUPPORT) + #define IFS_CLM_SUPPORT +#endif #define NHM_SUPPORT #define CLM_SUPPORT @@ -40,7 +45,7 @@ #endif #if (RTL8822C_SUPPORT) - /*#define PHYDM_PHYSTAUS_AUTO_SWITCH*/ + #define PHYDM_PHYSTAUS_AUTO_SWITCH #endif /*#define PHYDM_TDMA_DIG_SUPPORT*/ @@ -75,11 +80,11 @@ #define PHYDM_POWER_TRAINING_SUPPORT #endif -#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT) +#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_PMAC_TX_SETTING_SUPPORT #endif -#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT) +#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_MP_SUPPORT #endif @@ -156,6 +161,10 @@ #define CONFIG_RECEIVER_BLOCKING #endif +#if (RTL8821C_SUPPORT || RTL8822C_SUPPORT || RTL8822B_SUPPORT) + #define CONFIG_BW_INDICATION +#endif + #if (RTL8812A_SUPPORT || RTL8821A_SUPPORT || RTL8881A_SUPPORT ||\ RTL8192E_SUPPORT || RTL8723B_SUPPORT) #define CONFIG_RA_FW_DBG_CODE @@ -164,9 +173,15 @@ /* #ifdef CONFIG_SUPPORT_DYNAMIC_TXPWR */ #define CONFIG_DYNAMIC_TX_TWR /* #endif */ +#if (RTL8822C_SUPPORT) +#define PHYDM_HW_IGI +#endif #define CONFIG_PSD_TOOL #define PHYDM_SUPPORT_ADAPTIVITY #define PHYDM_SUPPORT_CCKPD +#if (defined(PHYDM_SUPPORT_CCKPD) && RTL8822C_SUPPORT) + #define PHYDM_DCC_ENHANCE +#endif /*#define CONFIG_RA_DYNAMIC_RTY_LIMIT*/ #define CONFIG_ANT_DETECTION #define CONFIG_BB_TXBF_API diff --git a/hal/phydm/phydm_hwconfig.c b/hal/phydm/phydm_hwconfig.c index f3d96bb..d3153b5 100644 --- a/hal/phydm/phydm_hwconfig.c +++ b/hal/phydm/phydm_hwconfig.c @@ -251,8 +251,8 @@ odm_config_rf_with_header_file(struct dm_struct *dm, READ_AND_CONFIG_MP(8822b, _txpwr_lmt_type17); else if (dm->rfe_type == 18) READ_AND_CONFIG_MP(8822b, _txpwr_lmt_type18); - else if (dm->rfe_type == 19) - READ_AND_CONFIG_MP(8822b, _txpwr_lmt_type19); + //else if (dm->rfe_type == 19) + //READ_AND_CONFIG_MP(8822b, _txpwr_lmt_type19); else READ_AND_CONFIG_MP(8822b, _txpwr_lmt); } @@ -428,10 +428,25 @@ odm_config_rf_with_header_file(struct dm_struct *dm, else if (e_rf_path == RF_PATH_B) READ_AND_CONFIG_MP(8822c, _radiob); } else if (config_type == CONFIG_RF_TXPWR_LMT) { - READ_AND_CONFIG_MP(8822c, _txpwr_lmt); + if (dm->rfe_type == 5) + READ_AND_CONFIG_MP(8822c, _txpwr_lmt_type5); + else + READ_AND_CONFIG_MP(8822c, _txpwr_lmt); } } #endif +#if (RTL8723F_SUPPORT) + if (dm->support_ic_type == ODM_RTL8723F) { + if (config_type == CONFIG_RF_RADIO) { + if (e_rf_path == RF_PATH_A) + READ_AND_CONFIG_MP(8723f, _radioa); + else if (e_rf_path == RF_PATH_B) + READ_AND_CONFIG_MP(8723f, _radiob); + } else if (config_type == CONFIG_RF_TXPWR_LMT) { + READ_AND_CONFIG_MP(8723f, _txpwr_lmt); + } + } +#endif #if (RTL8812F_SUPPORT) if (dm->support_ic_type == ODM_RTL8812F) { if (config_type == CONFIG_RF_RADIO) { @@ -665,8 +680,8 @@ odm_config_rf_with_tx_pwr_track_header_file(struct dm_struct *dm) READ_AND_CONFIG_MP(8822b, _txpowertrack_type17); else if (dm->rfe_type == 18) READ_AND_CONFIG_MP(8822b, _txpowertrack_type18); - else if (dm->rfe_type == 19) - READ_AND_CONFIG_MP(8822b, _txpowertrack_type19); + //else if (dm->rfe_type == 19) + //READ_AND_CONFIG_MP(8822b, _txpowertrack_type19); else READ_AND_CONFIG_MP(8822b, _txpowertrack); } @@ -807,8 +822,13 @@ odm_config_rf_with_tx_pwr_track_header_file(struct dm_struct *dm) #if RTL8195B_SUPPORT if (dm->support_ic_type == ODM_RTL8195B) { - READ_AND_CONFIG_MP(8195b, _txpowertrack); - READ_AND_CONFIG_MP(8195b, _txxtaltrack); + if (dm->package_type == 1) { + READ_AND_CONFIG_MP(8195b, _txpowertrack_pkg1); + READ_AND_CONFIG_MP(8195b, _txxtaltrack_pkg1); + } else { + READ_AND_CONFIG_MP(8195b, _txpowertrack); + READ_AND_CONFIG_MP(8195b, _txxtaltrack); + } } #endif @@ -821,6 +841,15 @@ odm_config_rf_with_tx_pwr_track_header_file(struct dm_struct *dm) } #endif +#if (RTL8723F_SUPPORT) + if (dm->support_ic_type == ODM_RTL8723F) { + if (dm->en_tssi_mode) + READ_AND_CONFIG_MP(8723f, _txpowertracktssi); + else + READ_AND_CONFIG_MP(8723f, _txpowertrack); + READ_AND_CONFIG_MP(8723f, _txxtaltrack); + } +#endif #if (RTL8812F_SUPPORT) if (dm->support_ic_type == ODM_RTL8812F) { if (dm->rfe_type == 0) @@ -831,6 +860,10 @@ odm_config_rf_with_tx_pwr_track_header_file(struct dm_struct *dm) READ_AND_CONFIG_MP(8812f, _txpowertrack_type2); else if (dm->rfe_type == 3) READ_AND_CONFIG_MP(8812f, _txpowertrack_type3); + else if (dm->rfe_type == 4) + READ_AND_CONFIG_MP(8812f, _txpowertrack_type4); + else if (dm->rfe_type == 5) + READ_AND_CONFIG_MP(8812f, _txpowertrack_type5); else READ_AND_CONFIG_MP(8812f, _txpowertrack); } @@ -1068,8 +1101,8 @@ odm_config_bb_with_header_file(struct dm_struct *dm, READ_AND_CONFIG_MP(8822b, _phy_reg_pg_type17); else if (dm->rfe_type == 18) READ_AND_CONFIG_MP(8822b, _phy_reg_pg_type18); - else if (dm->rfe_type == 19) - READ_AND_CONFIG_MP(8822b, _phy_reg_pg_type19); + //else if (dm->rfe_type == 19) + //READ_AND_CONFIG_MP(8822b, _phy_reg_pg_type19); else READ_AND_CONFIG_MP(8822b, _phy_reg_pg); } @@ -1228,12 +1261,18 @@ odm_config_bb_with_header_file(struct dm_struct *dm, #endif #if (RTL8195B_SUPPORT == 1) if (dm->support_ic_type == ODM_RTL8195B) { - if (config_type == CONFIG_BB_PHY_REG) + if (config_type == CONFIG_BB_PHY_REG) { READ_AND_CONFIG(8195b, _phy_reg); - else if (config_type == CONFIG_BB_AGC_TAB) + } else if (config_type == CONFIG_BB_AGC_TAB) { READ_AND_CONFIG(8195b, _agc_tab); - else if (config_type == CONFIG_BB_PHY_REG_PG) + } else if (config_type == CONFIG_BB_PHY_REG_PG) { READ_AND_CONFIG(8195b, _phy_reg_pg); + } else if (config_type == CONFIG_BB_PHY_REG_MP) { + if (dm->package_type == 1) + odm_set_bb_reg(dm, R_0xaa8, 0x1f0000, 0x10); + else + odm_set_bb_reg(dm, R_0xaa8, 0x1f0000, 0x12); + } } #endif #if (RTL8198F_SUPPORT == 1) @@ -1268,6 +1307,16 @@ odm_config_bb_with_header_file(struct dm_struct *dm, READ_AND_CONFIG(8822c, _phy_reg_pg); } #endif +#if (RTL8723F_SUPPORT) + if (dm->support_ic_type == ODM_RTL8723F) { + if (config_type == CONFIG_BB_PHY_REG) + READ_AND_CONFIG_MP(8723f, _phy_reg); + else if (config_type == CONFIG_BB_AGC_TAB) + READ_AND_CONFIG_MP(8723f, _agc_tab); + else if (config_type == CONFIG_BB_PHY_REG_PG) + READ_AND_CONFIG(8723f, _phy_reg_pg); + } +#endif #if (RTL8812F_SUPPORT) if (dm->support_ic_type == ODM_RTL8812F) { if (config_type == CONFIG_BB_PHY_REG) @@ -1317,9 +1366,8 @@ odm_config_mac_with_header_file(struct dm_struct *dm) "support_platform: 0x%X, support_interface: 0x%X, board_type: 0x%X\n", dm->support_platform, dm->support_interface, dm->board_type); -#if (RTL8822C_SUPPORT || RTL8812F_SUPPORT || RTL8814B_SUPPORT) - if (dm->support_ic_type & - (ODM_RTL8822C | ODM_RTL8812F | ODM_RTL8814B)) { +#ifdef PHYDM_IC_HALMAC_PARAM_SUPPORT + if (dm->support_ic_type & PHYDM_IC_SUPPORT_HALMAC_PARAM_OFFLOAD) { PHYDM_DBG(dm, ODM_COMP_INIT, "MAC para-package in HALMAC\n"); return result; } @@ -1541,6 +1589,11 @@ u32 odm_get_hw_img_version(struct dm_struct *dm) version = odm_get_version_mp_8197g_phy_reg(); break; #endif +#if (RTL8723F_SUPPORT) + case ODM_RTL8723F: + version = odm_get_version_mp_8723f_phy_reg(); + break; +#endif #if (RTL8814B_SUPPORT) case ODM_RTL8814B: version = odm_get_version_mp_8814b_phy_reg(); diff --git a/hal/phydm/phydm_interface.c b/hal/phydm/phydm_interface.c index ed832c4..7a0c428 100644 --- a/hal/phydm/phydm_interface.c +++ b/hal/phydm/phydm_interface.c @@ -705,9 +705,6 @@ void odm_initialize_timer(struct dm_struct *dm, struct phydm_timer_list *timer, init_timer(timer); timer->function = call_back_func; timer->data = (unsigned long)dm; -#if 0 - /*@mod_timer(timer, jiffies+RTL_MILISECONDS_TO_JIFFIES(10)); */ -#endif #elif (DM_ODM_SUPPORT_TYPE & ODM_CE) && defined(DM_ODM_CE_MAC80211) timer_setup(timer, call_back_func, 0); #elif (DM_ODM_SUPPORT_TYPE & ODM_CE) @@ -793,7 +790,7 @@ u8 phydm_trans_h2c_id(struct dm_struct *dm, u8 phydm_h2c_id) #elif (DM_ODM_SUPPORT_TYPE & ODM_AP) #if ((RTL8881A_SUPPORT == 1) || (RTL8192E_SUPPORT == 1) || (RTL8814A_SUPPORT == 1) || (RTL8822B_SUPPORT == 1) || (RTL8197F_SUPPORT == 1) || (RTL8192F_SUPPORT == 1)) /*@jj add 20170822*/ - if (dm->support_ic_type == ODM_RTL8881A || dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type & PHYDM_IC_3081_SERIES) + if (dm->support_ic_type & (ODM_RTL8881A | ODM_RTL8192E | ODM_RTL8192F | PHYDM_IC_3081_SERIES)) platform_h2c_id = H2C_88XX_RSSI_REPORT; else #endif @@ -855,7 +852,7 @@ u8 phydm_trans_h2c_id(struct dm_struct *dm, u8 phydm_h2c_id) #elif (DM_ODM_SUPPORT_TYPE & ODM_AP) #if ((RTL8881A_SUPPORT == 1) || (RTL8192E_SUPPORT == 1) || (RTL8814A_SUPPORT == 1) || (RTL8822B_SUPPORT == 1) || (RTL8197F_SUPPORT == 1) || (RTL8192F_SUPPORT == 1)) /*@jj add 20170822*/ - if (dm->support_ic_type == ODM_RTL8881A || dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type & PHYDM_IC_3081_SERIES) + if (dm->support_ic_type & (ODM_RTL8881A | ODM_RTL8192E | ODM_RTL8192F | PHYDM_IC_3081_SERIES)) platform_h2c_id = H2C_88XX_RA_PARA_ADJUST; else #endif @@ -906,7 +903,7 @@ u8 phydm_trans_h2c_id(struct dm_struct *dm, u8 phydm_h2c_id) #elif (DM_ODM_SUPPORT_TYPE & ODM_AP) #if ((RTL8881A_SUPPORT == 1) || (RTL8192E_SUPPORT == 1) || (RTL8814A_SUPPORT == 1) || (RTL8822B_SUPPORT == 1) || (RTL8197F_SUPPORT == 1) || (RTL8192F_SUPPORT == 1)) /*@jj add 20170822*/ - if (dm->support_ic_type == ODM_RTL8881A || dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type & PHYDM_IC_3081_SERIES) + if (dm->support_ic_type & (ODM_RTL8881A | ODM_RTL8192E | ODM_RTL8192F | PHYDM_IC_3081_SERIES)) platform_h2c_id = H2C_88XX_FW_TRACE_EN; else #endif @@ -924,7 +921,8 @@ u8 phydm_trans_h2c_id(struct dm_struct *dm, u8 phydm_h2c_id) case PHYDM_H2C_TXBF: #if ((RTL8192E_SUPPORT == 1) || (RTL8812A_SUPPORT == 1)) - platform_h2c_id = 0x41; /*@H2C_TxBF*/ + if (dm->support_ic_type & (ODM_RTL8192E | ODM_RTL8812)) + platform_h2c_id = 0x41; /*@H2C_TxBF*/ #endif break; @@ -1272,7 +1270,7 @@ odm_dpk_by_fw(struct dm_struct *dm) #if (DM_ODM_SUPPORT_TYPE & ODM_WIN) struct _ADAPTER *adapter = dm->adapter; - if (HAL_MAC_FWDPK_Trigger(&GET_HAL_MAC_INFO(adapter)) == 0) + if (hal_mac_fwdpk_trigger(&GET_HAL_MAC_INFO(adapter)) == 0) dpk_result = HAL_STATUS_SUCCESS; #else dpk_result = rtw_phydm_fw_dpk(dm); @@ -1332,82 +1330,6 @@ void phydm_enable_rx_related_interrupt_handler(struct dm_struct *dm) #endif } -#if 0 -boolean -phydm_get_txbf_en( - struct dm_struct *dm, - u16 mac_id, - u8 i -) -{ - boolean txbf_en = false; - -#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) -#elif (DM_ODM_SUPPORT_TYPE & ODM_CE) && !defined(DM_ODM_CE_MAC80211) - -#ifdef CONFIG_BEAMFORMING - enum beamforming_cap beamform_cap; - void *adapter = dm->adapter; - #ifdef PHYDM_BEAMFORMING_SUPPORT - beamform_cap = - phydm_beamforming_get_entry_beam_cap_by_mac_id(dm, mac_id); - #else/*@for drv beamforming*/ - beamform_cap = - beamforming_get_entry_beam_cap_by_mac_id(&adapter->mlmepriv, mac_id); - #endif - if (beamform_cap & (BEAMFORMER_CAP_HT_EXPLICIT | BEAMFORMER_CAP_VHT_SU)) - txbf_en = true; - else - txbf_en = false; -#endif /*@#ifdef CONFIG_BEAMFORMING*/ - -#elif (DM_ODM_SUPPORT_TYPE & ODM_AP) - -#ifdef PHYDM_BEAMFORMING_SUPPORT - u8 idx = 0xff; - boolean act_bfer = false; - BEAMFORMING_CAP beamform_cap = BEAMFORMING_CAP_NONE; - PRT_BEAMFORMING_ENTRY entry = NULL; - struct rtl8192cd_priv *priv = dm->priv; - #if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) - struct _BF_DIV_COEX_ *dm_bdc_table = &dm->dm_bdc_table; - - dm_bdc_table->num_txbfee_client = 0; - dm_bdc_table->num_txbfer_client = 0; - #endif -#endif - -#ifdef PHYDM_BEAMFORMING_SUPPORT - beamform_cap = Beamforming_GetEntryBeamCapByMacId(priv, mac_id); - entry = Beamforming_GetEntryByMacId(priv, mac_id, &idx); - if (beamform_cap & (BEAMFORMER_CAP_HT_EXPLICIT | BEAMFORMER_CAP_VHT_SU)) { - if (entry->Sounding_En) - txbf_en = true; - else - txbf_en = false; - act_bfer = true; - } - #if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) /*@BDC*/ - if (act_bfer == true) { - dm_bdc_table->w_bfee_client[i] = true; /* @AP act as BFer */ - dm_bdc_table->num_txbfee_client++; - } else - dm_bdc_table->w_bfee_client[i] = false; /* @AP act as BFer */ - - if (beamform_cap & (BEAMFORMEE_CAP_HT_EXPLICIT | BEAMFORMEE_CAP_VHT_SU)) { - dm_bdc_table->w_bfer_client[i] = true; /* @AP act as BFee */ - dm_bdc_table->num_txbfer_client++; - } else - dm_bdc_table->w_bfer_client[i] = false; /* @AP act as BFer */ - - #endif -#endif - -#endif - return txbf_en; -} -#endif - void phydm_iqk_wait(struct dm_struct *dm, u32 timeout) { #if (DM_ODM_SUPPORT_TYPE == ODM_CE) @@ -1518,6 +1440,33 @@ u8 phydm_get_tx_power_dbm(struct dm_struct *dm, u8 rf_path, return tx_power_dbm; } +s16 phydm_get_tx_power_mdbm(struct dm_struct *dm, u8 rf_path, + u8 rate, u8 bandwidth, u8 channel) +{ + s16 tx_power_dbm = 0; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + struct _ADAPTER *adapter = dm->adapter; + tx_power_dbm = PHY_GetTxPowerFinalAbsoluteValuemdBm(adapter, rf_path, rate, bandwidth, channel); +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + tx_power_dbm = rtw_odm_get_tx_power_mbm(dm, rf_path, rate, bandwidth, channel); +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + tx_power_dbm = PHY_GetTxPowerFinalAbsoluteValuembm(dm, rf_path, rate, bandwidth, channel); +#endif + return tx_power_dbm; +} + +u32 phydm_rfe_ctrl_gpio(struct dm_struct *dm, u8 gpio_num) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + return rtw_phydm_rfe_ctrl_gpio(dm->adapter, gpio_num); +#endif + return 0; +} + u64 phydm_division64(u64 x, u64 y) { #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) diff --git a/hal/phydm/phydm_interface.h b/hal/phydm/phydm_interface.h index 37a518a..2c75a23 100644 --- a/hal/phydm/phydm_interface.h +++ b/hal/phydm/phydm_interface.h @@ -48,6 +48,7 @@ enum phydm_h2c_cmd { PHYDM_H2C_MCC = 0x4f, PHYDM_H2C_RESP_TX_PATH_CTRL = 0x50, PHYDM_H2C_RESP_TX_ANT_CTRL = 0x51, + PHYDM_H2C_FW_DM_CTRL = 0x55, ODM_MAX_H2CCMD }; @@ -92,21 +93,6 @@ enum phydm_halmac_param { #define _bit_all(_name) BIT_##_name #define _bit_ic(_name, _ic) BIT_##_name##_ic -/* @_cat: implemented by Token-Pasting Operator. */ -#if 0 -#define _cat(_name, _ic_type, _func) \ - ( \ - _func##_all(_name)) -#endif - -#if 0 - -#define ODM_REG_DIG_11N 0xC50 -#define ODM_REG_DIG_11AC 0xDDD - -ODM_REG(DIG,_pdm_odm) -#endif - #if defined(DM_ODM_CE_MAC80211) #define ODM_BIT(name, dm) \ ((dm->support_ic_type & ODM_IC_11N_SERIES) ? \ @@ -322,15 +308,6 @@ void phydm_add_interrupt_mask_handler(struct dm_struct *dm, u8 interrupt_type); void phydm_enable_rx_related_interrupt_handler(struct dm_struct *dm); -#if 0 -boolean -phydm_get_txbf_en( - struct dm_struct *dm, - u16 mac_id, - u8 i -); -#endif - void phydm_iqk_wait(struct dm_struct *dm, u32 timeout); u8 phydm_get_hwrate_to_mrate(struct dm_struct *dm, u8 rate); @@ -340,6 +317,12 @@ void phydm_run_in_thread_cmd(struct dm_struct *dm, void (*func)(void *), u8 phydm_get_tx_rate(struct dm_struct *dm); u8 phydm_get_tx_power_dbm(struct dm_struct *dm, u8 rf_path, u8 rate, u8 bandwidth, u8 channel); + +s16 phydm_get_tx_power_mdbm(struct dm_struct *dm, u8 rf_path, + u8 rate, u8 bandwidth, u8 channel); + +u32 phydm_rfe_ctrl_gpio(struct dm_struct *dm, u8 gpio_num); + u64 phydm_division64(u64 x, u64 y); #endif /* @__ODM_INTERFACE_H__ */ diff --git a/hal/phydm/phydm_lna_sat.c b/hal/phydm/phydm_lna_sat.c index 9288610..f48ae5c 100644 --- a/hal/phydm/phydm_lna_sat.c +++ b/hal/phydm/phydm_lna_sat.c @@ -55,8 +55,7 @@ void phydm_lna_sat_chk_init( lna_info->pre_timer_check_cnt = 0; #if (RTL8198F_SUPPORT || RTL8814B_SUPPORT) - if (dm->support_ic_type & - (ODM_RTL8198F | ODM_RTL8814B)) + if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B)) phydm_lna_sat_chk_bb_init(dm); #endif } @@ -519,7 +518,7 @@ void phydm_lna_sat_chk_watchdog_type1( u8 rssi_min = dm->rssi_min; - PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "\n%s ==>\n", __func__); + PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__); if (!(dm->support_ability & ODM_BB_LNA_SAT_CHK)) { PHYDM_DBG(dm, DBG_LNA_SAT_CHK, @@ -540,13 +539,6 @@ void phydm_lna_sat_chk_watchdog_type1( return; } - if (!(dm->support_ic_type & - (ODM_RTL8197F | ODM_RTL8198F | ODM_RTL8814B))) { - PHYDM_DBG(dm, DBG_LNA_SAT_CHK, - "support_ic_type not 97F/98F/14B, return\n"); - return; - } - if (rssi_min == 0 || rssi_min == 0xff) { /*@adapt agc table 0 */ phydm_set_ofdm_agc_tab(dm, OFDM_AGC_TAB_0); @@ -621,10 +613,6 @@ void phydm_snr_collect( struct phydm_lna_sat_t *pinfo = &dm->dm_lna_sat_info; if (pinfo->is_sm_done) { -#if 0 - /*PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__);*/ -#endif - /* @adapt only path-A for calculation */ pinfo->snr_statistic[pinfo->cnt_snr_statistic] = rx_snr; @@ -1160,16 +1148,365 @@ void phydm_lna_sat_type2_sm( return; } } - - #endif /*@#ifdef PHYDM_LNA_SAT_CHK_TYPE2*/ -void phydm_lna_sat_debug( - void *dm_void, - char input[][16], - u32 *_used, - char *output, - u32 *_out_len) +#ifdef PHYDM_HW_SWITCH_AGC_TAB +u32 phydm_get_lna_pd_reg(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 rf_pd_reg = RF_0x8b; + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) { + if (*dm->channel <= 14) + rf_pd_reg = RF_0x87; + else + rf_pd_reg = RF_0x8b; + } +#endif + return rf_pd_reg; +} + +u32 phydm_get_lna_pd_en_mask(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 rf_pd_en_msk = BIT(2); + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) { + if (*dm->channel <= 14) + rf_pd_en_msk = BIT(4); + else + rf_pd_en_msk = BIT(2); + } +#endif + return rf_pd_en_msk; +} + +boolean phydm_get_lna_pd_en(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 rf_pd_reg = RF_0x8b; + u32 rf_pd_en_msk = BIT(2); + u32 pd_en = 0; + + rf_pd_reg = phydm_get_lna_pd_reg(dm); + rf_pd_en_msk = phydm_get_lna_pd_en_mask(dm); + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) + pd_en = config_phydm_read_rf_reg_8814b(dm, RF_PATH_A, + rf_pd_reg, + rf_pd_en_msk); +#endif + return (boolean)pd_en; +} + +void phydm_set_lna_pd_en(void *dm_void, boolean lna_pd_en) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + enum rf_path i = RF_PATH_A; + u32 rf_pd_reg = RF_0x8b; + u32 rf_pd_en_msk = BIT(2); + + rf_pd_reg = phydm_get_lna_pd_reg(dm); + rf_pd_en_msk = phydm_get_lna_pd_en_mask(dm); + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) + for (i = RF_PATH_A; i < MAX_PATH_NUM_8814B; i++) + config_phydm_write_rf_reg_8814b(dm, i, + rf_pd_reg, + rf_pd_en_msk, + (u8)lna_pd_en); +#endif +} + +u32 phydm_get_lna_pd_th_mask(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 rf_pd_th_msk = 0x3; + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) + rf_pd_th_msk = 0x3; +#endif + return rf_pd_th_msk; +} + +enum lna_pd_th_level phydm_get_lna_pd_th_lv(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 rf_pd_reg = RF_0x8b; + u32 rf_pd_th_msk = 0x3; + u32 pd_th_lv = 0x0; + + rf_pd_reg = phydm_get_lna_pd_reg(dm); + rf_pd_th_msk = phydm_get_lna_pd_th_mask(dm); + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) + pd_th_lv = config_phydm_read_rf_reg_8814b(dm, RF_PATH_A, + rf_pd_reg, + rf_pd_th_msk); +#endif + return (enum lna_pd_th_level)pd_th_lv; +} + +void phydm_set_lna_pd_th_lv(void *dm_void, + enum lna_pd_th_level lna_pd_th_lv) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + enum rf_path i = RF_PATH_A; + u32 rf_pd_reg = RF_0x8b; + u32 rf_pd_th_msk = 0x3; + + rf_pd_reg = phydm_get_lna_pd_reg(dm); + rf_pd_th_msk = phydm_get_lna_pd_th_mask(dm); + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) + for (i = RF_PATH_A; i < MAX_PATH_NUM_8814B; i++) + config_phydm_write_rf_reg_8814b(dm, i, + rf_pd_reg, + rf_pd_th_msk, + lna_pd_th_lv); +#endif +} + +u32 phydm_get_sat_agc_tab_version(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) + return odm_get_version_mp_8814b_extra_agc_tab(); +#endif + return 0; +} + +boolean phydm_get_auto_agc_config(void *dm_void, + enum agc_tab_switch_state state_sel) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 state_en = 0; +#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT + switch (state_sel) { + case AGC_SWH_IDLE: + state_en = odm_get_bb_reg(dm, R_0x18ac, BIT(16)); + break; + case AGC_SWH_OFDM: + state_en = odm_get_bb_reg(dm, R_0x18ac, BIT(17)); + break; + case AGC_SWH_CCK: + state_en = odm_get_bb_reg(dm, R_0x18ac, BIT(18)); + break; + default: + state_en = 0; + break; + } +#endif + return (boolean)state_en; +} + +boolean phydm_is_auto_agc_on(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + boolean state_on = false; + + state_on = ((phydm_get_auto_agc_config(dm, AGC_SWH_IDLE) || + phydm_get_auto_agc_config(dm, AGC_SWH_CCK) || + phydm_get_auto_agc_config(dm, AGC_SWH_OFDM)) && + phydm_get_lna_pd_en(dm)); + + return state_on; +} + +void phydm_config_auto_agc(void *dm_void, + boolean idle_en, + boolean cck_cca_en, + boolean ofdm_cca_en) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 hwagc_opt = 0; +#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT + if (dm->support_ic_type & ~ODM_RTL8814B) + return; + + if (idle_en) + hwagc_opt |= BIT(0); + else + hwagc_opt &= ~BIT(0); + if (ofdm_cca_en) + hwagc_opt |= BIT(1); + else + hwagc_opt &= ~BIT(1); + if (cck_cca_en) + hwagc_opt |= BIT(2); + else + hwagc_opt &= ~BIT(2); + + odm_set_bb_reg(dm, R_0x18ac, BIT(18) | BIT(17) | BIT(16), hwagc_opt); +#ifdef PHYDM_COMPILE_ABOVE_2SS + odm_set_bb_reg(dm, R_0x41ac, BIT(18) | BIT(17) | BIT(16), hwagc_opt); +#endif +#ifdef PHYDM_COMPILE_ABOVE_3SS + odm_set_bb_reg(dm, R_0x52ac, BIT(18) | BIT(17) | BIT(16), hwagc_opt); +#endif +#ifdef PHYDM_COMPILE_ABOVE_4SS + odm_set_bb_reg(dm, R_0x53ac, BIT(18) | BIT(17) | BIT(16), hwagc_opt); +#endif +#endif +} + +void phydm_auto_agc_tab_reset(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + phydm_set_lna_pd_th_lv(dm, 0x0); + phydm_config_auto_agc(dm, true, false, true); + phydm_set_lna_pd_en(dm, true); +} + +void phydm_auto_agc_tab_off(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + phydm_config_auto_agc(dm, false, false, false); + phydm_set_lna_pd_en(dm, false); +} + +void phydm_switch_sat_agc_by_band(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_lna_sat_t *lna_sat = &dm->dm_lna_sat_info; + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) + odm_config_mp_8814b_extra_agc_tab(dm, lna_sat->cur_rf_band); +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + pr_debug("%s ==> switch to band%d\n", __func__, lna_sat->cur_rf_band); +#else + PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==> switch to band%d\n", + __func__, lna_sat->cur_rf_band); +#endif +} + +void phydm_auto_agc_tab_init(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_lna_sat_t *lna_sat = &dm->dm_lna_sat_info; + u8 channel = *dm->channel; + + lna_sat->cur_rf_band = phydm_ch_to_rf_band(dm, channel); + phydm_switch_sat_agc_by_band(dm); + + if ((dm->support_ability & ODM_BB_LNA_SAT_CHK)) { + phydm_auto_agc_tab_reset(dm); + lna_sat->hw_swh_tab_on = true; + } else { + phydm_auto_agc_tab_off(dm); + lna_sat->hw_swh_tab_on = false; + } +} + +void phydm_auto_agc_tab_watchdog(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_lna_sat_t *lna_sat = &dm->dm_lna_sat_info; + boolean hw_swh_on = false; + + PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__); + + if (!(dm->support_ability & ODM_BB_LNA_SAT_CHK)) { + if (lna_sat->hw_swh_tab_on) { + phydm_auto_agc_tab_off(dm); + lna_sat->hw_swh_tab_on = false; + } + PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "Disabled LNA sat. check\n"); + return; + } + + if (!lna_sat->hw_swh_tab_on) + PHYDM_DBG(dm, DBG_LNA_SAT_CHK, + "[WARNING] HW switch AGC Tab not fully enabled\n"); +} + +void phydm_auto_agc_tab_debug(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_lna_sat_t *lna_sat = &dm->dm_lna_sat_info; + char help[] = "-h"; + u32 var1[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u8 i; + u8 agc_tab = 0; + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "LNA sat. AGC Tab version : %d\n", + phydm_get_sat_agc_tab_version(dm)); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Enable LNA peak detector : {0} {lna_pd_en = %d}\n", + phydm_get_lna_pd_en(dm)); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Set LNA peak detector lv : {1} {lna_pd_th_lv = %d}\n", + phydm_get_lna_pd_th_lv(dm)); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Config hw switch AGC tab : {2} {hw_swh_en_rx_idle} {hw_swh_en_cck_cca} {hw_swh_en_ofdm_cca} = (%d, %d, %d)\n", + phydm_get_auto_agc_config(dm, AGC_SWH_IDLE), + phydm_get_auto_agc_config(dm, AGC_SWH_CCK), + phydm_get_auto_agc_config(dm, AGC_SWH_OFDM)); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Reset to default setting : {3}\n", + phydm_get_auto_agc_config(dm, AGC_SWH_IDLE), + phydm_get_auto_agc_config(dm, AGC_SWH_CCK), + phydm_get_auto_agc_config(dm, AGC_SWH_OFDM)); + + } else { + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + for (i = 1; i < 10; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + } + + if (var1[0] == 0) { + phydm_set_lna_pd_en(dm, (boolean)var1[1]); + PDM_SNPF(out_len, used, output + used, out_len - used, + "set lna_pd_en = %d\n", + (u8)phydm_get_lna_pd_en(dm)); + } else if (var1[0] == 1) { + phydm_set_lna_pd_th_lv(dm, (u8)var1[1]); + PDM_SNPF(out_len, used, output + used, out_len - used, + "set lna_pd_th_lv = %d\n", + phydm_get_lna_pd_th_lv(dm)); + } else if (var1[0] == 2) { + phydm_config_auto_agc(dm, (boolean)var1[1], + (boolean)var1[2], + (boolean)var1[3]); + PDM_SNPF(out_len, used, output + used, out_len - used, + "set hw switch agc tab en: (rx_idle, cck_cca, ofdm_cca) = (%d, %d, %d)\n", + phydm_get_auto_agc_config(dm, AGC_SWH_IDLE), + phydm_get_auto_agc_config(dm, AGC_SWH_CCK), + phydm_get_auto_agc_config(dm, AGC_SWH_OFDM)); + } else if (var1[0] == 3) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "reset to default settings\n"); + phydm_auto_agc_tab_reset(dm); + } + lna_sat->hw_swh_tab_on = phydm_is_auto_agc_on(dm); + } + *_used = used; + *_out_len = out_len; +} +#endif /*@#ifdef PHYDM_HW_SWITCH_AGC_TAB*/ + +void phydm_lna_sat_debug(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_lna_sat_t *lna_t = &dm->dm_lna_sat_info; @@ -1264,8 +1601,7 @@ void phydm_lna_sat_debug( *_out_len = out_len; } -void phydm_lna_sat_chk_watchdog( - void *dm_void) +void phydm_lna_sat_chk_watchdog(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_lna_sat_t *lna_sat = &dm->dm_lna_sat_info; @@ -1273,29 +1609,40 @@ void phydm_lna_sat_chk_watchdog( PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__); if (lna_sat->lna_sat_type == LNA_SAT_WITH_PEAK_DET) { + #ifdef PHYDM_HW_SWITCH_AGC_TAB + if (dm->support_ic_type & ODM_RTL8814B) { + phydm_auto_agc_tab_watchdog(dm); + return; + } + #endif #ifdef PHYDM_LNA_SAT_CHK_TYPE1 - phydm_lna_sat_chk_watchdog_type1(dm); + if (dm->support_ic_type & + (ODM_RTL8197F | ODM_RTL8198F | ODM_RTL8814B)) { + phydm_lna_sat_chk_watchdog_type1(dm); + return; + } #endif } else if (lna_sat->lna_sat_type == LNA_SAT_WITH_TRAIN) { #ifdef PHYDM_LNA_SAT_CHK_TYPE2 - + return; #endif } + PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "support_ic_type match fail, return\n"); } -void phydm_lna_sat_config( - void *dm_void) +void phydm_lna_sat_config(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_lna_sat_t *lna_sat = &dm->dm_lna_sat_info; + lna_sat->lna_sat_type = 0; #if (RTL8822B_SUPPORT == 1) if (dm->support_ic_type & (ODM_RTL8822B)) lna_sat->lna_sat_type = LNA_SAT_WITH_TRAIN; #endif - #if (RTL8197F_SUPPORT || RTL8192F_SUPPORT ||\ + #if (RTL8197F_SUPPORT || RTL8192F_SUPPORT || \ RTL8198F_SUPPORT || RTL8814B_SUPPORT) if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8192F | ODM_RTL8198F | ODM_RTL8814B)) @@ -1306,15 +1653,11 @@ void phydm_lna_sat_config( __func__, lna_sat->lna_sat_type); } -void phydm_lna_sat_check_init( - void *dm_void) +void phydm_lna_sat_check_init(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_lna_sat_t *lna_sat = &dm->dm_lna_sat_info; - if ((dm->support_ability & ODM_BB_LNA_SAT_CHK)) - return; - /*@2018.04.17 Johnson*/ phydm_lna_sat_config(dm); #ifdef PHYDM_LNA_SAT_CHK_TYPE1 @@ -1326,6 +1669,12 @@ void phydm_lna_sat_check_init( /*@2018.04.17 Johnson end*/ if (lna_sat->lna_sat_type == LNA_SAT_WITH_PEAK_DET) { + #ifdef PHYDM_HW_SWITCH_AGC_TAB + if (dm->support_ic_type & ODM_RTL8814B) { + phydm_auto_agc_tab_init(dm); + return; + } + #endif #ifdef PHYDM_LNA_SAT_CHK_TYPE1 phydm_lna_sat_chk_init(dm); #endif diff --git a/hal/phydm/phydm_lna_sat.h b/hal/phydm/phydm_lna_sat.h index c9345b8..69a9349 100644 --- a/hal/phydm/phydm_lna_sat.h +++ b/hal/phydm/phydm_lna_sat.h @@ -31,7 +31,7 @@ * 1 ============================================================ */ -#define LNA_SAT_VERSION "1.0" +#define LNA_SAT_VERSION "1.1" /*@LNA saturation check*/ #define OFDM_AGC_TAB_0 0 @@ -77,6 +77,21 @@ enum lna_sat_type { LNA_SAT_WITH_TRAIN = 2, /*type2*/ }; +#ifdef PHYDM_HW_SWITCH_AGC_TAB +enum lna_pd_th_level { + LNA_PD_TH_LEVEL0 = 0, + LNA_PD_TH_LEVEL1 = 1, + LNA_PD_TH_LEVEL2 = 2, + LNA_PD_TH_LEVEL3 = 3 +}; + +enum agc_tab_switch_state { + AGC_SWH_IDLE, + AGC_SWH_CCK, + AGC_SWH_OFDM +}; +#endif + /* @1 ============================================================ * 1 structure * 1 ============================================================ @@ -130,6 +145,10 @@ struct phydm_lna_sat_t { u32 check_time; boolean pre_sat_status; boolean cur_sat_status; +#ifdef PHYDM_HW_SWITCH_AGC_TAB + boolean hw_swh_tab_on; + enum odm_rf_band cur_rf_band; +#endif struct phydm_timer_list phydm_lna_sat_chk_timer; u32 cur_timer_check_cnt; u32 pre_timer_check_cnt; @@ -169,5 +188,9 @@ void phydm_lna_sat_chk_watchdog(void *dm_void); void phydm_lna_sat_check_init(void *dm_void); +#ifdef PHYDM_HW_SWITCH_AGC_TAB +void phydm_auto_agc_tab_debug(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); +#endif #endif /*@#if (PHYDM_LNA_SAT_CHK_SUPPORT == 1)*/ #endif diff --git a/hal/phydm/phydm_math_lib.c b/hal/phydm/phydm_math_lib.c index 8995d43..c6c1035 100644 --- a/hal/phydm/phydm_math_lib.c +++ b/hal/phydm/phydm_math_lib.c @@ -159,22 +159,28 @@ u32 odm_convert_to_db(u64 value) break; } + /*special cases*/ if (j == 0 && i == 0) goto end; + if (i == 3 && j == 0) { + if (db_invert_table[3][0] - value > + value - (db_invert_table[2][7] >> FRAC_BITS)) { + i = 2; + j = 7; + } + goto end; + } + + if (i < 3) + value = value << FRAC_BITS; /*@elements of row 0~2 shift left*/ + + /*compare difference to get precise dB*/ if (j == 0) { - if (i != 3) { - if (db_invert_table[i][0] - value > - value - db_invert_table[i - 1][7]) { - i = i - 1; - j = 7; - } - } else { - if (db_invert_table[3][0] - value > - value - db_invert_table[2][7]) { - i = 2; - j = 7; - } + if (db_invert_table[i][j] - value > + value - db_invert_table[i - 1][7]) { + i = i - 1; + j = 7; } } else { if (db_invert_table[i][j] - value > diff --git a/hal/phydm/phydm_mp.c b/hal/phydm/phydm_mp.c index 3af2c0c..4b2bd52 100644 --- a/hal/phydm/phydm_mp.c +++ b/hal/phydm/phydm_mp.c @@ -40,6 +40,8 @@ void phydm_mp_set_single_tone_jgr3(void *dm_void, boolean is_single_tone, struct phydm_mp *mp = &dm->dm_mp_table; u8 start = RF_PATH_A, end = RF_PATH_A; u8 i = 0; + u8 central_ch = 0; + boolean is_2g_ch = false; switch (path) { case RF_PATH_A: @@ -53,7 +55,7 @@ void phydm_mp_set_single_tone_jgr3(void *dm_void, boolean is_single_tone, start = RF_PATH_A; end = RF_PATH_B; break; -#if (RTL8814B_SUPPORT == 1 || RTL8198F_SUPPORT == 1) +#if (defined(PHYDM_COMPILE_IC_4SS)) case RF_PATH_AC: start = RF_PATH_A; end = RF_PATH_C; @@ -96,62 +98,115 @@ void phydm_mp_set_single_tone_jgr3(void *dm_void, boolean is_single_tone, break; #endif } + + central_ch = (u8)odm_get_rf_reg(dm, RF_PATH_A, RF_0x18, 0xff); + is_2g_ch = (central_ch <= 14) ? true : false; + if (is_single_tone) { - mp->rf_reg0 = odm_get_rf_reg(dm, RF_PATH_A, RF_0x00, 0xfffff); -#if 0 - mp->rfe_sel_a_0 = odm_get_bb_reg(dm, R_0x1840, MASKDWORD); - mp->rfe_sel_b_0 = odm_get_bb_reg(dm, R_0x4140, MASKDWORD); - mp->rfe_sel_c_0 = odm_get_bb_reg(dm, R_0x5240, MASKDWORD); - mp->rfe_sel_d_0 = odm_get_bb_reg(dm, R_0x5340, MASKDWORD); - mp->rfe_sel_a_1 = odm_get_bb_reg(dm, R_0x1844, MASKDWORD); - mp->rfe_sel_b_1 = odm_get_bb_reg(dm, R_0x4144, MASKDWORD); - mp->rfe_sel_c_1 = odm_get_bb_reg(dm, R_0x5244, MASKDWORD); - mp->rfe_sel_d_1 = odm_get_bb_reg(dm, R_0x5344, MASKDWORD); -#endif - /* Disable CCK and OFDM */ - odm_set_bb_reg(dm, R_0x1c3c, 0x3, 0x0); - for (i = start; i <= end; i++) { - /* @Tx mode: RF0x00[19:16]=4'b0010 */ - odm_set_rf_reg(dm, i, RF_0x0, 0xF0000, 0x2); - /* @Lowest RF gain index: RF_0x0[4:0] = 0*/ - odm_set_rf_reg(dm, i, RF_0x0, 0x1F, 0x0); - /* @RF LO enabled */ - odm_set_rf_reg(dm, i, RF_0x58, BIT(1), 0x1); + /*Disable CCA*/ + if (is_2g_ch) { /*CCK RxIQ weighting = [0,0]*/ + if(dm->support_ic_type & ODM_RTL8723F) { + odm_set_bb_reg(dm, R_0x2a24, BIT(13), 0x1); /*CCK*/ + } else { + odm_set_bb_reg(dm, R_0x1a9c, BIT(20), 0x0); + odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x3); + } } + odm_set_bb_reg(dm, R_0x1d58, 0xff8, 0x1ff); /*OFDM*/ + if (dm->support_ic_type & ODM_RTL8723F) { + odm_set_rf_reg(dm, RF_PATH_A, RF_0x5, BIT(0), 0x0); + for (i = start; i <= end; i++) { + mp->rf0[i] = odm_get_rf_reg(dm, i, RF_0x0, RFREG_MASK); + /*Tx mode: RF0x00[19:16]=4'b0010 */ + odm_set_rf_reg(dm, i, RF_0x0, 0xF0000, 0x2); + /*Lowest RF gain index: RF_0x1[5:0] TX power*/ + mp->rf1[i] = odm_get_rf_reg(dm, i, RF_0x1, RFREG_MASK); + odm_set_rf_reg(dm, i, RF_0x1, 0x3f, 0x0);//TX power + /*RF LO enabled */ + odm_set_rf_reg(dm, i, RF_0x58, BIT(1), 0x1); + } + } else { + for (i = start; i <= end; i++) { + mp->rf0[i] = odm_get_rf_reg(dm, i, RF_0x0, RFREG_MASK); + /*Tx mode: RF0x00[19:16]=4'b0010 */ + odm_set_rf_reg(dm, i, RF_0x0, 0xF0000, 0x2); + /*Lowest RF gain index: RF_0x0[4:0] = 0*/ + odm_set_rf_reg(dm, i, RF_0x0, 0x1f, 0x0); + /*RF LO enabled */ + odm_set_rf_reg(dm, i, RF_0x58, BIT(1), 0x1); + } + } + #if (RTL8814B_SUPPORT) if (dm->support_ic_type & ODM_RTL8814B) { - /* @Tx mode: RF0x00[19:16]=4'b0010 */ + mp->rf0_syn[RF_SYN0] = config_phydm_read_syn_reg_8814b( + dm, RF_SYN0, RF_0x0, RFREG_MASK); + /*Lowest RF gain index: RF_0x0[4:0] = 0x0*/ config_phydm_write_rf_syn_8814b(dm, RF_SYN0, RF_0x0, - 0xF0000, 0x2); - /* @Lowest RF gain index: RF_0x0[4:0] = 0*/ - config_phydm_write_rf_syn_8814b(dm, RF_SYN0, RF_0x0, - 0x1F, 0x0); - /* @RF LO enabled */ + 0x1f, 0x0); + /*RF LO enabled */ config_phydm_write_rf_syn_8814b(dm, RF_SYN0, RF_0x58, BIT(1), 0x1); + /*SYN1*/ + if (*dm->band_width == CHANNEL_WIDTH_80_80) { + mp->rf0_syn[RF_SYN1] = config_phydm_read_syn_reg_8814b( + dm, RF_SYN1, RF_0x0, + RFREG_MASK); + config_phydm_write_rf_syn_8814b(dm, RF_SYN1, + RF_0x0, 0x1f, + 0x0); + config_phydm_write_rf_syn_8814b(dm, RF_SYN1, + RF_0x58, BIT(1), + 0x1); + } } #endif } else { - /* Eable CCK and OFDM */ - odm_set_bb_reg(dm, R_0x1c3c, 0x3, 0x3); - if (!(dm->support_ic_type & ODM_RTL8814B)) { + /*Enable CCA*/ + if (is_2g_ch) { /*CCK RxIQ weighting = [1,1]*/ + if(dm->support_ic_type & ODM_RTL8723F) { + odm_set_bb_reg(dm, R_0x2a24, BIT(13), 0x0); /*CCK*/ + } else { + odm_set_bb_reg(dm, R_0x1a9c, BIT(20), 0x1); + odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x0); + } + } + odm_set_bb_reg(dm, R_0x1d58, 0xff8, 0x0); /*OFDM*/ + + if(dm->support_ic_type & ODM_RTL8723F) { for (i = start; i <= end; i++) { - odm_set_rf_reg(dm, i, RF_0x00, 0xfffff, - mp->rf_reg0); - /* RF LO disabled */ + odm_set_rf_reg(dm, i, RF_0x0, RFREG_MASK, mp->rf0[i]); + odm_set_rf_reg(dm, i, RF_0x1, RFREG_MASK, mp->rf1[i]); + /*RF LO disabled */ + odm_set_rf_reg(dm, i, RF_0x58, BIT(1), 0x0); + } + odm_set_rf_reg(dm, RF_PATH_A, RF_0x5, BIT(0), 0x1); + } else { + for (i = start; i <= end; i++) { + odm_set_rf_reg(dm, i, RF_0x0, RFREG_MASK, mp->rf0[i]); + /*RF LO disabled */ odm_set_rf_reg(dm, i, RF_0x58, BIT(1), 0x0); } } -#if 0 - odm_set_bb_reg(dm, R_0x1840, MASKDWORD, mp->rfe_sel_a_0); - odm_set_bb_reg(dm, R_0x4140, MASKDWORD, mp->rfe_sel_b_0); - odm_set_bb_reg(dm, R_0x5240, MASKDWORD, mp->rfe_sel_c_0); - odm_set_bb_reg(dm, R_0x5340, MASKDWORD, mp->rfe_sel_d_0); - odm_set_bb_reg(dm, R_0x1844, MASKDWORD, mp->rfe_sel_a_1); - odm_set_bb_reg(dm, R_0x4144, MASKDWORD, mp->rfe_sel_b_1); - odm_set_bb_reg(dm, R_0x5244, MASKDWORD, mp->rfe_sel_c_1); - odm_set_bb_reg(dm, R_0x5344, MASKDWORD, mp->rfe_sel_d_1); -#endif + #if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) { + config_phydm_write_rf_syn_8814b(dm, RF_SYN0, RF_0x0, + RFREG_MASK, + mp->rf0_syn[RF_SYN0]); + config_phydm_write_rf_syn_8814b(dm, RF_SYN0, RF_0x58, + BIT(1), 0x0); + /*SYN1*/ + if (*dm->band_width == CHANNEL_WIDTH_80_80) { + config_phydm_write_rf_syn_8814b(dm, RF_SYN1, + RF_0x0, + RFREG_MASK, + mp->rf0_syn[RF_SYN1]); + config_phydm_write_rf_syn_8814b(dm, RF_SYN1, + RF_0x58, BIT(1), + 0x0); + } + } + #endif } } @@ -163,34 +218,140 @@ void phydm_mp_set_carrier_supp_jgr3(void *dm_void, boolean is_carrier_supp, if (is_carrier_supp) { if (phydm_is_cck_rate(dm, (u8)rate_index)) { - /* @if CCK block on? */ + /*if CCK block on? */ if (!odm_get_bb_reg(dm, R_0x1c3c, BIT(1))) odm_set_bb_reg(dm, R_0x1c3c, BIT(1), 1); - /* @Turn Off All Test mode */ - odm_set_bb_reg(dm, R_0x1ca4, 0x7, 0x0); - - /* @transmit mode */ - odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x2); - /* @turn off scramble setting */ - odm_set_bb_reg(dm, R_0x1a00, 0x8, 0x0); - /* @Set CCK Tx Test Rate, set FTxRate to 1Mbps */ - odm_set_bb_reg(dm, R_0x1a00, 0x3000, 0x0); + if(dm->support_ic_type & ODM_RTL8723F){ + /* @Carrier suppress tx */ + odm_set_bb_reg(dm, R_0x2a08, BIT(18), 0x1); + /*turn off scramble setting */ + odm_set_bb_reg(dm, R_0x2a04, BIT(5), 0x1); + /*Set CCK Tx Test Rate, set TxRate to 2Mbps */ + odm_set_bb_reg(dm, R_0x2a08, 0x300000, 0x1); + /* BB and PMAC cont tx */ + odm_set_bb_reg(dm, R_0x2a08, BIT(17), 0x1); + odm_set_bb_reg(dm, R_0x2a00, BIT(28), 0x1); + /* TX CCK ON */ + odm_set_bb_reg(dm, R_0x2a08, BIT(31), 0x0); + odm_set_bb_reg(dm, R_0x2a08, BIT(31), 0x1); + } + else { + /*Turn Off All Test mode */ + odm_set_bb_reg(dm, R_0x1ca4, 0x7, 0x0); + + /*transmit mode */ + odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x2); + /*turn off scramble setting */ + odm_set_bb_reg(dm, R_0x1a00, BIT(3), 0x0); + /*Set CCK Tx Test Rate, set TxRate to 1Mbps */ + odm_set_bb_reg(dm, R_0x1a00, 0x3000, 0x0); + } } - } else { /* @Stop Carrier Suppression. */ + } else { /*Stop Carrier Suppression. */ if (phydm_is_cck_rate(dm, (u8)rate_index)) { - /* @normal mode */ - odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x0); - /* @turn on scramble setting */ - odm_set_bb_reg(dm, R_0x1a00, 0x8, 0x1); - /* @BB Reset */ - odm_set_bb_reg(dm, R_0x1d0c, 0x10000, 0x0); - odm_set_bb_reg(dm, R_0x1d0c, 0x10000, 0x1); + if(dm->support_ic_type & ODM_RTL8723F) { + /* TX Stop */ + odm_set_bb_reg(dm, R_0x2a00, BIT(0), 0x1); + /* Clear BB cont tx */ + odm_set_bb_reg(dm, R_0x2a00, BIT(28), 0x0); + /* Clear PMAC cont tx */ + odm_set_bb_reg(dm, R_0x2a08, BIT(17), 0x0); + /* Clear TX Stop */ + odm_set_bb_reg(dm, R_0x2a00, BIT(0), 0x0); + /* normal mode */ + odm_set_bb_reg(dm, R_0x2a08, BIT(18), 0x0); + /* turn on scramble setting */ + odm_set_bb_reg(dm, R_0x2a04, BIT(5), 0x0); + } + else { + /*normal mode */ + odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x0); + /*turn on scramble setting */ + odm_set_bb_reg(dm, R_0x1a00, BIT(3), 0x1); + } + /*BB Reset */ + odm_set_bb_reg(dm, R_0x1d0c, BIT(16), 0x0); + odm_set_bb_reg(dm, R_0x1d0c, BIT(16), 0x1); } } } -#endif +void phydm_mp_set_single_carrier_jgr3(void *dm_void, boolean is_single_carrier) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_mp *mp = &dm->dm_mp_table; + + if (is_single_carrier) { + /*1. if OFDM block on? */ + if (!odm_get_bb_reg(dm, R_0x1c3c, BIT(0))) + odm_set_bb_reg(dm, R_0x1c3c, BIT(0), 1); + + if (dm->support_ic_type & ODM_RTL8723F) { + /*3. turn on scramble setting */ + odm_set_bb_reg(dm, R_0x2a04, BIT(5), 0); + /*4. Turn On single carrier. */ + odm_set_bb_reg(dm, R_0x1ca4, 0x7, OFDM_SINGLE_CARRIER); + } + else { + /*2. set CCK test mode off, set to CCK normal mode */ + odm_set_bb_reg(dm, R_0x1a00, 0x3, 0); + /*3. turn on scramble setting */ + odm_set_bb_reg(dm, R_0x1a00, BIT(3), 1); + /*4. Turn On single carrier. */ + odm_set_bb_reg(dm, R_0x1ca4, 0x7, OFDM_SINGLE_CARRIER); + } + } else { + /*Turn off all test modes. */ + odm_set_bb_reg(dm, R_0x1ca4, 0x7, OFDM_OFF); + + /*Delay 10 ms */ + ODM_delay_ms(10); + + /*BB Reset*/ + odm_set_bb_reg(dm, R_0x1d0c, BIT(16), 0x0); + odm_set_bb_reg(dm, R_0x1d0c, BIT(16), 0x1); + } +} + +void phydm_mp_get_tx_ok_jgr3(void *dm_void, u32 rate_index) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_mp *mp = &dm->dm_mp_table; + + if (phydm_is_cck_rate(dm, (u8)rate_index)) + mp->tx_phy_ok_cnt = odm_get_bb_reg(dm, R_0x2de4, MASKLWORD); + else + mp->tx_phy_ok_cnt = odm_get_bb_reg(dm, R_0x2de0, MASKLWORD); +} + +void phydm_mp_get_rx_ok_jgr3(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_mp *mp = &dm->dm_mp_table; + + u32 cck_ok = 0, ofdm_ok = 0, ht_ok = 0, vht_ok = 0; + u32 cck_err = 0, ofdm_err = 0, ht_err = 0, vht_err = 0; + if(dm->support_ic_type & ODM_RTL8723F) + cck_ok = odm_get_bb_reg(dm, R_0x2aac, MASKLWORD); + else + cck_ok = odm_get_bb_reg(dm, R_0x2c04, MASKLWORD); + ofdm_ok = odm_get_bb_reg(dm, R_0x2c14, MASKLWORD); + ht_ok = odm_get_bb_reg(dm, R_0x2c10, MASKLWORD); + vht_ok = odm_get_bb_reg(dm, R_0x2c0c, MASKLWORD); + if(dm->support_ic_type & ODM_RTL8723F) + cck_err = odm_get_bb_reg(dm, R_0x2aac, MASKHWORD); + else + cck_err = odm_get_bb_reg(dm, R_0x2c04, MASKHWORD); + ofdm_err = odm_get_bb_reg(dm, R_0x2c14, MASKHWORD); + ht_err = odm_get_bb_reg(dm, R_0x2c10, MASKHWORD); + vht_err = odm_get_bb_reg(dm, R_0x2c0c, MASKHWORD); + + mp->rx_phy_ok_cnt = cck_ok + ofdm_ok + ht_ok + vht_ok; + mp->rx_phy_crc_err_cnt = cck_err + ofdm_err + ht_err + vht_err; + mp->io_value = (u32)mp->rx_phy_ok_cnt; +} +#endif void phydm_mp_set_crystal_cap(void *dm_void, u8 crystal_cap) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -218,61 +379,9 @@ void phydm_mp_set_carrier_supp(void *dm_void, boolean is_carrier_supp, void phydm_mp_set_single_carrier(void *dm_void, boolean is_single_carrier) { struct dm_struct *dm = (struct dm_struct *)dm_void; - struct phydm_mp *mp = &dm->dm_mp_table; - if (is_single_carrier) { - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - /* @1. if OFDM block on? */ - if (!odm_get_bb_reg(dm, R_0x1c3c, BIT(0))) - odm_set_bb_reg(dm, R_0x1c3c, BIT(0), 1); - - /* @2. set CCK test mode off, set to CCK normal mode */ - odm_set_bb_reg(dm, R_0x1a00, 0x3, 0); - - /* @3. turn on scramble setting */ - odm_set_bb_reg(dm, R_0x1a00, 0x8, 1); - - /* @4. Turn On single carrier. */ - odm_set_bb_reg(dm, R_0x1ca4, 0x7, OFDM_SINGLE_CARRIER); - } else { - /* @1. if OFDM block on? */ - if (!odm_get_bb_reg(dm, R_0x800, 0x2000000)) - odm_set_bb_reg(dm, R_0x800, 0x2000000, 1); - - /* @2. set CCK test mode off, set to CCK normal mode */ - odm_set_bb_reg(dm, R_0xa00, 0x3, 0); - - /* @3. turn on scramble setting */ - odm_set_bb_reg(dm, R_0xa00, 0x8, 1); - - /* @4. Turn On single carrier. */ - if (dm->support_ic_type & ODM_IC_11AC_SERIES) - odm_set_bb_reg(dm, R_0x914, 0x70000, - OFDM_SINGLE_CARRIER); - else if (dm->support_ic_type & ODM_IC_11N_SERIES) - odm_set_bb_reg(dm, R_0xd00, 0x70000000, - OFDM_SINGLE_CARRIER); - } - } else { /* @Stop Single Carrier. */ - /* @Turn off all test modes. */ - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) - odm_set_bb_reg(dm, R_0x1ca4, 0x7, OFDM_OFF); - else if (dm->support_ic_type & ODM_IC_11AC_SERIES) - odm_set_bb_reg(dm, R_0x914, 0x70000, OFDM_OFF); - else if (dm->support_ic_type & ODM_IC_11N_SERIES) - odm_set_bb_reg(dm, R_0xd00, 0x70000000, OFDM_OFF); - /* @Delay 10 ms */ - ODM_delay_ms(10); - - /* @BB Reset */ - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - odm_set_bb_reg(dm, R_0x1d0c, 0x10000, 0x0); - odm_set_bb_reg(dm, R_0x1d0c, 0x10000, 0x1); - } else { - odm_set_bb_reg(dm, R_0x100, 0x100, 0x0); - odm_set_bb_reg(dm, R_0x100, 0x100, 0x1); - } - } + if (dm->support_ic_type & ODM_IC_JGR3_SERIES) + phydm_mp_set_single_carrier_jgr3(dm, is_single_carrier); } void phydm_mp_reset_rx_counters_phy(void *dm_void) { @@ -284,65 +393,16 @@ void phydm_mp_reset_rx_counters_phy(void *dm_void) void phydm_mp_get_tx_ok(void *dm_void, u32 rate_index) { struct dm_struct *dm = (struct dm_struct *)dm_void; - struct phydm_mp *mp = &dm->dm_mp_table; - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - if (phydm_is_cck_rate(dm, (u8)rate_index)) - mp->tx_phy_ok_cnt = odm_get_bb_reg(dm, R_0x2de4, - 0xffff); - else - mp->tx_phy_ok_cnt = odm_get_bb_reg(dm, R_0x2de0, - 0xffff); - } else { - if (phydm_is_cck_rate(dm, (u8)rate_index)) - mp->tx_phy_ok_cnt = odm_get_bb_reg(dm, R_0xf50, - 0xffff); - else - mp->tx_phy_ok_cnt = odm_get_bb_reg(dm, R_0xf50, - 0xffff0000); - } + if (dm->support_ic_type & ODM_IC_JGR3_SERIES) + phydm_mp_get_tx_ok_jgr3(dm, rate_index); } void phydm_mp_get_rx_ok(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; - struct phydm_mp *mp = &dm->dm_mp_table; - u32 cck_ok = 0, ofdm_ok = 0, ht_ok = 0, vht_ok = 0; - u32 cck_err = 0, ofdm_err = 0, ht_err = 0, vht_err = 0; - - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - cck_ok = odm_get_bb_reg(dm, R_0x2c04, 0xffff); - ofdm_ok = odm_get_bb_reg(dm, R_0x2c14, 0xffff); - ht_ok = odm_get_bb_reg(dm, R_0x2c10, 0xffff); - vht_ok = odm_get_bb_reg(dm, R_0x2c0c, 0xffff); - - cck_err = odm_get_bb_reg(dm, R_0x2c04, 0xffff0000); - ofdm_err = odm_get_bb_reg(dm, R_0x2c14, 0xffff0000); - ht_err = odm_get_bb_reg(dm, R_0x2c10, 0xffff0000); - vht_err = odm_get_bb_reg(dm, R_0x2c0c, 0xffff0000); - } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { - cck_ok = odm_get_bb_reg(dm, R_0xf04, 0x3FFF); - ofdm_ok = odm_get_bb_reg(dm, R_0xf14, 0x3FFF); - ht_ok = odm_get_bb_reg(dm, R_0xf10, 0x3FFF); - vht_ok = odm_get_bb_reg(dm, R_0xf0c, 0x3FFF); - - cck_err = odm_get_bb_reg(dm, R_0xf04, 0x3FFF0000); - ofdm_err = odm_get_bb_reg(dm, R_0xf14, 0x3FFF0000); - ht_err = odm_get_bb_reg(dm, R_0xf10, 0x3FFF0000); - vht_err = odm_get_bb_reg(dm, R_0xf0c, 0x3FFF0000); - } else if (dm->support_ic_type & ODM_IC_11N_SERIES) { - cck_ok = odm_get_bb_reg(dm, R_0xf88, MASKDWORD); - ofdm_ok = odm_get_bb_reg(dm, R_0xf94, 0xffff); - ht_ok = odm_get_bb_reg(dm, R_0xf90, 0xffff); - - cck_err = odm_get_bb_reg(dm, R_0xf84, MASKDWORD); - ofdm_err = odm_get_bb_reg(dm, R_0xf94, 0xffff0000); - ht_err = odm_get_bb_reg(dm, R_0xf90, 0xffff0000); - } - - mp->rx_phy_ok_cnt = cck_ok + ofdm_ok + ht_ok + vht_ok; - mp->rx_phy_crc_err_cnt = cck_err + ofdm_err + ht_err + vht_err; - mp->io_value = (u32)mp->rx_phy_ok_cnt; + if (dm->support_ic_type & ODM_IC_JGR3_SERIES) + phydm_mp_get_rx_ok_jgr3(dm); } #endif diff --git a/hal/phydm/phydm_mp.h b/hal/phydm/phydm_mp.h index e9e40ae..5805a03 100644 --- a/hal/phydm/phydm_mp.h +++ b/hal/phydm/phydm_mp.h @@ -26,7 +26,8 @@ #ifndef __PHYDM_MP_H__ #define __PHYDM_MP_H__ -#define MP_VERSION "1.3" +/*2020.04.27 Refine single tone Tx flow*/ +#define MP_VERSION "1.5" /* @1 ============================================================ * 1 Definition @@ -37,22 +38,18 @@ * 1 ============================================================ */ struct phydm_mp { - /* @Rx OK count, statistics used in Mass Production Test.*/ + /*Rx OK count, statistics used in Mass Production Test.*/ u64 tx_phy_ok_cnt; u64 rx_phy_ok_cnt; - /* @Rx CRC32 error count, statistics used in Mass Production Test.*/ + /*Rx CRC32 error count, statistics used in Mass Production Test.*/ u64 rx_phy_crc_err_cnt; - /* @The Value of IO operation is depend of MptActType.*/ + /*The Value of IO operation is depend of MptActType.*/ u32 io_value; - u32 rf_reg0; - /* @u32 rfe_sel_a_0;*/ - /* @u32 rfe_sel_b_0;*/ - /* @u32 rfe_sel_c_0;*/ - /* @u32 rfe_sel_d_0;*/ - /* @u32 rfe_sel_a_1;*/ - /* @u32 rfe_sel_b_1;*/ - /* @u32 rfe_sel_c_1;*/ - /* @u32 rfe_sel_d_1;*/ + u32 rf0[RF_PATH_MEM_SIZE]; + #if (RTL8814B_SUPPORT) + u32 rf0_syn[2]; + #endif + u32 rf1[RF_PATH_MEM_SIZE]; }; /* @1 ============================================================ diff --git a/hal/phydm/phydm_noisemonitor.c b/hal/phydm/phydm_noisemonitor.c index aeeb255..d2e95cf 100644 --- a/hal/phydm/phydm_noisemonitor.c +++ b/hal/phydm/phydm_noisemonitor.c @@ -258,7 +258,8 @@ s16 odm_inband_noise_monitor_ac(struct dm_struct *dm, u8 pause_dig, u8 igi, s32 value32, pwdb_A = 0, sval, noise, sum = 0; boolean pd_flag; u8 valid_cnt = 0; - u64 start = 0, func_start = 0, func_end = 0; + u8 invalid_cnt = 0; + u64 start = 0, func_start = 0, func_end = 0, proc_time = 0; s32 val_s32 = 0; s16 rpt = 0; u8 val_u8 = 0; @@ -350,6 +351,15 @@ s16 odm_inband_noise_monitor_ac(struct dm_struct *dm, u8 pause_dig, u8 igi, "After divided, sum = %d\n", sum); break; } + } else { + /*Invalid sval and return -110 dBm*/ + invalid_cnt++; + PHYDM_DBG(dm, DBG_ENV_MNTR, "Invalid sval\n"); + if (invalid_cnt >= VALID_CNT + 5) { + PHYDM_DBG(dm, DBG_ENV_MNTR, + "Invalid count > TH, Return -110, Break!!\n"); + return -110; + } } } diff --git a/hal/phydm/phydm_pathdiv.c b/hal/phydm/phydm_pathdiv.c index 8fb8561..a6b347c 100644 --- a/hal/phydm/phydm_pathdiv.c +++ b/hal/phydm/phydm_pathdiv.c @@ -1040,10 +1040,8 @@ void phydm_pathdiv_debug(void *dm_void, char input[][16], u32 *_used, u8 i, input_idx = 0; for (i = 0; i < 5; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &val[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &val[i]); + input_idx++; } if (input_idx == 0) diff --git a/hal/phydm/phydm_phystatus.c b/hal/phydm/phydm_phystatus.c index ca4b945..7d7ecd7 100644 --- a/hal/phydm/phydm_phystatus.c +++ b/hal/phydm/phydm_phystatus.c @@ -197,25 +197,36 @@ void phydm_reset_phystatus_statistic(struct dm_struct *dm) sizeof(struct phydm_phystatus_statistic)); } -void phydm_avg_phystatus_index_p1(void *dm_void, - struct phydm_phyinfo_struct *phy_info, - struct phydm_perpkt_info_struct *pktinfo) +void phydm_reset_phy_info(struct dm_struct *dm, + struct phydm_phyinfo_struct *phy_info) +{ + u8 i = 0; + + odm_memory_set(dm, &phy_info->physts_rpt_valid, 0, + sizeof(struct phydm_phyinfo_struct)); + + phy_info->rx_power = -110; + phy_info->recv_signal_power = -110; + + for (i = 0; i < dm->num_rf_path; i++) + phy_info->rx_pwr[i] = -110; +} + +void phydm_avg_rssi_evm_snr(void *dm_void, + struct phydm_phyinfo_struct *phy_info, + struct phydm_perpkt_info_struct *pktinfo) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_phy_dbg_info *dbg_i = &dm->phy_dbg_info; struct phydm_phystatus_statistic *dbg_s = &dbg_i->physts_statistic_info; - u8 rssi[PHYSTS_PATH_NUM] = {0}; - u8 evm[PHYSTS_PATH_NUM] = {0}; - s8 snr[PHYSTS_PATH_NUM] = {0}; + u8 *rssi = phy_info->rx_mimo_signal_strength; + u8 *evm = phy_info->rx_mimo_evm_dbm; + s8 *snr = phy_info->rx_snr; u32 size = PHYSTS_PATH_NUM; /*size of path=4*/ u16 size_th = PHY_HIST_SIZE - 1; /*size of threshold*/ u16 val = 0, intvl = 0; u8 i = 0; - odm_move_memory(dm, rssi, phy_info->rx_mimo_signal_strength, size); - odm_move_memory(dm, evm, phy_info->rx_mimo_evm_dbm, size); - odm_move_memory(dm, snr, phy_info->rx_snr, size); - if (pktinfo->is_packet_beacon) { for (i = 0; i < dm->num_rf_path; i++) dbg_s->rssi_beacon_sum[i] += rssi[i]; @@ -226,7 +237,7 @@ void phydm_avg_phystatus_index_p1(void *dm_void, if (pktinfo->data_rate <= ODM_RATE11M) { /*RSSI*/ dbg_s->rssi_cck_sum += rssi[0]; - #ifdef PHYSTS_3RD_TYPE_SUPPORT + #if (defined(PHYSTS_3RD_TYPE_SUPPORT) && defined(PHYDM_COMPILE_ABOVE_2SS)) if (dm->support_ic_type & PHYSTS_3RD_TYPE_IC) { for (i = 1; i < dm->num_rf_path; i++) dbg_s->rssi_cck_sum_abv_2ss[i - 1] += rssi[i]; @@ -401,7 +412,7 @@ u8 phydm_get_signal_quality(struct phydm_phyinfo_struct *phy_info, return result; } -u8 phydm_pwr_2_percent(s8 ant_power) +u8 phydm_pw_2_percent(s8 ant_power) { if ((ant_power <= -100) || ant_power >= 20) return 0; @@ -412,73 +423,6 @@ u8 phydm_pwr_2_percent(s8 ant_power) } #if (DM_ODM_SUPPORT_TYPE & ODM_WIN) - -#if 0 /*(DM_ODM_SUPPORT_TYPE == ODM_CE)*/ -s32 phydm_signal_scale_mapping_92c_series(struct dm_struct *dm, s32 curr_sig) -{ - s32 ret_sig = 0; - -#if (DEV_BUS_TYPE == RT_PCI_INTERFACE) - if (dm->support_interface == ODM_ITRF_PCIE) { - /* step 1. Scale mapping. */ - if (curr_sig >= 61 && curr_sig <= 100) - ret_sig = 90 + ((curr_sig - 60) / 4); - else if (curr_sig >= 41 && curr_sig <= 60) - ret_sig = 78 + ((curr_sig - 40) / 2); - else if (curr_sig >= 31 && curr_sig <= 40) - ret_sig = 66 + (curr_sig - 30); - else if (curr_sig >= 21 && curr_sig <= 30) - ret_sig = 54 + (curr_sig - 20); - else if (curr_sig >= 5 && curr_sig <= 20) - ret_sig = 42 + (((curr_sig - 5) * 2) / 3); - else if (curr_sig == 4) - ret_sig = 36; - else if (curr_sig == 3) - ret_sig = 27; - else if (curr_sig == 2) - ret_sig = 18; - else if (curr_sig == 1) - ret_sig = 9; - else - ret_sig = curr_sig; - } -#endif - -#if ((DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE)) - if (dm->support_interface == ODM_ITRF_USB || - dm->support_interface == ODM_ITRF_SDIO) { - if (curr_sig >= 51 && curr_sig <= 100) - ret_sig = 100; - else if (curr_sig >= 41 && curr_sig <= 50) - ret_sig = 80 + ((curr_sig - 40) * 2); - else if (curr_sig >= 31 && curr_sig <= 40) - ret_sig = 66 + (curr_sig - 30); - else if (curr_sig >= 21 && curr_sig <= 30) - ret_sig = 54 + (curr_sig - 20); - else if (curr_sig >= 10 && curr_sig <= 20) - ret_sig = 42 + (((curr_sig - 10) * 2) / 3); - else if (curr_sig >= 5 && curr_sig <= 9) - ret_sig = 22 + (((curr_sig - 5) * 3) / 2); - else if (curr_sig >= 1 && curr_sig <= 4) - ret_sig = 6 + (((curr_sig - 1) * 3) / 2); - else - ret_sig = curr_sig; - } - -#endif - return ret_sig; -} - -s32 phydm_signal_scale_mapping(struct dm_struct *dm, s32 curr_sig) -{ -#ifdef CONFIG_SIGNAL_SCALE_MAPPING - return phydm_signal_scale_mapping_92c_series(dm, curr_sig); -#else - return curr_sig; -#endif -} -#endif - void phydm_process_signal_strength(struct dm_struct *dm, struct phydm_phyinfo_struct *phy_info, struct phydm_perpkt_info_struct *pktinfo) @@ -522,9 +466,7 @@ void phydm_process_signal_strength(struct dm_struct *dm, phy_info->signal_strength = ss; } -#endif -#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) static u8 phydm_sq_patch_lenovo( struct dm_struct *dm, u8 is_cck_rate, @@ -918,7 +860,7 @@ void phydm_phy_sts_n_parsing(struct dm_struct *dm, if (dm->board_type & ODM_BOARD_EXT_LNA) rx_pwr_all -= dm->ext_lna_gain; - pwdb_all = phydm_pwr_2_percent(rx_pwr_all); + pwdb_all = phydm_pw_2_percent(rx_pwr_all); if (pktinfo->is_to_self) { dm->cck_lna_idx = lna_idx; @@ -939,9 +881,8 @@ void phydm_phy_sts_n_parsing(struct dm_struct *dm, #endif sq = phydm_get_signal_quality(phy_info, dm, phy_sts); -#if 0 /* @dbg_print("cck sq = %d\n", sq); */ -#endif + phy_info->signal_quality = sq; phy_info->rx_mimo_signal_quality[RF_PATH_A] = sq; phy_info->rx_mimo_signal_quality[RF_PATH_B] = -1; @@ -967,7 +908,7 @@ void phydm_phy_sts_n_parsing(struct dm_struct *dm, dm->ofdm_agc_idx[i] = val_s8; phy_info->rx_pwr[i] = rx_pwr[i]; - RSSI = phydm_pwr_2_percent(rx_pwr[i]); + RSSI = phydm_pw_2_percent(rx_pwr[i]); total_rssi += RSSI; phy_info->rx_mimo_signal_strength[i] = (u8)RSSI; @@ -992,7 +933,7 @@ void phydm_phy_sts_n_parsing(struct dm_struct *dm, val_s8 = phy_sts->cck_sig_qual_ofdm_pwdb_all >> 1; rx_pwr_all = (val_s8 & 0x7f) - 110; - pwdb_all = phydm_pwr_2_percent(rx_pwr_all); + pwdb_all = phydm_pw_2_percent(rx_pwr_all); pwdb_all_bt = pwdb_all; phy_info->rx_pwdb_all = pwdb_all; @@ -1009,6 +950,9 @@ void phydm_phy_sts_n_parsing(struct dm_struct *dm, * value to positive one, then the dbm value * (which is supposed to be negative) is not correct anymore. */ + if (i >= PHYDM_MAX_RF_PATH_N) + break; + EVM = phydm_evm_2_percent(phy_sts->stream_rxevm[i]); /*@Fill value in RFD, Get the 1st spatial stream only*/ @@ -1170,7 +1114,7 @@ void phydm_rx_physts_1st_type(struct dm_struct *dm, vga_idx = cck_agc_rpt & 0x1F; rx_pwr_db = phydm_get_cck_rssi(dm, lna_idx, vga_idx); - rssi = phydm_pwr_2_percent(rx_pwr_db); + rssi = phydm_pw_2_percent(rx_pwr_db); if (dm->support_ic_type == ODM_RTL8812 && !dm->is_cck_high_power) { @@ -1199,7 +1143,7 @@ void phydm_rx_physts_1st_type(struct dm_struct *dm, val = phy_sts->gain_trsw_cd[i - 2]; phy_info->rx_pwr[i] = (val & 0x7F) - 110; - rssi = phydm_pwr_2_percent(phy_info->rx_pwr[i]); + rssi = phydm_pw_2_percent(phy_info->rx_pwr[i]); phy_info->rx_mimo_signal_strength[i] = rssi; /*@[SNR]*/ @@ -1231,7 +1175,7 @@ void phydm_rx_physts_1st_type(struct dm_struct *dm, val = phy_sts->pwdb_all >> 1; /*old fomula*/ rx_pwr_db = (val & 0x7f) - 110; - phy_info->rx_pwdb_all = phydm_pwr_2_percent(rx_pwr_db); + phy_info->rx_pwdb_all = phydm_pw_2_percent(rx_pwr_db); /*@(4)EVM of OFDM rate*/ for (i = 0; i < pktinfo->rate_ss; i++) { @@ -1375,9 +1319,6 @@ void phydm_process_rssi_for_dm(struct dm_struct *dm, #ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY odm_s0s1_sw_ant_div_by_ctrl_frame_process_rssi(dm, phy_info, pktinfo); #endif - #ifdef ODM_EVM_ENHANCE_ANTDIV - phydm_rx_rate_for_antdiv(dm, pktinfo); - #endif sta = dm->phydm_sta_info[pktinfo->station_id]; @@ -1415,6 +1356,11 @@ void phydm_process_rssi_for_dm(struct dm_struct *dm, } /* @--------------Statistic for antenna/path diversity--------------- */ + #ifdef ODM_EVM_ENHANCE_ANTDIV + if (dm->antdiv_evm_en) + phydm_rx_rate_for_antdiv(dm, pktinfo); + #endif + #if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) if (dm->support_ability & ODM_BB_ANT_DIV) odm_process_rssi_for_ant_div(dm, phy_info, pktinfo); @@ -1597,6 +1543,7 @@ boolean phydm_physts_auto_switch_jgr3(void *dm_void, u8 *phy_sts, boolean is_skip_physts_parsing = false; u8 phy_sts_byte0 = (*phy_sts & 0xff); u8 phy_ppdu_cnt_pre = 0, mac_ppdu_cnt_pre = 0; + u8 ppdu_phy_rate_pre = 0, ppdu_macid_pre = 0; u8 page = phy_sts_byte0 & 0xf; if (!pkt_proc->physts_auto_swch_en) @@ -1604,9 +1551,13 @@ boolean phydm_physts_auto_switch_jgr3(void *dm_void, u8 *phy_sts, phy_ppdu_cnt_pre = pkt_proc->phy_ppdu_cnt; mac_ppdu_cnt_pre = pkt_proc->mac_ppdu_cnt; + ppdu_phy_rate_pre = pkt_proc->ppdu_phy_rate; + ppdu_macid_pre = pkt_proc->ppdu_macid; pkt_proc->phy_ppdu_cnt = (phy_sts_byte0 & 0x30) >> 4; pkt_proc->mac_ppdu_cnt = pktinfo->ppdu_cnt; + pkt_proc->ppdu_phy_rate = pktinfo->data_rate; + pkt_proc->ppdu_macid = pktinfo->station_id; PHYDM_DBG(dm, DBG_PHY_STATUS, "[rate:0x%x] PPDU mac{pre, curr}= {%d, %d}, phy{pre, curr}= {%d, %d}\n", @@ -1618,7 +1569,9 @@ boolean phydm_physts_auto_switch_jgr3(void *dm_void, u8 *phy_sts, return is_skip_physts_parsing; } - if (phy_ppdu_cnt_pre == pkt_proc->phy_ppdu_cnt && + if (ppdu_macid_pre == pkt_proc->ppdu_macid && + ppdu_phy_rate_pre == pkt_proc->ppdu_phy_rate && + phy_ppdu_cnt_pre == pkt_proc->phy_ppdu_cnt && mac_ppdu_cnt_pre == pkt_proc->mac_ppdu_cnt) { if (pkt_proc->page_bitmap_record & BIT(page)) { /*@PHYDM_DBG(dm, DBG_PHY_STATUS, "collect page-%d enough\n", page);*/ @@ -1631,9 +1584,11 @@ boolean phydm_physts_auto_switch_jgr3(void *dm_void, u8 *phy_sts, /*@PHYDM_DBG(dm, DBG_PHY_STATUS, "update page-%d\n", page);*/ pkt_proc->page_bitmap_record |= BIT(page); } + pkt_proc->is_1st_mpdu = false; } else { /*@PHYDM_DBG(dm, DBG_PHY_STATUS, "[New Pkt] update page-%d\n", page);*/ pkt_proc->page_bitmap_record = BIT(page); + pkt_proc->is_1st_mpdu = true; } PHYDM_DBG(dm, DBG_PHY_STATUS, @@ -1651,39 +1606,40 @@ void phydm_physts_auto_switch_jgr3_set(void *dm_void, boolean enable, struct pkt_process_info *pkt_proc = &dm->pkt_proc_struct; u16 en_page_num = 1; - if (dm->support_ic_type != ODM_RTL8822C) + if (!(dm->support_ic_type & PHYSTS_AUTO_SWITCH_IC)) return; - +#if 0 + if (!(dm->support_ic_type & PHYSTS_3RD_TYPE_IC)) + return; +#endif pkt_proc->physts_auto_swch_en = enable; pkt_proc->page_bitmap_target = bitmap_en; phydm_physts_auto_switch_jgr3_reset(dm); en_page_num = phydm_ones_num_in_bitmap((u64)bitmap_en, 8); - PHYDM_DBG(dm, DBG_PHY_STATUS, "en=%d, bitmap_en=%d, en_page_num=%d\n", - enable, bitmap_en, en_page_num); + PHYDM_DBG(dm, DBG_CMN, "[%s]en=%d, bitmap_en=%d, en_page_num=%d\n", + __func__, enable, bitmap_en, en_page_num); - if (dm->support_ic_type & PHYSTS_3RD_TYPE_IC) { - if (enable) { - /*@per MPDU latch & update phy-staatus*/ - odm_set_mac_reg(dm, R_0x60c, BIT(31), 1); - /*@Update Period (OFDM Symbol)*/ - odm_set_bb_reg(dm, R_0x8c0, 0xfc000, 3); - /*@switchin bitmap*/ - odm_set_bb_reg(dm, R_0x8c4, 0x7f80000, bitmap_en); - /*@mode 3*/ - odm_set_bb_reg(dm, R_0x8c4, (BIT(28) | BIT(27)), 3); - } else { - odm_set_mac_reg(dm, R_0x60c, BIT(31), 0); - odm_set_bb_reg(dm, R_0x8c0, 0xfc000, 0x0); - odm_set_bb_reg(dm, R_0x8c4, 0x7f80000, 0x2); - odm_set_bb_reg(dm, R_0x8c4, (BIT(28) | BIT(27)), 0); - } + if (enable) { + /*@per MPDU latch & update phy-staatus*/ + odm_set_mac_reg(dm, R_0x60c, BIT(31), 1); + /*@Update Period (OFDM Symbol)*/ + odm_set_bb_reg(dm, R_0x8c0, 0xfc000, 3); + /*@switchin bitmap*/ + odm_set_bb_reg(dm, R_0x8c4, 0x7f80000, bitmap_en); + /*@mode 3*/ + odm_set_bb_reg(dm, R_0x8c4, (BIT(28) | BIT(27)), 3); + } else { + odm_set_mac_reg(dm, R_0x60c, BIT(31), 0); + odm_set_bb_reg(dm, R_0x8c0, 0xfc000, 0x1); + odm_set_bb_reg(dm, R_0x8c4, 0x7f80000, 0x2); + odm_set_bb_reg(dm, R_0x8c4, (BIT(28) | BIT(27)), 0); } } -void phydm_avg_phystatus_index_p4(void *dm_void, - struct phydm_phyinfo_struct *phy_info, - struct phydm_perpkt_info_struct *pktinfo) +void phydm_avg_condi_num(void *dm_void, + struct phydm_phyinfo_struct *phy_info, + struct phydm_perpkt_info_struct *pktinfo) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_phy_dbg_info *dbg_i = &dm->phy_dbg_info; @@ -1698,48 +1654,36 @@ void phydm_avg_phystatus_index_p4(void *dm_void, arry_idx = pktinfo->rate_ss - 1; dbg_s->p4_cnt[arry_idx]++; - dbg_s->cn_sum[arry_idx] += phy_info->condition_num_seg0; + dbg_s->cn_sum[arry_idx] += dbg_i->condition_num_seg0; /*CN Histogram*/ - val = (u16)phy_info->condition_num_seg0; + val = (u16)dbg_i->condition_num_seg0; intvl = phydm_find_intrvl(dm, val, dbg_i->cn_hist_th, size_th); dbg_s->cn_hist[arry_idx][intvl]++; - dbg_i->condi_num = (u32)phy_info->condition_num_seg0; /*will remove*/ + dbg_i->condi_num = (u32)dbg_i->condition_num_seg0; /*will remove*/ } - -void phydm_get_physts_jgr3_4_cn(struct dm_struct *dm, u8 *phy_status_inf, - struct phydm_perpkt_info_struct *pktinfo, - struct phydm_phyinfo_struct *phy_info) -{ - struct phy_sts_rpt_jgr3_type4 *phy_sts = NULL; - struct odm_phy_dbg_info *dbg_i = &dm->phy_dbg_info; - - if (pktinfo->rate_ss == 1) - return; - - phy_sts = (struct phy_sts_rpt_jgr3_type4 *)phy_status_inf; - - odm_move_memory(dm, phy_info->eigen_val, phy_sts->eigenvalue, 4); - phy_info->condition_num_seg0 = phy_sts->avg_cond_num_0; -} - #endif -void phydm_print_phystat_jaguar3(struct dm_struct *dm, u8 *phy_sts, - struct phydm_perpkt_info_struct *pktinfo, - struct phydm_phyinfo_struct *phy_info) +void phydm_print_phystat_jgr3(struct dm_struct *dm, u8 *phy_sts, + struct phydm_perpkt_info_struct *pktinfo, + struct phydm_phyinfo_struct *phy_info) { struct phy_sts_rpt_jgr3_type0 *rpt0 = NULL; struct phy_sts_rpt_jgr3_type1 *rpt1 = NULL; struct phy_sts_rpt_jgr3_type2_3 *rpt2 = NULL; struct phy_sts_rpt_jgr3_type4 *rpt3 = NULL; struct phy_sts_rpt_jgr3_type5 *rpt4 = NULL; + struct phy_sts_rpt_jgr3_type6 *rpt5 = NULL; + struct odm_phy_dbg_info *dbg = &dm->phy_dbg_info; u8 phy_status_page_num = (*phy_sts & 0xf); - u32 phy_status_tmp[PHY_STATUS_JRGUAR3_DW_LEN] = {0}; + u32 *phy_status_tmp = NULL; u8 i = 0; - u32 size = PHY_STATUS_JRGUAR3_DW_LEN << 2; + /*u32 size = PHY_STATUS_JRGUAR3_DW_LEN << 2;*/ + + if (!(dm->debug_components & DBG_PHY_STATUS)) + return; rpt0 = (struct phy_sts_rpt_jgr3_type0 *)phy_sts; rpt1 = (struct phy_sts_rpt_jgr3_type1 *)phy_sts; @@ -1747,9 +1691,14 @@ void phydm_print_phystat_jaguar3(struct dm_struct *dm, u8 *phy_sts, rpt3 = (struct phy_sts_rpt_jgr3_type4 *)phy_sts; rpt4 = (struct phy_sts_rpt_jgr3_type5 *)phy_sts; - odm_move_memory(dm, phy_status_tmp, phy_sts, size); - if (!(dm->debug_components & DBG_PHY_STATUS)) - return; + if (dm->support_ic_type & ODM_RTL8723F) { + rpt5 = (struct phy_sts_rpt_jgr3_type6 *)phy_sts; + + if (pktinfo->is_cck_rate) + phy_status_page_num = 0; + } + + phy_status_tmp = (u32 *)phy_sts; if (dbg->show_phy_sts_all_pkt == 0) { if (!pktinfo->is_packet_match_bssid) @@ -1777,32 +1726,51 @@ void phydm_print_phystat_jaguar3(struct dm_struct *dm, u8 *phy_sts, ((4 * i) + 3), (4 * i), phy_status_tmp[i]); if (phy_status_page_num == 0) { /* @CCK(default) */ - pr_debug("[0] Pkt_cnt=%d, Channel_msb=%d, Pwdb_a=%d, Gain_a=%d, TRSW=%d, AGC_table_b=%d, AGC_table_c=%d,\n", - rpt0->pkt_cnt, rpt0->channel_msb, rpt0->pwdb_a, - rpt0->gain_a, rpt0->trsw, rpt0->agc_table_b, - rpt0->agc_table_c); - pr_debug("[4] Path_Sel_o=%d, Gnt_BT_keep_cnt=%d, HW_AntSW_occur_keep_cck=%d,\n Band=%d, Channel=%d, AGC_table_a=%d, l_RXSC=%d, AGC_table_d=%d\n", - rpt0->path_sel_o, rpt0->gnt_bt_keep_cck, - rpt0->hw_antsw_occur_keep_cck, rpt0->band, - rpt0->channel, rpt0->agc_table_a, rpt0->l_rxsc, - rpt0->agc_table_d); - pr_debug("[8] AntIdx={%d, %d, %d, %d}, Length=%d\n", - rpt0->antidx_d, rpt0->antidx_c, rpt0->antidx_b, - rpt0->antidx_a, rpt0->length); - pr_debug("[12] MF_off=%d, SQloss=%d, lockbit=%d, raterr=%d, rxrate=%d, lna_h_a=%d, CCK_BB_power_a=%d, lna_l_a=%d, vga_a=%d, sq=%d\n", - rpt0->mf_off, rpt0->sqloss, rpt0->lockbit, - rpt0->raterr, rpt0->rxrate, rpt0->lna_h_a, - rpt0->bb_power_a, rpt0->lna_l_a, rpt0->vga_a, - rpt0->signal_quality); - pr_debug("[16] Gain_b=%d, lna_h_b=%d, CCK_BB_power_b=%d, lna_l_b=%d, vga_b=%d, Pwdb_b=%d\n", - rpt0->gain_b, rpt0->lna_h_b, rpt0->bb_power_b, - rpt0->lna_l_b, rpt0->vga_b, rpt0->pwdb_b); - pr_debug("[20] Gain_c=%d, lna_h_c=%d, CCK_BB_power_c=%d, lna_l_c=%d, vga_c=%d, Pwdb_c=%d\n", - rpt0->gain_c, rpt0->lna_h_c, rpt0->bb_power_c, - rpt0->lna_l_c, rpt0->vga_c, rpt0->pwdb_c); - pr_debug("[24] Gain_d=%d, lna_h_d=%d, CCK_BB_power_d=%d, lna_l_d=%d, vga_d=%d, Pwdb_d=%d\n", - rpt0->gain_c, rpt0->lna_h_c, rpt0->bb_power_c, - rpt0->lna_l_c, rpt0->vga_c, rpt0->pwdb_c); + if (dm->support_ic_type & ODM_RTL8723F) { + #if (RTL8723F_SUPPORT) + pr_debug("[0] Pop_idx=%d, Pkt_cnt=%d, Channel_msb=%d, AGC_table_path0=%d, TRSW_mux_keep=%d, HW_AntSW_occur_keep_cck=%d, Gnt_BT_keep_cnt=%d,Rssi_msb=%d\n", + rpt5->pop_idx, rpt5->pkt_cnt, + rpt5->channel_msb, rpt5->agc_table_a, + rpt5->trsw, rpt5->hw_antsw_occur_keep_cck, + rpt5->gnt_bt_keep_cck, rpt5->rssi_msb); + pr_debug("[4] Channel=%d, Antidx_CCK_keep=%d, Cck_mp_gain_idx_keep=%d\n", + rpt5->channel, rpt5->antidx_a, + rpt5->mp_gain_idx_a); + pr_debug("[8] Rssi=%d\n",rpt5->rssi); + pr_debug("[12] Avg_cfo=%d\n",rpt5->avg_cfo); + pr_debug("[16] Coarse_cfo=%d, Coarse_cfo_msb=%d, Avg_cfo_msb=%d, Evm_hdr=%d\n", + rpt5->coarse_cfo, rpt5->coarse_cfo_msb, + rpt5->avg_cfo_msb, rpt5->evm_hdr); + pr_debug("[20] Evm_pld=%d\n",rpt5->evm_pld); + #endif + } else { + pr_debug("[0] Pkt_cnt=%d, Channel_msb=%d, Pwdb_a=%d, Gain_a=%d, TRSW=%d, AGC_table_b=%d, AGC_table_c=%d,\n", + rpt0->pkt_cnt, rpt0->channel_msb, rpt0->pwdb_a, + rpt0->gain_a, rpt0->trsw, rpt0->agc_table_b, + rpt0->agc_table_c); + pr_debug("[4] Path_Sel_o=%d, Gnt_BT_keep_cnt=%d, HW_AntSW_occur_keep_cck=%d,\n Band=%d, Channel=%d, AGC_table_a=%d, l_RXSC=%d, AGC_table_d=%d\n", + rpt0->path_sel_o, rpt0->gnt_bt_keep_cck, + rpt0->hw_antsw_occur_keep_cck, rpt0->band, + rpt0->channel, rpt0->agc_table_a, rpt0->l_rxsc, + rpt0->agc_table_d); + pr_debug("[8] AntIdx={%d, %d, %d, %d}, Length=%d\n", + rpt0->antidx_d, rpt0->antidx_c, rpt0->antidx_b, + rpt0->antidx_a, rpt0->length); + pr_debug("[12] MF_off=%d, SQloss=%d, lockbit=%d, raterr=%d, rxrate=%d, lna_h_a=%d, CCK_BB_power_a=%d, lna_l_a=%d, vga_a=%d, sq=%d\n", + rpt0->mf_off, rpt0->sqloss, rpt0->lockbit, + rpt0->raterr, rpt0->rxrate, rpt0->lna_h_a, + rpt0->bb_power_a, rpt0->lna_l_a, rpt0->vga_a, + rpt0->signal_quality); + pr_debug("[16] Gain_b=%d, lna_h_b=%d, CCK_BB_power_b=%d, lna_l_b=%d, vga_b=%d, Pwdb_b=%d\n", + rpt0->gain_b, rpt0->lna_h_b, rpt0->bb_power_b, + rpt0->lna_l_b, rpt0->vga_b, rpt0->pwdb_b); + pr_debug("[20] Gain_c=%d, lna_h_c=%d, CCK_BB_power_c=%d, lna_l_c=%d, vga_c=%d, Pwdb_c=%d\n", + rpt0->gain_c, rpt0->lna_h_c, rpt0->bb_power_c, + rpt0->lna_l_c, rpt0->vga_c, rpt0->pwdb_c); + pr_debug("[24] Gain_d=%d, lna_h_d=%d, CCK_BB_power_d=%d, lna_l_d=%d, vga_d=%d, Pwdb_d=%d\n", + rpt0->gain_c, rpt0->lna_h_c, rpt0->bb_power_c, + rpt0->lna_l_c, rpt0->vga_c, rpt0->pwdb_c); + } } else if (phy_status_page_num == 1) { pr_debug("[0] pwdb[C:A]={%d, %d, %d}, Channel_pri_msb=%d, Pkt_cnt=%d,\n", rpt1->pwdb_c, rpt1->pwdb_b, rpt1->pwdb_a, @@ -1916,17 +1884,15 @@ void phydm_print_phystat_jaguar3(struct dm_struct *dm, u8 *phy_sts, } } -void phydm_reset_phy_info_3rd(struct dm_struct *phydm, - struct phydm_phyinfo_struct *phy_info) +void phydm_reset_phy_info_jgr3(struct dm_struct *phydm, + struct phydm_phyinfo_struct *phy_info) { + u8 i; + phy_info->rx_pwdb_all = 0; phy_info->signal_quality = 0; phy_info->band_width = 0; phy_info->rx_count = 0; - odm_memory_set(phydm, phy_info->rx_mimo_signal_quality, 0, 4); - odm_memory_set(phydm, phy_info->rx_mimo_signal_strength, 0, 4); - odm_memory_set(phydm, phy_info->rx_snr, 0, 4); - phy_info->rx_power = -110; phy_info->recv_signal_power = -110; phy_info->bt_rx_rssi_percentage = 0; @@ -1935,13 +1901,19 @@ void phydm_reset_phy_info_3rd(struct dm_struct *phydm, phy_info->is_mu_packet = 0; phy_info->is_beamformed = 0; phy_info->rxsc = 0; - odm_memory_set(phydm, phy_info->rx_pwr, -110, 4); - odm_memory_set(phydm, phy_info->cfo_short, 0, 8); - odm_memory_set(phydm, phy_info->cfo_tail, 0, 8); - odm_memory_set(phydm, phy_info->rx_mimo_evm_dbm, 0, 4); + for (i = 0; i < 4; i++) { + phy_info->rx_mimo_signal_strength[i] = 0; + phy_info->rx_mimo_signal_quality[i] = 0; + phy_info->rx_mimo_evm_dbm[i] = 0; + phy_info->cfo_short[i] = 0; + phy_info->cfo_tail[i] = 0; + phy_info->rx_pwr[i] = -110; + phy_info->rx_snr[i] = 0; + } } +#if 0 void phydm_per_path_info_3rd(u8 rx_path, s8 pwr, s8 rx_evm, s8 cfo_tail, s8 rx_snr, struct phydm_phyinfo_struct *phy_info) { @@ -1950,36 +1922,23 @@ void phydm_per_path_info_3rd(u8 rx_path, s8 pwr, s8 rx_evm, s8 cfo_tail, /* SNR is S(8,1), EVM is S(8,1), CFO is S(8,7) */ - if (rx_evm < 0) { - /* @Calculate EVM in dBm */ - evm_dbm = ((u8)(0 - rx_evm) >> 1); - - if (evm_dbm == 64) - evm_dbm = 0; /*@if 1SS rate, evm_dbm [2nd stream] =64*/ - - if (evm_dbm != 0) { - /* @Convert EVM to 0%~100% percentage */ - if (evm_dbm >= 34) - evm_percentage = 100; - else - evm_percentage = (evm_dbm << 1) + (evm_dbm); - } - } + evm_dbm = (rx_evm == -128) ? 0 : ((u8)(0 - rx_evm) >> 1); + evm_percentage = (evm_dbm >= 34) ? 100 : evm_dbm * 3; phy_info->rx_pwr[rx_path] = pwr; /*@CFO(kHz) = CFO_tail * 312.5(kHz) / 2^7 ~= CFO tail * 5/2 (kHz)*/ phy_info->cfo_tail[rx_path] = (cfo_tail * 5) >> 1; phy_info->rx_mimo_evm_dbm[rx_path] = evm_dbm; - phy_info->rx_mimo_signal_strength[rx_path] = phydm_pwr_2_percent(pwr); + phy_info->rx_mimo_signal_strength[rx_path] = phydm_pw_2_percent(pwr); phy_info->rx_mimo_signal_quality[rx_path] = evm_percentage; phy_info->rx_snr[rx_path] = rx_snr >> 1; } -void phydm_common_phy_info_3rd(s8 rx_power, u8 channel, boolean is_beamformed, - boolean is_mu_packet, u8 bandwidth, - u8 signal_quality, u8 rxsc, - struct phydm_phyinfo_struct *phy_info) +void phydm_common_phy_info_jgr3(s8 rx_power, u8 channel, boolean is_beamformed, + boolean is_mu_packet, u8 bandwidth, + u8 signal_quality, u8 rxsc, + struct phydm_phyinfo_struct *phy_info) { phy_info->rx_power = rx_power; /* RSSI in dB */ phy_info->recv_signal_power = rx_power; /* RSSI in dB */ @@ -1988,22 +1947,13 @@ void phydm_common_phy_info_3rd(s8 rx_power, u8 channel, boolean is_beamformed, phy_info->is_mu_packet = is_mu_packet; /* @MU packet */ phy_info->rxsc = rxsc; - phy_info->rx_pwdb_all = phydm_pwr_2_percent(rx_power); /*percentage */ + phy_info->rx_pwdb_all = phydm_pw_2_percent(rx_power); /*percentage */ phy_info->signal_quality = signal_quality; /* signal quality */ phy_info->band_width = bandwidth; /* @bandwidth */ - -#if 0 - /* @if (pktinfo->is_packet_match_bssid) */ - { - dbg_print("rx_pwdb_all = %d, rx_power = %d, recv_signal_power = %d\n", phy_info->rx_pwdb_all, phy_info->rx_power, phy_info->recv_signal_power); - dbg_print("signal_quality = %d\n", phy_info->signal_quality); - dbg_print("is_beamformed = %d, is_mu_packet = %d, rx_count = %d\n", phy_info->is_beamformed, phy_info->is_mu_packet, phy_info->rx_count + 1); - dbg_print("channel = %d, rxsc = %d, band_width = %d\n", channel, rxsc, bandwidth); - } -#endif } +#endif -void phydm_get_physts_jgr3_0(struct dm_struct *dm, u8 *phy_status_inf, +void phydm_get_physts_0_jgr3(struct dm_struct *dm, u8 *phy_status_inf, struct phydm_perpkt_info_struct *pktinfo, struct phydm_phyinfo_struct *phy_info) { @@ -2011,18 +1961,29 @@ void phydm_get_physts_jgr3_0(struct dm_struct *dm, u8 *phy_status_inf, struct phy_sts_rpt_jgr3_type0 *phy_sts = NULL; struct odm_phy_dbg_info *dbg_i = &dm->phy_dbg_info; u8 sq = 0, i, rx_cnt = 0; - s8 rx_power[4]; + s8 rx_power[4], pwdb; s8 rx_pwr_db_max = -120; phy_sts = (struct phy_sts_rpt_jgr3_type0 *)phy_status_inf; + #if (RTL8197G_SUPPORT) + if (dm->support_ic_type & ODM_RTL8197G) { + if (dm->rx_ant_status == BB_PATH_B) { + phy_sts->pwdb_b = phy_sts->pwdb_a; + phy_sts->gain_b = phy_sts->gain_a; + phy_sts->pwdb_a = 0; + phy_sts->gain_a = 0; + } + } + #endif + rx_power[0] = phy_sts->pwdb_a; rx_power[1] = phy_sts->pwdb_b; rx_power[2] = phy_sts->pwdb_c; rx_power[3] = phy_sts->pwdb_d; - #if (RTL8822C_SUPPORT) - if (dm->support_ic_type & ODM_RTL8822C) { + #if (RTL8822C_SUPPORT || RTL8197G_SUPPORT) + if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8197G)) { struct phydm_physts *physts_table = &dm->dm_physts_table; if (phy_sts->gain_a < physts_table->cck_gi_l_bnd) rx_power[0] += ((physts_table->cck_gi_l_bnd - @@ -2042,27 +2003,26 @@ void phydm_get_physts_jgr3_0(struct dm_struct *dm, u8 *phy_status_inf, /* @Update per-path information */ for (i = RF_PATH_A; i < dm->num_rf_path; i++) { - if (dm->rx_ant_status & BIT(i)) { - rx_cnt++; /* @check the number of the ant */ + if ((dm->rx_ant_status & BIT(i)) == 0) + continue; - if (rx_cnt > dm->num_rf_path) - break; + rx_cnt++; /* @check the number of the ant */ - if (pktinfo->is_to_self) - dm->ofdm_agc_idx[i] = rx_power[i]; + if (rx_cnt > dm->num_rf_path) + break; - /* @Setting the RX power: agc_idx -110 dBm*/ - rx_power[i] -= 110; + if (pktinfo->is_to_self) + dm->ofdm_agc_idx[i] = rx_power[i]; - /* Update CCK pwdb */ - /* Update per-path information */ - phydm_per_path_info_3rd(i, rx_power[i], 0, 0, 0, - phy_info); + /* @Setting the RX power: agc_idx -110 dBm*/ + pwdb = rx_power[i] - 110; - /* search maximum pwdb */ - if (rx_power[i] > rx_pwr_db_max) - rx_pwr_db_max = rx_power[i]; - } + phy_info->rx_pwr[i] = pwdb; + phy_info->rx_mimo_signal_strength[i] = phydm_pw_2_percent(pwdb); + + /* search maximum pwdb */ + if (pwdb > rx_pwr_db_max) + rx_pwr_db_max = pwdb; } /* @Calculate Signal Quality*/ @@ -2094,10 +2054,16 @@ void phydm_get_physts_jgr3_0(struct dm_struct *dm, u8 *phy_status_inf, dbg_i->is_ldpc_pkt = false; dbg_i->is_stbc_pkt = false; - /* Update Common information */ - phydm_common_phy_info_3rd(rx_pwr_db_max, phy_sts->channel, false, - false, CHANNEL_WIDTH_20, sq, - phy_sts->l_rxsc, phy_info); + /*cck channel has hw bug, [WLANBB-1429]*/ + phy_info->channel = 0; + phy_info->rx_power = rx_pwr_db_max; + phy_info->recv_signal_power = rx_pwr_db_max; + phy_info->is_beamformed = false; + phy_info->is_mu_packet = false; + phy_info->rxsc = phy_sts->l_rxsc; + phy_info->rx_pwdb_all = phydm_pw_2_percent(rx_pwr_db_max); + phy_info->signal_quality = sq; + phy_info->band_width = CHANNEL_WIDTH_20; #ifdef CONFIG_PHYDM_ANTENNA_DIVERSITY dm->dm_fat_table.antsel_rx_keep_0 = phy_sts->antidx_a; @@ -2107,100 +2073,44 @@ void phydm_get_physts_jgr3_0(struct dm_struct *dm, u8 *phy_status_inf, #endif } -void phydm_get_physts_jgr3_1(struct dm_struct *dm, u8 *phy_status_inf, - struct phydm_perpkt_info_struct *pktinfo, - struct phydm_phyinfo_struct *phy_info) +void phydm_get_physts_1_others_jgr3(struct dm_struct *dm, u8 *phy_status_inf, + struct phydm_perpkt_info_struct *pktinfo, + struct phydm_phyinfo_struct *phy_info) { - /* type 1 is used for ofdm packet */ struct phy_sts_rpt_jgr3_type1 *phy_sts = NULL; struct odm_phy_dbg_info *dbg_i = &dm->phy_dbg_info; - s8 rx_pwr_db = -120; - s8 rx_path_pwr_db = 0; - u8 i, rxsc, bw = CHANNEL_WIDTH_20, rx_cnt = 0; - u8 pwdb[4]; - boolean is_mu = false; + s8 evm = 0; + u8 i; + s8 sq = 0; phy_sts = (struct phy_sts_rpt_jgr3_type1 *)phy_status_inf; - pwdb[0] = phy_sts->pwdb_a; - pwdb[1] = phy_sts->pwdb_b; - pwdb[2] = phy_sts->pwdb_c; - pwdb[3] = phy_sts->pwdb_d; + /* SNR: S(8,1), EVM: S(8,1), CFO: S(8,7) */ - /* Update per-path information */ for (i = RF_PATH_A; i < dm->num_rf_path; i++) { - if (dm->rx_ant_status & BIT(i)) { - rx_cnt++; /* @check the number of the ant */ + if ((dm->rx_ant_status & BIT(i)) == 0) + continue; - if (rx_cnt > dm->num_rf_path) - break; + evm = phy_sts->rxevm[i]; + evm = (evm == -128) ? 0 : ((0 - evm) >> 1); + sq = (evm >= 34) ? 100 : evm * 3; /* @Convert EVM to 0~100%*/ - /* Update per-path information - * (RSSI_dB RSSI_percentage EVM SNR CFO sq) - */ - /* @EVM report is reported by stream, not path */ - /* @per-path pw (dB)*/ - rx_path_pwr_db = (s8)pwdb[i] - 110; - - if (pktinfo->is_to_self) - dm->ofdm_agc_idx[i] = pwdb[i]; - - phydm_per_path_info_3rd(i, rx_path_pwr_db, - phy_sts->rxevm[rx_cnt - 1], - phy_sts->cfo_tail[i], - phy_sts->rxsnr[i], phy_info); - - /*@CFO(kHz) = CFO_tail*312.5/2^7 ~= CFO tail*5/2*/ - dbg_i->cfo_tail[i] = (phy_sts->cfo_tail[i] * 5) >> 1; - /* search maximum pwdb */ - if (rx_path_pwr_db > rx_pwr_db) - rx_pwr_db = rx_path_pwr_db; - } + phy_info->rx_mimo_evm_dbm[i] = (u8)evm; + phy_info->rx_mimo_signal_quality[i] = sq; + phy_info->rx_snr[i] = phy_sts->rxsnr[i] >> 1; + /*@CFO(kHz) = CFO_tail*312.5(kHz)/2^7 ~= CFO tail * 5/2 (kHz)*/ + phy_info->cfo_tail[i] = (phy_sts->cfo_tail[i] * 5) >> 1; + dbg_i->cfo_tail[i] = (phy_sts->cfo_tail[i] * 5) >> 1; } + phy_info->signal_quality = phy_info->rx_mimo_signal_quality[0]; - /* @mapping RX counter from 1~4 to 0~3 */ - if (rx_cnt > 0) - phy_info->rx_count = rx_cnt - 1; - - /* @Check if MU packet or not */ if (phy_sts->gid != 0 && phy_sts->gid != 63) { - is_mu = true; + phy_info->is_mu_packet = true; dbg_i->num_qry_mu_pkt++; } else { - is_mu = false; + phy_info->is_mu_packet = false; } - /* @count BF packet */ - dbg_i->num_qry_bf_pkt = dbg_i->num_qry_bf_pkt + phy_sts->beamformed; - - /*STBC or LDPC pkt*/ - dbg_i->is_ldpc_pkt = phy_sts->ldpc; - dbg_i->is_stbc_pkt = phy_sts->stbc; - - /* @Check sub-channel */ - if (pktinfo->data_rate > ODM_RATE11M && - pktinfo->data_rate < ODM_RATEMCS0) - rxsc = phy_sts->l_rxsc; /*@Legacy*/ - else - rxsc = phy_sts->ht_rxsc; /* @HT and VHT */ - - /* @Check RX bandwidth */ - if (rxsc >= 1 && rxsc <= 8) - bw = CHANNEL_WIDTH_20; - else if (rxsc >= 9 && rxsc <= 12) - bw = CHANNEL_WIDTH_40; - else if (rxsc >= 13) - bw = CHANNEL_WIDTH_80; - else - bw = *dm->band_width; - - /* Update packet information */ - /* RX power choose the path with the maximum power */ - phydm_common_phy_info_3rd(rx_pwr_db, phy_sts->channel_pri_lsb, - (boolean)phy_sts->beamformed, is_mu, - bw, phy_info->rx_mimo_signal_quality[0], - rxsc, phy_info); - phydm_parsing_cfo(dm, pktinfo, phy_sts->cfo_tail, pktinfo->rate_ss); #if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) @@ -2211,239 +2121,180 @@ void phydm_get_physts_jgr3_1(struct dm_struct *dm, u8 *phy_status_inf, #endif } -void phydm_get_physts_jgr3_2_3(struct dm_struct *dm, u8 *phy_status_inf, - struct phydm_perpkt_info_struct *pktinfo, - struct phydm_phyinfo_struct *phy_info) +void phydm_get_physts_2_others_jgr3(struct dm_struct *dm, u8 *phy_status_inf, + struct phydm_perpkt_info_struct *pktinfo, + struct phydm_phyinfo_struct *phy_info) { /* type 2 & 3 is used for ofdm packet */ struct phy_sts_rpt_jgr3_type2_3 *phy_sts = NULL; - struct odm_phy_dbg_info *dbg_i = &dm->phy_dbg_info; - s8 rx_pwr_db_max = -120; - s8 rx_path_pwr_db = 0; - u8 i, rxsc, bw = CHANNEL_WIDTH_20, rx_count = 0; - - phy_sts = (struct phy_sts_rpt_jgr3_type2_3 *)phy_status_inf; - - /* Update per-path information */ - for (i = RF_PATH_A; i < dm->num_rf_path; i++) { - if (dm->rx_ant_status & BIT(i)) { - rx_count++; /* @check the number of the ant */ - - if (rx_count > dm->num_rf_path) - break; - - /* Update per-path information - * (RSSI_dB RSSI_percentage EVM SNR CFO sq) - */ - /* @EVM report is reported by stream, not path */ - rx_path_pwr_db = (s8)phy_sts->pwdb[i] - 110; /*@dB*/ - - if (pktinfo->is_to_self) - dm->ofdm_agc_idx[i] = phy_sts->pwdb[i]; - - phydm_per_path_info_3rd(i, rx_path_pwr_db, 0, - 0, 0, phy_info); - - /* search maximum pwdb */ - if (rx_path_pwr_db > rx_pwr_db_max) - rx_pwr_db_max = rx_path_pwr_db; - } - } - - /* @mapping RX counter from 1~4 to 0~3 */ - if (rx_count > 0) - phy_info->rx_count = rx_count - 1; - - /* @count BF packet */ - dbg_i->num_qry_bf_pkt = dm->phy_dbg_info.num_qry_bf_pkt + - phy_sts->beamformed; - - /*STBC or LDPC pkt*/ - dbg_i->is_ldpc_pkt = phy_sts->ldpc; - dbg_i->is_stbc_pkt = phy_sts->stbc; - - /* @Check sub-channel */ - if (pktinfo->data_rate > ODM_RATE11M && - pktinfo->data_rate < ODM_RATEMCS0) - rxsc = phy_sts->l_rxsc; /*@Legacy*/ - else - rxsc = phy_sts->ht_rxsc; /* @HT and VHT */ - - /* @Check RX bandwidth */ - if (rxsc >= 1 && rxsc <= 8) - bw = CHANNEL_WIDTH_20; - else if (rxsc >= 9 && rxsc <= 12) - bw = CHANNEL_WIDTH_40; - else if (rxsc >= 13) - bw = CHANNEL_WIDTH_80; - else - bw = *dm->band_width; - - /* Update packet information */ - /* RX power choose the path with the maximum power */ - phydm_common_phy_info_3rd(rx_pwr_db_max, phy_sts->channel_lsb, - (boolean)phy_sts->beamformed, - false, bw, 0, rxsc, phy_info); } -void phydm_get_physts_jgr3_4(struct dm_struct *dm, u8 *phy_status_inf, - struct phydm_perpkt_info_struct *pktinfo, - struct phydm_phyinfo_struct *phy_info) +void phydm_get_physts_4_others_jgr3(struct dm_struct *dm, u8 *phy_status_inf, + struct phydm_perpkt_info_struct *pktinfo, + struct phydm_phyinfo_struct *phy_info) { - /* type 4 is used for ofdm packet */ struct phy_sts_rpt_jgr3_type4 *phy_sts = NULL; struct odm_phy_dbg_info *dbg_i = &dm->phy_dbg_info; - s8 rx_pwr_db_max = -120; - s8 rx_path_pwr_db = 0; - u8 i, rxsc, bw = CHANNEL_WIDTH_20, rx_cnt = 0; + s8 evm = 0; + u8 i; + s8 sq = 0; phy_sts = (struct phy_sts_rpt_jgr3_type4 *)phy_status_inf; - /* Update per-path information */ + /* SNR: S(8,1), EVM: S(8,1), CFO: S(8,7) */ + for (i = RF_PATH_A; i < dm->num_rf_path; i++) { - if (dm->rx_ant_status & BIT(i)) { - rx_cnt++; /* @check the number of the ant */ + if ((dm->rx_ant_status & BIT(i)) == 0) + continue; - if (rx_cnt > dm->num_rf_path) - break; + evm = phy_sts->rxevm[i]; + evm = (evm == -128) ? 0 : ((0 - evm) >> 1); + sq = (evm >= 34) ? 100 : evm * 3; /* @Convert EVM to 0~100%*/ - /* Update per-path information - * (RSSI_dB RSSI_percentage EVM SNR CFO sq) - */ - /* @EVM report is reported by stream, not path */ - rx_path_pwr_db = (s8)phy_sts->pwdb[i] - 110; /*@dB*/ - - if (pktinfo->is_to_self) - dm->ofdm_agc_idx[i] = phy_sts->pwdb[i]; - - phydm_per_path_info_3rd(i, rx_path_pwr_db, - phy_sts->rxevm[rx_cnt - 1], - 0, phy_sts->rxsnr[i], - phy_info); - - /* search maximum pwdb */ - if (rx_path_pwr_db > rx_pwr_db_max) - rx_pwr_db_max = rx_path_pwr_db; - } + phy_info->rx_mimo_evm_dbm[i] = (u8)evm; + phy_info->rx_mimo_signal_quality[i] = sq; + phy_info->rx_snr[i] = phy_sts->rxsnr[i] >> 1; } - - /* @mapping RX counter from 1~4 to 0~3 */ - if (rx_cnt > 0) - phy_info->rx_count = rx_cnt - 1; - - /* @count BF packet */ - dbg_i->num_qry_bf_pkt = dm->phy_dbg_info.num_qry_bf_pkt + - phy_sts->beamformed; - - /* @STBC or LDPC pkt*/ - dbg_i->is_ldpc_pkt = phy_sts->ldpc; - dbg_i->is_stbc_pkt = phy_sts->stbc; - - /* @Check sub-channel */ - if (pktinfo->data_rate > ODM_RATE11M && - pktinfo->data_rate < ODM_RATEMCS0) - rxsc = phy_sts->l_rxsc; /*@Legacy*/ - else - rxsc = phy_sts->ht_rxsc; /* @HT and VHT */ - - /* @Check RX bandwidth */ - if (rxsc >= 1 && rxsc <= 8) - bw = CHANNEL_WIDTH_20; - else if (rxsc >= 9 && rxsc <= 12) - bw = CHANNEL_WIDTH_40; - else if (rxsc >= 13) - bw = CHANNEL_WIDTH_80; - else - bw = *dm->band_width; - - /* @Conditional number */ - dbg_i->condi_num = (u32)phy_sts->avg_cond_num_0; - - /* Update packet information */ - /* RX power choose the path with the maximum power */ - phydm_common_phy_info_3rd(rx_pwr_db_max, phy_sts->channel_lsb, - (boolean)phy_sts->beamformed, - false, bw, 0, rxsc, phy_info); + phy_info->signal_quality = phy_info->rx_mimo_signal_quality[0]; +#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) + dm->dm_fat_table.antsel_rx_keep_0 = phy_sts->antidx_a; + dm->dm_fat_table.antsel_rx_keep_1 = phy_sts->antidx_b; + dm->dm_fat_table.antsel_rx_keep_2 = phy_sts->antidx_c; + dm->dm_fat_table.antsel_rx_keep_3 = phy_sts->antidx_d; +#endif + odm_move_memory(dm, dbg_i->eigen_val, phy_sts->eigenvalue, 4); + dbg_i->condition_num_seg0 = phy_sts->avg_cond_num_0; } -void phydm_get_physts_jgr3_5(struct dm_struct *dm, u8 *phy_status_inf, +void phydm_get_physts_5_others_jgr3(struct dm_struct *dm, u8 *phy_status_inf, + struct phydm_perpkt_info_struct *pktinfo, + struct phydm_phyinfo_struct *phy_info) +{ + struct phy_sts_rpt_jgr3_type5 *phy_sts = NULL; + +} +#if (RTL8723F_SUPPORT) +void phydm_get_physts_6_jgr3(struct dm_struct *dm, u8 *phy_status_inf, struct phydm_perpkt_info_struct *pktinfo, struct phydm_phyinfo_struct *phy_info) { - /* type 5 is used for ofdm packet */ - struct phy_sts_rpt_jgr3_type5 *phy_sts = NULL; + /* type 0 is used for cck packet */ + struct phy_sts_rpt_jgr3_type6 *phy_sts = NULL; + struct odm_phy_dbg_info *dbg_i = &dm->phy_dbg_info; + u8 sq = 0, i, rx_cnt = 0; + s8 rx_power[4], pwdb; + s8 rx_pwr_db_max = -120; + u8 evm = 0; + phy_sts = (struct phy_sts_rpt_jgr3_type6 *)phy_status_inf; + /* judy_add_8723F_0512 */ + /* rssi S(11,3) */ + rx_power[0] = (s8)((phy_sts->rssi_msb << 5) + (phy_sts->rssi >> 3)); + /* @Update per-path information */ + for (i = RF_PATH_A; i < dm->num_rf_path; i++) { + if ((dm->rx_ant_status & BIT(i)) == 0) + continue; + + rx_cnt++; /* @check the number of the ant */ + + if (rx_cnt > dm->num_rf_path) + break; + + if (pktinfo->is_to_self) + dm->ofdm_agc_idx[i] = rx_power[i]+110; + + /* @Setting the RX power: agc_idx dBm*/ + pwdb = rx_power[i]; + + phy_info->rx_pwr[i] = pwdb; + phy_info->rx_mimo_signal_strength[i] = phydm_pw_2_percent(pwdb); + + /* search maximum pwdb */ + if (pwdb > rx_pwr_db_max) + rx_pwr_db_max = pwdb; + } + + /* @Calculate EVM U(8,2)*/ + evm = phy_sts->evm_pld >> 2; + if (pktinfo->data_rate > ODM_RATE2M) + phy_info->rx_cck_evm = (u8)(evm - 10);/* @5_5M/11M*/ + else + phy_info->rx_cck_evm = (u8)(evm - 12);/* @1M/2M*/ + + sq = (phy_info->rx_cck_evm >= 34) ? 100 : phy_info->rx_cck_evm * 3; + phy_info->signal_quality = sq; + /*@CCK no STBC and LDPC*/ + dbg_i->is_ldpc_pkt = false; + dbg_i->is_stbc_pkt = false; + + /*cck channel has hw bug, [WLANBB-1429]*/ + phy_info->channel = 0; + phy_info->rx_power = rx_pwr_db_max; + phy_info->recv_signal_power = rx_pwr_db_max; + phy_info->is_beamformed = false; + phy_info->is_mu_packet = false; + phy_info->rx_pwdb_all = phydm_pw_2_percent(rx_pwr_db_max); + phy_info->band_width = CHANNEL_WIDTH_20; + + //phydm_parsing_cfo(dm, pktinfo, phy_sts->avg_cfo, pktinfo->rate_ss); + + #ifdef CONFIG_PHYDM_ANTENNA_DIVERSITY + dm->dm_fat_table.antsel_rx_keep_0 = phy_sts->antidx_a; + dm->dm_fat_table.antsel_rx_keep_1 = 0; + dm->dm_fat_table.antsel_rx_keep_2 = 0; + dm->dm_fat_table.antsel_rx_keep_3 = 0; + #endif +} +#endif +void phydm_get_physts_ofdm_cmn_jgr3(struct dm_struct *dm, u8 *phy_status_inf, + struct phydm_perpkt_info_struct *pktinfo, + struct phydm_phyinfo_struct *phy_info) +{ + struct phy_sts_rpt_jgr3_ofdm_cmn *phy_sts = NULL; struct odm_phy_dbg_info *dbg_i = &dm->phy_dbg_info; s8 rx_pwr_db_max = -120; - s8 rx_path_pwr_db = 0; - u8 i, rxsc, bw = CHANNEL_WIDTH_20, rx_count = 0; + s8 pwdb = 0; + u8 i, rx_cnt = 0; - phy_sts = (struct phy_sts_rpt_jgr3_type5 *)phy_status_inf; + phy_sts = (struct phy_sts_rpt_jgr3_ofdm_cmn *)phy_status_inf; - /* Update per-path information */ + /* Parsing Offset0 & 4*/ for (i = RF_PATH_A; i < dm->num_rf_path; i++) { - if (dm->rx_ant_status & BIT(i)) { - rx_count++; /* @check the number of the ant */ + if ((dm->rx_ant_status & BIT(i)) == 0) + continue; - if (rx_count > dm->num_rf_path) - break; + rx_cnt++; /* @check the number of the ant */ - /* Update per-path information - * (RSSI_dB RSSI_percentage EVM SNR CFO sq) - */ - /* @EVM report is reported by stream, not path */ - rx_path_pwr_db = (s8)phy_sts->pwdb[i] - 110; /*@dB*/ + pwdb = (s8)phy_sts->pwdb[i] - 110; /*@dB*/ - if (pktinfo->is_to_self) - dm->ofdm_agc_idx[i] = phy_sts->pwdb[i]; + if (pktinfo->is_to_self) + dm->ofdm_agc_idx[i] = phy_sts->pwdb[i]; - phydm_per_path_info_3rd(i, rx_path_pwr_db, - 0, 0, 0, phy_info); + /* search maximum pwdb */ + if (pwdb > rx_pwr_db_max) + rx_pwr_db_max = pwdb; - /* search maximum pwdb */ - if (rx_path_pwr_db > rx_pwr_db_max) - rx_pwr_db_max = rx_path_pwr_db; - } + phy_info->rx_pwr[i] = pwdb; + phy_info->rx_mimo_signal_strength[i] = phydm_pw_2_percent(pwdb); } - /* @mapping RX counter from 1~4 to 0~3 */ - if (rx_count > 0) - phy_info->rx_count = rx_count - 1; + phy_info->rx_count = (rx_cnt > 0) ? rx_cnt - 1 : 0; /*from 1~4 to 0~3 */ + phy_info->rx_power = rx_pwr_db_max; + phy_info->rx_pwdb_all = phydm_pw_2_percent(rx_pwr_db_max); + phy_info->recv_signal_power = rx_pwr_db_max; + phy_info->channel = phy_sts->channel_lsb; + phy_info->is_beamformed = (boolean)phy_sts->beamformed; + phy_info->rxsc = (PHYDM_IS_LEGACY_RATE(pktinfo->data_rate)) ? + phy_sts->l_rxsc : phy_sts->ht_rxsc; + phy_info->band_width = phydm_rxsc_2_bw(dm, phy_info->rxsc); - /* @count BF packet */ - dbg_i->num_qry_bf_pkt = dm->phy_dbg_info.num_qry_bf_pkt + - phy_sts->beamformed; - - /*STBC or LDPC pkt*/ dbg_i->is_ldpc_pkt = phy_sts->ldpc; dbg_i->is_stbc_pkt = phy_sts->stbc; - - /* @Check sub-channel */ - if (pktinfo->data_rate > ODM_RATE11M && - pktinfo->data_rate < ODM_RATEMCS0) - rxsc = phy_sts->l_rxsc; /*@Legacy*/ - else - rxsc = phy_sts->ht_rxsc; /* @HT and VHT */ - - /* @Check RX bandwidth */ - if (rxsc >= 1 && rxsc <= 8) - bw = CHANNEL_WIDTH_20; - else if (rxsc >= 9 && rxsc <= 12) - bw = CHANNEL_WIDTH_40; - else if (rxsc >= 13) - bw = CHANNEL_WIDTH_80; - else - bw = *dm->band_width; - - /* Update packet information */ - /* RX power choose the path with the maximum power */ - phydm_common_phy_info_3rd(rx_pwr_db_max, phy_sts->channel_lsb, - (boolean)phy_sts->beamformed, - false, bw, 0, rxsc, phy_info); + dbg_i->num_qry_bf_pkt += phy_sts->beamformed; } -void phydm_process_dm_rssi_3rd_type(struct dm_struct *dm, - struct phydm_phyinfo_struct *phy_info, - struct phydm_perpkt_info_struct *pktinfo) +void phydm_process_dm_rssi_jgr3(struct dm_struct *dm, + struct phydm_phyinfo_struct *phy_info, + struct phydm_perpkt_info_struct *pktinfo) { struct cmn_sta_info *sta = NULL; struct rssi_info *rssi_t = NULL; @@ -2477,6 +2328,15 @@ void phydm_process_dm_rssi_3rd_type(struct dm_struct *dm, dm->phy_dbg_info.beacon_phy_rate = pktinfo->data_rate; } + #if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) + if (dm->support_ability & ODM_BB_ANT_DIV) + odm_process_rssi_for_ant_div(dm, phy_info, pktinfo); + #endif + + #ifdef ODM_EVM_ENHANCE_ANTDIV + phydm_rx_rate_for_antdiv(dm, pktinfo); + #endif + #if (defined(CONFIG_PATH_DIVERSITY)) if (dm->support_ability & ODM_BB_PATH_DIV) phydm_process_rssi_for_path_div(dm, phy_info, pktinfo); @@ -2489,11 +2349,6 @@ void phydm_process_dm_rssi_3rd_type(struct dm_struct *dm, rssi_t = &sta->rssi_stat; - if (pktinfo->is_cck_rate) - rssi_t->rssi_cck = (s8)rssi_db; - else - rssi_t->rssi_ofdm = (s8)rssi_db; - for (i = 0; i < dm->num_rf_path; i++) { rssi_tmp = phy_info->rx_mimo_signal_strength[i]; if (rssi_tmp != 0) { @@ -2525,49 +2380,89 @@ void phydm_process_dm_rssi_3rd_type(struct dm_struct *dm, rssi_t->rssi_acc = MA_ACC(rssi_t->rssi_acc, rssi_db, RSSI_MA); rssi_t->rssi = (s8)GET_MA_VAL(rssi_t->rssi_acc, RSSI_MA); } + + if (pktinfo->is_cck_rate) + rssi_t->rssi_cck = (s8)rssi_db; + else + rssi_t->rssi_ofdm = (s8)rssi_db; } -void phydm_rx_physts_3rd_type(void *dm_void, u8 *phy_sts, - struct phydm_perpkt_info_struct *pktinfo, - struct phydm_phyinfo_struct *phy_info) +void phydm_rx_physts_jgr3(void *dm_void, u8 *phy_sts, + struct phydm_perpkt_info_struct *pktinfo, + struct phydm_phyinfo_struct *phy_info) { struct dm_struct *dm = (struct dm_struct *)dm_void; u8 phy_status_type = (*phy_sts & 0xf); - + if (dm->support_ic_type & ODM_RTL8723F) { + if (pktinfo->data_rate <= ODM_RATE11M) + phy_status_type = 6; + } /*@[Step 2]*/ - phydm_reset_phy_info_3rd(dm, phy_info); /* @Memory reset */ + /*phydm_reset_phy_info_jgr3(dm, phy_info);*/ /* @Memory reset */ /* Phy status parsing */ switch (phy_status_type) { case 0: /*@CCK*/ - phydm_get_physts_jgr3_0(dm, phy_sts, pktinfo, phy_info); + phydm_get_physts_0_jgr3(dm, phy_sts, pktinfo, phy_info); break; case 1: - phydm_get_physts_jgr3_1(dm, phy_sts, pktinfo, phy_info); + phydm_get_physts_ofdm_cmn_jgr3(dm, phy_sts, pktinfo, phy_info); + phydm_get_physts_1_others_jgr3(dm, phy_sts, pktinfo, phy_info); break; case 2: case 3: - phydm_get_physts_jgr3_2_3(dm, phy_sts, pktinfo, phy_info); + phydm_get_physts_ofdm_cmn_jgr3(dm, phy_sts, pktinfo, phy_info); + phydm_get_physts_2_others_jgr3(dm, phy_sts, pktinfo, phy_info); break; case 4: - #ifdef PHYDM_PHYSTAUS_AUTO_SWITCH - if (dm->pkt_proc_struct.physts_auto_swch_en) - phydm_get_physts_jgr3_4_cn(dm, - phy_sts, pktinfo, phy_info); - else - #endif - phydm_get_physts_jgr3_4(dm, phy_sts, pktinfo, phy_info); + phydm_get_physts_ofdm_cmn_jgr3(dm, phy_sts, pktinfo, phy_info); + phydm_get_physts_4_others_jgr3(dm, phy_sts, pktinfo, phy_info); break; case 5: - phydm_get_physts_jgr3_5(dm, phy_sts, pktinfo, phy_info); + phydm_get_physts_ofdm_cmn_jgr3(dm, phy_sts, pktinfo, phy_info); + phydm_get_physts_5_others_jgr3(dm, phy_sts, pktinfo, phy_info); break; +#if (RTL8723F_SUPPORT) + case 6: + phydm_get_physts_6_jgr3(dm, phy_sts, pktinfo, phy_info); + break; +#endif default: break; } +#if 0 + PHYDM_DBG(dm, DBG_PHY_STATUS, "RSSI: {%d, %d}\n", + phy_info->rx_mimo_signal_strength[0], + phy_info->rx_mimo_signal_strength[1]); + PHYDM_DBG(dm, DBG_PHY_STATUS, "rxdb: {%d, %d}\n", + phy_info->rx_pwr[0], phy_info->rx_pwr[1]); + PHYDM_DBG(dm, DBG_PHY_STATUS, "EVM: {%d, %d}\n", + phy_info->rx_mimo_evm_dbm[0], phy_info->rx_mimo_evm_dbm[1]); + PHYDM_DBG(dm, DBG_PHY_STATUS, "SQ: {%d, %d}\n", + phy_info->rx_mimo_signal_quality[0], + phy_info->rx_mimo_signal_quality[1]); + PHYDM_DBG(dm, DBG_PHY_STATUS, "SNR: {%d, %d}\n", + phy_info->rx_snr[0], phy_info->rx_snr[1]); + PHYDM_DBG(dm, DBG_PHY_STATUS, "CFO: {%d, %d}\n", + phy_info->cfo_tail[0], phy_info->cfo_tail[1]); + PHYDM_DBG(dm, DBG_PHY_STATUS, + "rx_pwdb_all = %d, rx_power = %d, recv_signal_power = %d\n", + phy_info->rx_pwdb_all, phy_info->rx_power, + phy_info->recv_signal_power); + PHYDM_DBG(dm, DBG_PHY_STATUS, "signal_quality = %d\n", + phy_info->signal_quality); + PHYDM_DBG(dm, DBG_PHY_STATUS, + "is_beamformed = %d, is_mu_packet = %d, rx_count = %d\n", + phy_info->is_beamformed, phy_info->is_mu_packet, + phy_info->rx_count); + PHYDM_DBG(dm, DBG_PHY_STATUS, + "channel = %d, rxsc = %d, band_width = %d\n", + phy_info->channel, phy_info->rxsc, phy_info->band_width); +#endif /*@[Step 1]*/ - phydm_print_phystat_jaguar3(dm, phy_sts, pktinfo, phy_info); + phydm_print_phystat_jgr3(dm, phy_sts, pktinfo, phy_info); } #endif @@ -2599,33 +2494,6 @@ phydm_query_is_mu_api(struct dm_struct *phydm, u8 ppdu_idx, u8 *p_data_rate, return is_mu; } -void phydm_reset_phy_info(struct dm_struct *phydm, - struct phydm_phyinfo_struct *phy_info) -{ - phy_info->rx_pwdb_all = 0; - phy_info->signal_quality = 0; - phy_info->band_width = 0; - phy_info->rx_count = 0; - odm_memory_set(phydm, phy_info->rx_mimo_signal_quality, 0, 4); - odm_memory_set(phydm, phy_info->rx_mimo_signal_strength, 0, 4); - odm_memory_set(phydm, phy_info->rx_snr, 0, 4); - - phy_info->rx_power = -110; - phy_info->recv_signal_power = -110; - phy_info->bt_rx_rssi_percentage = 0; - phy_info->signal_strength = 0; - phy_info->channel = 0; - phy_info->is_mu_packet = 0; - phy_info->is_beamformed = 0; - phy_info->rxsc = 0; - odm_memory_set(phydm, phy_info->rx_pwr, -110, 4); - odm_memory_set(phydm, phy_info->cfo_short, 0, 8); - odm_memory_set(phydm, phy_info->cfo_tail, 0, 8); - odm_memory_set(phydm, phy_info->ant_idx, 0, 4); - - odm_memory_set(phydm, phy_info->rx_mimo_evm_dbm, 0, 4); -} - void phydm_print_phy_sts_jgr2(struct dm_struct *dm, u8 *phy_status_inf, struct phydm_perpkt_info_struct *pktinfo, struct phydm_phyinfo_struct *phy_info) @@ -2771,7 +2639,7 @@ void phydm_set_per_path_phy_info(u8 rx_path, s8 pwr, s8 rx_evm, s8 cfo_tail, /*@CFO(kHz) = CFO_tail * 312.5(kHz) / 2^7 ~= CFO tail * 5/2 (kHz)*/ phy_info->cfo_tail[rx_path] = (cfo_tail * 5) >> 1; phy_info->rx_mimo_evm_dbm[rx_path] = evm_dbm; - phy_info->rx_mimo_signal_strength[rx_path] = phydm_pwr_2_percent(pwr); + phy_info->rx_mimo_signal_strength[rx_path] = phydm_pw_2_percent(pwr); phy_info->rx_mimo_signal_quality[rx_path] = evm_percentage; phy_info->rx_snr[rx_path] = rx_snr >> 1; phy_info->ant_idx[rx_path] = ant_idx; @@ -2806,7 +2674,7 @@ void phydm_set_common_phy_info(s8 rx_power, u8 channel, boolean is_beamformed, phy_info->rxsc = rxsc; /* RSSI in percentage */ - phy_info->rx_pwdb_all = phydm_pwr_2_percent(rx_power); + phy_info->rx_pwdb_all = phydm_pw_2_percent(rx_power); phy_info->signal_quality = signal_quality; /* signal quality */ phy_info->band_width = bandwidth; /* @bandwidth */ @@ -3211,8 +3079,6 @@ void phydm_rx_physts_2nd_type(void *dm_void, u8 *phy_sts, struct dm_struct *dm = (struct dm_struct *)dm_void; u8 page = (*phy_sts & 0xf); - phydm_reset_phy_info(dm, phy_info); /* @Memory reset */ - /* Phy status parsing */ switch (page) { case 0: /*@CCK*/ @@ -3237,15 +3103,19 @@ void phydm_rx_physts_2nd_type(void *dm_void, u8 *phy_sts, /*@==============================================*/ #endif -void odm_phy_status_query(struct dm_struct *dm, - struct phydm_phyinfo_struct *phy_info, - u8 *phy_sts, - struct phydm_perpkt_info_struct *pktinfo) +boolean odm_phy_status_query(struct dm_struct *dm, + struct phydm_phyinfo_struct *phy_info, + u8 *phy_sts, + struct phydm_perpkt_info_struct *pktinfo) { +#ifdef PHYDM_PHYSTAUS_AUTO_SWITCH + struct pkt_process_info *pkt_proc = &dm->pkt_proc_struct; + boolean auto_swch_en = dm->pkt_proc_struct.physts_auto_swch_en; +#endif u8 rate = pktinfo->data_rate; u8 page = (*phy_sts & 0xf); - pktinfo->is_cck_rate = (rate <= ODM_RATE11M) ? true : false; + pktinfo->is_cck_rate = PHYDM_IS_CCK_RATE(rate); pktinfo->rate_ss = phydm_rate_to_num_ss(dm, rate); dm->rate_ss = pktinfo->rate_ss; /*@For AP EVM SW antenna diversity use*/ @@ -3255,18 +3125,19 @@ void odm_phy_status_query(struct dm_struct *dm, dm->phy_dbg_info.num_qry_phy_status_ofdm++; /*Reset phy_info*/ - odm_memory_set(dm, phy_info->rx_mimo_signal_strength, 0, 4); - odm_memory_set(dm, phy_info->rx_mimo_signal_quality, 0, 4); + phydm_reset_phy_info(dm, phy_info); + if (dm->support_ic_type & PHYSTS_3RD_TYPE_IC) { #ifdef PHYSTS_3RD_TYPE_SUPPORT #ifdef PHYDM_PHYSTAUS_AUTO_SWITCH if (phydm_physts_auto_switch_jgr3(dm, phy_sts, pktinfo)) { PHYDM_DBG(dm, DBG_PHY_STATUS, "SKIP parsing\n"); - return; + phy_info->physts_rpt_valid = false; + return false; } #endif - phydm_rx_physts_3rd_type(dm, phy_sts, pktinfo, phy_info); - phydm_process_dm_rssi_3rd_type(dm, phy_info, pktinfo); + phydm_rx_physts_jgr3(dm, phy_sts, pktinfo, phy_info); + phydm_process_dm_rssi_jgr3(dm, phy_info, pktinfo); #endif } else if (dm->support_ic_type & PHYSTS_2ND_TYPE_IC) { #if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT) @@ -3290,8 +3161,7 @@ void odm_phy_status_query(struct dm_struct *dm, #endif /*For basic debug message*/ - if (pktinfo->is_packet_match_bssid || pktinfo->is_packet_beacon || - *dm->mp_mode) { + if (pktinfo->is_packet_match_bssid || *dm->mp_mode) { dm->curr_station_id = pktinfo->station_id; dm->rx_rate = rate; dm->rssi_a = phy_info->rx_mimo_signal_strength[RF_PATH_A]; @@ -3308,19 +3178,21 @@ void odm_phy_status_query(struct dm_struct *dm, else if (phy_info->band_width == CHANNEL_WIDTH_80) dm->rxsc_80 = (s8)phy_info->rxsc; - #ifdef PHYSTS_3RD_TYPE_SUPPORT #ifdef PHYDM_PHYSTAUS_AUTO_SWITCH - if (page == 4 && dm->pkt_proc_struct.physts_auto_swch_en && - pktinfo->rate_ss > 1) { - phydm_avg_phystatus_index_p4(dm, phy_info, pktinfo); - } else if (page <= 1) - #endif + if (auto_swch_en && page == 4 && pktinfo->rate_ss > 1) + phydm_avg_condi_num(dm, phy_info, pktinfo); + + if (!auto_swch_en || + (pkt_proc->is_1st_mpdu || PHYDM_IS_LEGACY_RATE(rate))) #endif { - phydm_avg_phystatus_index_p1(dm, phy_info, pktinfo); + phydm_avg_rssi_evm_snr(dm, phy_info, pktinfo); phydm_rx_statistic_cal(dm, phy_info, phy_sts, pktinfo); } } + + phy_info->physts_rpt_valid = true; + return true; } void phydm_rx_phy_status_init(void *dm_void) @@ -3333,10 +3205,9 @@ void phydm_rx_phy_status_init(void *dm_void) dbg->show_phy_sts_cnt = 0; phydm_avg_phystatus_init(dm); - #if 0 + #ifdef PHYDM_PHYSTAUS_AUTO_SWITCH - phydm_physts_auto_switch_jgr3_set(dm, true, BIT(4) | BIT(1)); - #endif + dm->pkt_proc_struct.physts_auto_swch_en = false; #endif } @@ -3352,14 +3223,13 @@ void phydm_physts_dbg(void *dm_void, char input[][16], u32 *_used, u8 i = 0; for (i = 0; i < 3; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var[i]); } if ((strcmp(input[1], help) == 0)) { PDM_SNPF(out_len, used, output + used, out_len - used, - "Page Auto Switching: {1} {en} {bitmap(hex)}\n"); - } else if (var[0] == 1) { + "Page Auto Switching: swh {en} {bitmap(hex)}\n"); + } else if ((strcmp(input[1], "swh") == 0)) { #ifdef PHYDM_PHYSTAUS_AUTO_SWITCH PHYDM_SSCANF(input[3], DCMD_HEX, &var[2]); enable = (boolean)var[1]; diff --git a/hal/phydm/phydm_phystatus.h b/hal/phydm/phydm_phystatus.h index 578530f..c65b624 100644 --- a/hal/phydm/phydm_phystatus.h +++ b/hal/phydm/phydm_phystatus.h @@ -26,6 +26,9 @@ #ifndef __PHYDM_PHYSTATUS_H__ #define __PHYDM_PHYSTATUS_H__ +/* 2020.07.03 fix cck report bug due to 8723F coding error*/ +#define PHYSTS_VERSION "1.2" + /*@--------------------------Define ------------------------------------------*/ #define CCK_RSSI_INIT_COUNT 5 @@ -645,7 +648,79 @@ __PACK struct phy_sts_rpt_jgr3_type0 { u8 gain_d : 6; #endif }; +#if(RTL8723F_SUPPORT) +__PACK struct phy_sts_rpt_jgr3_type6 { + /* judy_add_8723F_0512 */ +/* @DW0 : Offset 0 */ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 pop_idx : 4; + u8 pkt_cnt : 2; + u8 channel_msb : 2; +#else + u8 channel_msb : 2; + u8 pkt_cnt : 2; + u8 pop_idx : 4; +#endif +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 agc_table_a : 4; + u8 rsvd_0 : 4; +#else + u8 rsvd_0 : 4; + u8 agc_table_a : 4; +#endif + u8 rsvd_1 : 8; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 trsw : 1; + u8 hw_antsw_occur_keep_cck : 1; + u8 gnt_bt_keep_cck : 1; + u8 rssi_msb : 3; + u8 rsvd_2 : 2; +#else + u8 rsvd_2 : 2; + u8 rssi_msb : 3; + u8 gnt_bt_keep_cck : 1; + u8 hw_antsw_occur_keep_cck : 1; + u8 trsw : 1; +#endif + +/* @DW1 : Offset 4 */ + u8 channel; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 antidx_a : 4; + u8 rsvd_2_1 : 4; +#else + u8 rsvd_2_1 : 4; + u8 antidx_a : 4; +#endif + u8 rsvd_2_2; + u8 mp_gain_idx_a; + +/* @DW2 : Offset 8 */ + u16 rsvd_3_1; + u8 rsvd_4_1; + u8 rssi; + +/* @DW3 : Offset 12 */ + u16 rsvd_4_2; + u8 rsvd_5_1; + u8 avg_cfo; +/* @DW4 : Offset 16 */ + u8 coarse_cfo; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 coarse_cfo_msb : 4; + u8 avg_cfo_msb : 4; +#else + u8 avg_cfo_msb : 4; + u8 coarse_cfo_msb : 4; +#endif + u8 evm_hdr; + u8 evm_pld; +/* @DW5 : Offset 20 */ + u32 rsvd_6_1; + u32 rsvd_7_1; +}; +#endif __PACK struct phy_sts_rpt_jgr3_type1 { /* @DW0 : Offset 0 */ #if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) @@ -1092,20 +1167,55 @@ __PACK struct phy_sts_rpt_jgr3_type5 { u8 inf_pos_0_d; u8 inf_pos_1_d; }; + +__PACK struct phy_sts_rpt_jgr3_ofdm_cmn { + #if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 page_num : 4; + u8 pkt_cnt : 2; + u8 channel_msb : 2; + #else + u8 channel_msb : 2; + u8 pkt_cnt : 2; + u8 page_num : 4; + #endif + u8 pwdb[4]; + #if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 l_rxsc : 4; + u8 ht_rxsc : 4; + #else + u8 ht_rxsc : 4; + u8 l_rxsc : 4; + #endif + u8 channel_lsb; + #if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 band : 2; + u8 rsvd_0 : 2; + u8 gnt_bt : 1; + u8 ldpc : 1; + u8 stbc : 1; + u8 beamformed : 1; + #else + u8 beamformed : 1; + u8 stbc : 1; + u8 ldpc : 1; + u8 gnt_bt : 1; + u8 rsvd_0 : 1; + u8 band : 2; + #endif +}; #endif /*@#ifdef PHYSTS_3RD_TYPE_SUPPORT*/ +#ifdef PHYDM_PHYSTAUS_AUTO_SWITCH +void phydm_physts_auto_switch_jgr3_set(void *dm_void, boolean enable, + u8 bitmap_en); +#endif + #if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1) boolean phydm_query_is_mu_api(struct dm_struct *phydm, u8 ppdu_idx, u8 *p_data_rate, u8 *p_gid); #endif -#ifdef PHYSTS_3RD_TYPE_SUPPORT -void phydm_rx_physts_3rd_type(void *dm_void, u8 *phy_sts, - struct phydm_perpkt_info_struct *pktinfo, - struct phydm_phyinfo_struct *phy_info); -#endif - void phydm_reset_phystatus_avg(struct dm_struct *dm); void phydm_reset_phystatus_statistic(struct dm_struct *dm); @@ -1127,10 +1237,10 @@ void phydm_normal_driver_rx_sniffer( s32 phydm_signal_scale_mapping(struct dm_struct *dm, s32 curr_sig); #endif -void odm_phy_status_query(struct dm_struct *dm, - struct phydm_phyinfo_struct *phy_info, - u8 *phy_status_inf, - struct phydm_perpkt_info_struct *pktinfo); +boolean odm_phy_status_query(struct dm_struct *dm, + struct phydm_phyinfo_struct *phy_info, + u8 *phy_sts, + struct phydm_perpkt_info_struct *pktinfo); void phydm_rx_phy_status_init(void *dm_void); diff --git a/hal/phydm/phydm_pmac_tx_setting.c b/hal/phydm/phydm_pmac_tx_setting.c index cf98560..296f39c 100644 --- a/hal/phydm/phydm_pmac_tx_setting.c +++ b/hal/phydm/phydm_pmac_tx_setting.c @@ -32,32 +32,34 @@ #ifdef PHYDM_PMAC_TX_SETTING_SUPPORT #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT - void phydm_start_cck_cont_tx_jgr3(void *dm_void, struct phydm_pmac_info *tx_info) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_pmac_tx *pmac_tx = &dm->dm_pmac_tx_table; - u8 rate = tx_info->tx_rate; /* @HW rate */ + u8 rate = tx_info->tx_rate; /* HW rate */ - /* @if CCK block on? */ + /* if CCK block on? */ if (!odm_get_bb_reg(dm, R_0x1c3c, BIT(1))) - odm_set_bb_reg(dm, R_0x1c3c, BIT(1), 1); - - /* @Turn Off All Test mode */ + odm_set_bb_reg(dm, R_0x1c3c, BIT(1), 0x1); + if (dm->support_ic_type & ODM_RTL8723F) { + odm_set_bb_reg(dm, R_0x2a08, BIT(21)|BIT(20), rate); + odm_set_bb_reg(dm, R_0x2a04, BIT(5), 0x0); /* turn on scrambler*/ + } else { + /* Turn Off All Test mode */ odm_set_bb_reg(dm, R_0x1ca4, 0x7, 0x0); odm_set_bb_reg(dm, R_0x1a00, 0x3000, rate); - odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x2); /* @transmit mode */ - odm_set_bb_reg(dm, R_0x1a00, 0x8, 0x1); /* @turn on scramble setting */ + odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x2); /* transmit mode */ + odm_set_bb_reg(dm, R_0x1a00, BIT(3), 0x1); /* turn on scrambler*/ - /* @Fix rate selection issue */ - odm_set_bb_reg(dm, R_0x1a70, 0x4000, 0x1); - /* @set RX weighting for path I & Q to 0 */ + /* Fix rate selection issue */ + odm_set_bb_reg(dm, R_0x1a70, BIT(14), 0x1); + /* set RX weighting for path I & Q to 0 */ odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x3); - /* @set loopback mode */ - odm_set_bb_reg(dm, R_0x1c3c, 0x10, 0x1); - + /* set loopback mode */ + odm_set_bb_reg(dm, R_0x1c3c, BIT(4), 0x1); + } pmac_tx->cck_cont_tx = true; pmac_tx->ofdm_cont_tx = false; } @@ -70,16 +72,21 @@ void phydm_stop_cck_cont_tx_jgr3(void *dm_void) pmac_tx->cck_cont_tx = false; pmac_tx->ofdm_cont_tx = false; - odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x0); /* @normal mode */ - odm_set_bb_reg(dm, R_0x1a00, 0x8, 0x1); /* @turn on scramble setting */ + if (dm->support_ic_type & ODM_RTL8723F) { + /* @Disable pmac tx_en*/ + odm_set_bb_reg(dm, R_0x2a04, BIT(5), 0x0); /* turn on scrambler*/ + } else { + odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x0); /* normal mode */ + odm_set_bb_reg(dm, R_0x1a00, BIT(3), 0x1); /* turn on scrambler*/ - /* @back to default */ - odm_set_bb_reg(dm, R_0x1a70, 0x4000, 0x0); - odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x0); - odm_set_bb_reg(dm, R_0x1c3c, 0x10, 0x0); - /* @BB Reset */ - odm_set_bb_reg(dm, R_0x1d0c, 0x10000, 0x0); - odm_set_bb_reg(dm, R_0x1d0c, 0x10000, 0x1); + /* back to default */ + odm_set_bb_reg(dm, R_0x1a70, BIT(14), 0x0); + odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x0); + odm_set_bb_reg(dm, R_0x1c3c, BIT(4), 0x0); + } + /* BB Reset */ + odm_set_bb_reg(dm, R_0x1d0c, BIT(16), 0x0); + odm_set_bb_reg(dm, R_0x1d0c, BIT(16), 0x1); } void phydm_start_ofdm_cont_tx_jgr3(void *dm_void) @@ -87,17 +94,18 @@ void phydm_start_ofdm_cont_tx_jgr3(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_pmac_tx *pmac_tx = &dm->dm_pmac_tx_table; - /* @1. if OFDM block on */ + /* 1. if OFDM block on */ if (!odm_get_bb_reg(dm, R_0x1c3c, BIT(0))) - odm_set_bb_reg(dm, R_0x1c3c, BIT(0), 1); + odm_set_bb_reg(dm, R_0x1c3c, BIT(0), 0x1); + if (!(dm->support_ic_type & ODM_RTL8723F)) { - /* @2. set CCK test mode off, set to CCK normal mode */ - odm_set_bb_reg(dm, R_0x1a00, 0x3, 0); + /* 2. set CCK test mode off, set to CCK normal mode */ + odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x0); - /* @3. turn on scramble setting */ - odm_set_bb_reg(dm, R_0x1a00, 0x8, 1); - - /* @4. Turn On Continue Tx and turn off the other test modes. */ + /* 3. turn on scramble setting */ + odm_set_bb_reg(dm, R_0x1a00, BIT(3), 0x1); + } + /* 4. Turn On Continue Tx and turn off the other test modes. */ odm_set_bb_reg(dm, R_0x1ca4, 0x7, 0x1); pmac_tx->cck_cont_tx = false; @@ -112,126 +120,15 @@ void phydm_stop_ofdm_cont_tx_jgr3(void *dm_void) pmac_tx->cck_cont_tx = false; pmac_tx->ofdm_cont_tx = false; - /* @Turn Off All Test mode */ + /* Turn Off All Test mode */ odm_set_bb_reg(dm, R_0x1ca4, 0x7, 0x0); - /* @Delay 10 ms */ + /* Delay 10 ms */ ODM_delay_ms(10); - /* @BB Reset */ - odm_set_bb_reg(dm, R_0x1d0c, 0x10000, 0x0); - odm_set_bb_reg(dm, R_0x1d0c, 0x10000, 0x1); -} - -void phydm_set_single_tone_jgr3(void *dm_void, boolean is_single_tone, - boolean en_pmac_tx, u8 path) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct phydm_pmac_tx *pmac_tx = &dm->dm_pmac_tx_table; - u8 start = RF_PATH_A, end = RF_PATH_A; - u8 i = 0; - - switch (path) { - case RF_PATH_A: - case RF_PATH_B: - case RF_PATH_C: - case RF_PATH_D: - start = path; - end = path; - break; - case RF_PATH_AB: - start = RF_PATH_A; - end = RF_PATH_B; - break; -#if (RTL8814B_SUPPORT || RTL8198F_SUPPORT) - case RF_PATH_AC: - start = RF_PATH_A; - end = RF_PATH_C; - break; - case RF_PATH_AD: - start = RF_PATH_A; - end = RF_PATH_D; - break; - case RF_PATH_BC: - start = RF_PATH_B; - end = RF_PATH_C; - break; - case RF_PATH_BD: - start = RF_PATH_B; - end = RF_PATH_D; - break; - case RF_PATH_CD: - start = RF_PATH_C; - end = RF_PATH_D; - break; - case RF_PATH_ABC: - start = RF_PATH_A; - end = RF_PATH_C; - break; - case RF_PATH_ABD: - start = RF_PATH_A; - end = RF_PATH_D; - break; - case RF_PATH_ACD: - start = RF_PATH_A; - end = RF_PATH_D; - break; - case RF_PATH_BCD: - start = RF_PATH_B; - end = RF_PATH_D; - break; - case RF_PATH_ABCD: - start = RF_PATH_A; - end = RF_PATH_D; - break; -#endif - } - - if (is_single_tone) { - pmac_tx->tx_scailing = odm_get_bb_reg(dm, R_0x81c, MASKDWORD); - - if (!en_pmac_tx) { - phydm_start_ofdm_cont_tx_jgr3(dm); - /*SendPSPoll(pAdapter);*/ - } - - odm_set_bb_reg(dm, R_0x1c68, BIT(24), 0x1); /* @Disable CCA */ - - for (i = start; i <= end; i++) { - /* @Tx mode: RF0x00[19:16]=4'b0010 */ - /* @odm_set_rf_reg(dm, i, RF_0x0, 0xF0000, 0x2); */ - /* @Lowest RF gain index: RF_0x0[4:0] = 0*/ - odm_set_rf_reg(dm, i, RF_0x0, 0x1F, 0x0); - /* @RF LO enabled */ - odm_set_rf_reg(dm, i, RF_0x58, BIT(1), 0x1); - } - #if (RTL8814B_SUPPORT == 1) - if (dm->support_ic_type & ODM_RTL8814B) { - /* @Tx mode: RF0x00[19:16]=4'b0010 */ - /* config_phydm_write_rf_syn_8814b(dm, RF_SYN0, RF_0x0, - * 0xF0000, 0x2); - */ - /* @Lowest RF gain index: RF_0x0[4:0] = 0*/ - config_phydm_write_rf_syn_8814b(dm, RF_SYN0, RF_0x0, - 0x1F, 0x0); - /* @RF LO enabled */ - config_phydm_write_rf_syn_8814b(dm, RF_SYN0, RF_0x58, - BIT(1), 0x1); - } - #endif - odm_set_bb_reg(dm, R_0x81c, 0x001FC000, 0); - } else { - for (i = start; i <= end; i++) { - /* @RF LO disabled */ - odm_set_rf_reg(dm, i, RF_0x58, BIT(1), 0x0); - } - odm_set_bb_reg(dm, R_0x1c68, BIT(24), 0x0); /* @Enable CCA */ - - if (!en_pmac_tx) - phydm_stop_ofdm_cont_tx_jgr3(dm); - - odm_set_bb_reg(dm, R_0x81c, MASKDWORD, pmac_tx->tx_scailing); - } + /* BB Reset */ + odm_set_bb_reg(dm, R_0x1d0c, BIT(16), 0x0); + odm_set_bb_reg(dm, R_0x1d0c, BIT(16), 0x1); } void phydm_stop_pmac_tx_jgr3(void *dm_void, struct phydm_pmac_info *tx_info) @@ -240,28 +137,39 @@ void phydm_stop_pmac_tx_jgr3(void *dm_void, struct phydm_pmac_info *tx_info) struct phydm_pmac_tx *pmac_tx = &dm->dm_pmac_tx_table; u32 tmp = 0; - if (tx_info->mode == CONT_TX) { - odm_set_bb_reg(dm, R_0x1e70, 0xf, 2); /* TX Stop */ + odm_set_bb_reg(dm, R_0x1e70, 0xf, 0x2); /* TX Stop */ + if (dm->support_ic_type & ODM_RTL8723F) { + if (tx_info->mode == CONT_TX) { + if (pmac_tx->is_cck_rate) { + /* TX Stop */ + odm_set_bb_reg(dm, R_0x2a00, BIT(0), 0x1); + /* Clear BB cont tx */ + odm_set_bb_reg(dm, R_0x2a00, BIT(28), 0x0); + /* Clear PMAC cont tx */ + odm_set_bb_reg(dm, R_0x2a08, BIT(17), 0x0); + /* Clear TX Stop */ + odm_set_bb_reg(dm, R_0x2a00, BIT(0), 0x0); + phydm_stop_cck_cont_tx_jgr3(dm); + } else + phydm_stop_ofdm_cont_tx_jgr3(dm); + } else { + if (pmac_tx->is_cck_rate) { + /* packet_count = 0x1 */ + odm_set_bb_reg(dm, R_0x2a04, 0x03ff0000, 0x1); + /* @Disable pmac tx_en*/ + odm_set_bb_reg(dm, R_0x2a08, BIT(31), 0x0); + /* @Enable pmac tx_en*/ + odm_set_bb_reg(dm, R_0x2a08, BIT(31), 0x1); + phydm_stop_cck_cont_tx_jgr3(dm); + } + } + }else { + if (tx_info->mode == CONT_TX) { if (pmac_tx->is_cck_rate) phydm_stop_cck_cont_tx_jgr3(dm); else phydm_stop_ofdm_cont_tx_jgr3(dm); - } else { - if (pmac_tx->is_cck_rate) { - tmp = odm_get_bb_reg(dm, R_0x2de4, MASKLWORD); - odm_set_bb_reg(dm, R_0x1e64, MASKLWORD, tmp + 50); } - odm_set_bb_reg(dm, R_0x1e70, 0xf, 2); /* TX Stop */ - } - - if (tx_info->mode == OFDM_SINGLE_TONE_TX) { - /* Stop HW TX -> Stop Continuous TX -> Stop RF Setting */ - if (pmac_tx->is_cck_rate) - phydm_stop_cck_cont_tx_jgr3(dm); - else - phydm_stop_ofdm_cont_tx_jgr3(dm); - - phydm_set_single_tone_jgr3(dm, false, true, pmac_tx->path); } } @@ -272,34 +180,39 @@ void phydm_set_mac_phy_txinfo_jgr3(void *dm_void, struct phydm_pmac_tx *pmac_tx = &dm->dm_pmac_tx_table; u32 tmp = 0; - odm_set_bb_reg(dm, R_0xa58, 0x003F8000, tx_info->tx_rate); + odm_set_bb_reg(dm, R_0xa58, 0x003f8000, tx_info->tx_rate); - /* @0x900[1] ndp_sound */ - odm_set_bb_reg(dm, R_0x900, 0x2, tx_info->ndp_sound); + /*0x900[1] ndp_sound */ + odm_set_bb_reg(dm, R_0x900, BIT(1), tx_info->ndp_sound); - /* @0x900[27:24] txsc [29:28] bw [31:30] m_stbc */ - if (dm->support_ic_type & (ODM_RTL8812F | ODM_RTL8197G)) { - tmp = (tx_info->tx_sc) | ((tx_info->bw) << 4) | - ((tx_info->m_stbc) << 6); - } else { - tmp = (tx_info->tx_sc) | ((tx_info->bw) << 4) | - ((tx_info->m_stbc - 1) << 6); - } - odm_set_bb_reg(dm, R_0x900, 0xFF000000, tmp); + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) + tx_info->m_stbc = tx_info->m_stbc - 1; + #endif + /*0x900[27:24] txsc [29:28] bw [31:30] m_stbc */ + tmp = (tx_info->tx_sc) | ((tx_info->bw) << 4) | + ((tx_info->m_stbc) << 6); + odm_set_bb_reg(dm, R_0x900, 0xff000000, tmp); - if (pmac_tx->is_ofdm_rate) { - odm_set_bb_reg(dm, R_0x900, 0x1, 0); - odm_set_bb_reg(dm, R_0x900, 0x4, 0); - } else if (pmac_tx->is_ht_rate) { - odm_set_bb_reg(dm, R_0x900, 0x1, 1); - odm_set_bb_reg(dm, R_0x900, 0x4, 0); + if (tx_info->tx_sc == 1) /*upper*/ + odm_set_bb_reg(dm, R_0x1ae0, 0x7000, 0x5); + else if (tx_info->tx_sc == 2) /*lower*/ + odm_set_bb_reg(dm, R_0x1ae0, 0x7000, 0x6); + else /* duplicate*/ + odm_set_bb_reg(dm, R_0x1ae0, 0x7000, 0x0); + + if (pmac_tx->is_ht_rate) { + odm_set_bb_reg(dm, R_0x900, BIT(0), 0x1); + odm_set_bb_reg(dm, R_0x900, BIT(2), 0x0); } else if (pmac_tx->is_vht_rate) { - odm_set_bb_reg(dm, R_0x900, 0x1, 0); - odm_set_bb_reg(dm, R_0x900, 0x4, 1); + odm_set_bb_reg(dm, R_0x900, BIT(0), 0x0); + odm_set_bb_reg(dm, R_0x900, BIT(2), 0x1); + } else { + odm_set_bb_reg(dm, R_0x900, BIT(0), 0x0); + odm_set_bb_reg(dm, R_0x900, BIT(2), 0x0); } - tmp = tx_info->packet_period; /* @for TX interval */ - odm_set_bb_reg(dm, R_0x9b8, 0xffff0000, tmp); + /* for TX interval */ + odm_set_bb_reg(dm, R_0x9b8, MASKHWORD, tx_info->packet_period); } void phydm_set_sig_jgr3(void *dm_void, struct phydm_pmac_info *tx_info) @@ -311,26 +224,14 @@ void phydm_set_sig_jgr3(void *dm_void, struct phydm_pmac_info *tx_info) if (pmac_tx->is_cck_rate) return; - /* @L-SIG */ odm_set_bb_reg(dm, R_0x1eb4, 0xfffff, tx_info->packet_count); + /* L-SIG */ tmp = BYTE_2_DWORD(0, tx_info->lsig[2], tx_info->lsig[1], tx_info->lsig[0]); odm_set_bb_reg(dm, R_0x908, 0xffffff, tmp); -#if 0 - /* @0x924[7:0] = Data init octet */ - tmp = tx_info->packet_pattern; - odm_set_bb_reg(dm, R_0x924, 0xff, tmp); - - if (tx_info->packet_pattern == RANDOM_BY_PN32) - tmp = 0x3; - else - tmp = 0x0; - - odm_set_bb_reg(dm, R_0x914, 0x60000000, tmp); -#endif if (pmac_tx->is_ht_rate) { - /* @HT SIG */ + /* HT SIG */ tmp = BYTE_2_DWORD(0, tx_info->ht_sig[2], tx_info->ht_sig[1], tx_info->ht_sig[0]); odm_set_bb_reg(dm, R_0x90c, 0xffffff, tmp); @@ -338,7 +239,7 @@ void phydm_set_sig_jgr3(void *dm_void, struct phydm_pmac_info *tx_info) tx_info->ht_sig[3]); odm_set_bb_reg(dm, R_0x910, 0xffffff, tmp); } else if (pmac_tx->is_vht_rate) { - /* @VHT SIG A/B/serv_field/delimiter */ + /* VHT SIG A/B/serv_field/delimiter */ tmp = BYTE_2_DWORD(0, tx_info->vht_sig_a[2], tx_info->vht_sig_a[1], tx_info->vht_sig_a[0]); @@ -350,10 +251,8 @@ void phydm_set_sig_jgr3(void *dm_void, struct phydm_pmac_info *tx_info) tmp = BYTE_2_DWORD(tx_info->vht_sig_b[3], tx_info->vht_sig_b[2], tx_info->vht_sig_b[1], tx_info->vht_sig_b[0]); - odm_set_bb_reg(dm, R_0x914, 0x1FFFFFFF, tmp); - - tmp = tx_info->vht_sig_b_crc; - odm_set_bb_reg(dm, R_0x938, 0xff00, tmp); + odm_set_bb_reg(dm, R_0x914, 0x1fffffff, tmp); + odm_set_bb_reg(dm, R_0x938, 0xff00, tx_info->vht_sig_b_crc); tmp = BYTE_2_DWORD(tx_info->vht_delimiter[3], tx_info->vht_delimiter[2], @@ -369,22 +268,39 @@ void phydm_set_cck_preamble_hdr_jgr3(void *dm_void, struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_pmac_tx *pmac_tx = &dm->dm_pmac_tx_table; u32 tmp = 0; + u8 rate = tx_info->tx_rate; /* HW rate */ if (!pmac_tx->is_cck_rate) return; - tmp = tx_info->packet_count | (tx_info->sfd << 16); - odm_set_bb_reg(dm, R_0x1e64, MASKDWORD, tmp); - tmp = tx_info->signal_field | (tx_info->service_field << 8) | - (tx_info->length << 16); - odm_set_bb_reg(dm, R_0x1e68, MASKDWORD, tmp); - tmp = BYTE_2_DWORD(0, 0, tx_info->crc16[1], tx_info->crc16[0]); - odm_set_bb_reg(dm, R_0x1e6c, 0xffff, tmp); + if (dm->support_ic_type & ODM_RTL8723F) { + #if (RTL8723F_SUPPORT) + odm_set_bb_reg(dm, R_0x2a04, 0x03ff0000, tx_info->packet_count); + odm_set_bb_reg(dm, R_0x2a08, BIT(22), tx_info->service_field_bit2); + odm_set_bb_reg(dm, R_0x2a08, BIT(21) | BIT(20), rate); + odm_set_bb_reg(dm, R_0x2a08, 0x1ffff, tx_info->packet_length); + /* turn on scrambler */ + odm_set_bb_reg(dm, R_0x2a04, BIT(5), 0x0); - if (tx_info->is_short_preamble) - odm_set_bb_reg(dm, R_0x1e6c, BIT(16), 0); - else - odm_set_bb_reg(dm, R_0x1e6c, BIT(16), 1); + if (tx_info->is_short_preamble) + odm_set_bb_reg(dm, R_0x2a08, BIT(19), 0x1); + else + odm_set_bb_reg(dm, R_0x2a08, BIT(19), 0x0); + #endif + } else { + tmp = tx_info->packet_count | (tx_info->sfd << 16); + odm_set_bb_reg(dm, R_0x1e64, MASKDWORD, tmp); + tmp = tx_info->signal_field | (tx_info->service_field << 8) | + (tx_info->length << 16); + odm_set_bb_reg(dm, R_0x1e68, MASKDWORD, tmp); + tmp = BYTE_2_DWORD(0, 0, tx_info->crc16[1], tx_info->crc16[0]); + odm_set_bb_reg(dm, R_0x1e6c, MASKLWORD, tmp); + + if (tx_info->is_short_preamble) + odm_set_bb_reg(dm, R_0x1e6c, BIT(16), 0x0); + else + odm_set_bb_reg(dm, R_0x1e6c, BIT(16), 0x1); + } } void phydm_set_mode_jgr3(void *dm_void, struct phydm_pmac_info *tx_info, @@ -400,17 +316,6 @@ void phydm_set_mode_jgr3(void *dm_void, struct phydm_pmac_info *tx_info, phydm_start_cck_cont_tx_jgr3(dm, tx_info); else phydm_start_ofdm_cont_tx_jgr3(dm); - } else if (mode == OFDM_SINGLE_TONE_TX) { - /* Continuous TX -> HW TX -> RF Setting */ - tx_info->packet_count = 1; - - if (pmac_tx->is_cck_rate) - phydm_start_cck_cont_tx_jgr3(dm, tx_info); - else - phydm_start_ofdm_cont_tx_jgr3(dm); - } else if (mode == PKTS_TX) { - if (pmac_tx->is_cck_rate && tx_info->packet_count == 0) - tx_info->packet_count = 0xffff; } } @@ -419,24 +324,37 @@ void phydm_set_pmac_txon_jgr3(void *dm_void, struct phydm_pmac_info *tx_info) struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_pmac_tx *pmac_tx = &dm->dm_pmac_tx_table; - odm_set_bb_reg(dm, R_0x1d08, BIT(0), 1); /* Turn on PMAC */ + odm_set_bb_reg(dm, R_0x1d08, BIT(0), 0x1); /*Turn on PMAC */ - /* mac scramble seed setting, only in 8198F */ - #if (RTL8198F_SUPPORT) - if (dm->support_ic_type & ODM_RTL8198F) - if (!odm_get_bb_reg(dm, R_0x1d10, BIT(16))) - odm_set_bb_reg(dm, R_0x1d10, BIT(16), 1); - #endif - - if (pmac_tx->is_cck_rate) { - odm_set_bb_reg(dm, R_0x1e70, 0xf, 8); /* TX CCK ON */ - odm_set_bb_reg(dm, R_0x1a84, BIT(31), 0); + if (dm->support_ic_type & ODM_RTL8723F) { + if (pmac_tx->is_cck_rate) { + if (tx_info->mode == CONT_TX) { + /* BB and PMAC cont tx */ + odm_set_bb_reg(dm, R_0x2a08, BIT(17), 0x1); + odm_set_bb_reg(dm, R_0x2a00, BIT(28), 0x1); + } + /* TX CCK ON */ + odm_set_bb_reg(dm, R_0x2a08, BIT(31), 0x0); + odm_set_bb_reg(dm, R_0x2a08, BIT(31), 0x1); + } else { + odm_set_bb_reg(dm, R_0x1e70, 0xf, 0x0); /*TX Ofdm OFF */ + odm_set_bb_reg(dm, R_0x1e70, 0xf, 0x4); /*TX Ofdm ON */ + } } else { - odm_set_bb_reg(dm, R_0x1e70, 0xf, 4); /* TX Ofdm ON */ + /*mac scramble seed setting, only in 8198F */ + #if (RTL8198F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8198F) + if (!odm_get_bb_reg(dm, R_0x1d10, BIT(16))) + odm_set_bb_reg(dm, R_0x1d10, BIT(16), 0x1); + #endif + + if (pmac_tx->is_cck_rate){ + odm_set_bb_reg(dm, R_0x1e70, 0xf, 0x8); /*TX CCK ON */ + odm_set_bb_reg(dm, R_0x1a84, BIT(31), 0x0); + } else { + odm_set_bb_reg(dm, R_0x1e70, 0xf, 0x4); /*TX Ofdm ON */ + } } - - if (tx_info->mode == OFDM_SINGLE_TONE_TX) - phydm_set_single_tone_jgr3(dm, true, true, pmac_tx->path); } void phydm_set_pmac_tx_jgr3(void *dm_void, struct phydm_pmac_info *tx_info, @@ -473,18 +391,20 @@ void phydm_set_tmac_tx_jgr3(void *dm_void) /* Turn on TMAC */ if (odm_get_bb_reg(dm, R_0x1d08, BIT(0))) - odm_set_bb_reg(dm, R_0x1d08, BIT(0), 0); + odm_set_bb_reg(dm, R_0x1d08, BIT(0), 0x0); /* mac scramble seed setting, only in 8198F */ - #if (RTL8198F_SUPPORT == 1) + #if (RTL8198F_SUPPORT) if (dm->support_ic_type & ODM_RTL8198F) if (odm_get_bb_reg(dm, R_0x1d10, BIT(16))) - odm_set_bb_reg(dm, R_0x1d10, BIT(16), 0); + odm_set_bb_reg(dm, R_0x1d10, BIT(16), 0x0); #endif /* Turn on TMAC CCK */ - if ((odm_get_bb_reg(dm, R_0x1a84, BIT(31))) == 0) - odm_set_bb_reg(dm, R_0x1a84, BIT(31), 1); + if (!(dm->support_ic_type & ODM_RTL8723F)) { + if (!odm_get_bb_reg(dm, R_0x1a84, BIT(31))) + odm_set_bb_reg(dm, R_0x1a84, BIT(31), 0x1); + } } #endif @@ -492,42 +412,40 @@ void phydm_start_cck_cont_tx(void *dm_void, struct phydm_pmac_info *tx_info) { struct dm_struct *dm = (struct dm_struct *)dm_void; + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT if (dm->support_ic_type & ODM_IC_JGR3_SERIES) phydm_start_cck_cont_tx_jgr3(dm, tx_info); + #endif } void phydm_stop_cck_cont_tx(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT if (dm->support_ic_type & ODM_IC_JGR3_SERIES) phydm_stop_cck_cont_tx_jgr3(dm); + #endif } void phydm_start_ofdm_cont_tx(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT if (dm->support_ic_type & ODM_IC_JGR3_SERIES) phydm_start_ofdm_cont_tx_jgr3(dm); + #endif } void phydm_stop_ofdm_cont_tx(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT if (dm->support_ic_type & ODM_IC_JGR3_SERIES) phydm_stop_ofdm_cont_tx_jgr3(dm); -} - -void phydm_set_single_tone(void *dm_void, boolean is_single_tone, - boolean en_pmac_tx, u8 path) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) - phydm_set_single_tone_jgr3(dm, is_single_tone, - en_pmac_tx, path); + #endif } void phydm_set_pmac_tx(void *dm_void, struct phydm_pmac_info *tx_info, @@ -535,16 +453,132 @@ void phydm_set_pmac_tx(void *dm_void, struct phydm_pmac_info *tx_info, { struct dm_struct *dm = (struct dm_struct *)dm_void; + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT if (dm->support_ic_type & ODM_IC_JGR3_SERIES) phydm_set_pmac_tx_jgr3(dm, tx_info, mpt_rf_path); + #endif } void phydm_set_tmac_tx(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT if (dm->support_ic_type & ODM_IC_JGR3_SERIES) phydm_set_tmac_tx_jgr3(dm); + #endif } -#endif +void phydm_pmac_tx_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_pmac_info tx_info; + char help[] = "-h"; + char dbg_buf[PHYDM_SNPRINT_SIZE] = {0}; + u32 var[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u8 i = 0; + u32 tx_cnt = 0x0; + u8 poll_cnt = 0x0; + + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var[0]); + + if (!(dm->support_ic_type & ODM_IC_JGR3_SERIES)) + return; + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "[pmac_tx] basic : {1} {rate_idx}(only 1M & 6M) {count}\n"); + } else { + for (i = 1; i < 7; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var[i]); + } + } + + tx_info.en_pmac_tx = true; + tx_info.mode = PKTS_TX; + tx_info.ndp_sound = false; + tx_info.bw = CHANNEL_WIDTH_20; + tx_info.tx_sc = 0x0; /*duplicate*/ + tx_info.m_stbc = 0x0; /*disable*/ + tx_info.packet_period = 2000; /*d'500 us*/ + tx_info.tx_rate = (u8)var[1]; + tx_info.packet_count = (u32)var[2]; + + if (tx_info.tx_rate == ODM_RATE1M) { + tx_info.signal_field = 0xa; /*rate = 1M*/ + tx_info.service_field = 0x0; + if (dm->support_ic_type & ODM_RTL8723F) { + tx_info.service_field_bit2= 0x1; + tx_info.packet_length = 1000; /*1000 bytes*/ + } + tx_info.length = 8000; /*d'8000 us=1000 bytes*/ + tx_info.crc16[0] = 0x60; + tx_info.crc16[1] = 0x8e; + /*long preamble*/ + tx_info.is_short_preamble = false; + tx_info.sfd = 0xf3a0; + } else if (tx_info.tx_rate == ODM_RATE6M) { + /*l-sig[3:0] = rate = 6M = 0xb*/ + /*l-sig[16:5] = length = 1000 bytes*/ + /*l-sig[17] = parity = 1*/ + tx_info.lsig[0] = 0xb; + tx_info.lsig[1] = 0x7d; + tx_info.lsig[2] = 0x2; + } + phydm_print_rate_2_buff(dm, tx_info.tx_rate, dbg_buf, + PHYDM_SNPRINT_SIZE); + PDM_SNPF(out_len, used, output + used, out_len - used, + "rate=%s, count=%d, pkt_interval=500(us), length=1000(bytes)\n", + dbg_buf, tx_info.packet_count); + + if (phydm_stop_ic_trx(dm, PHYDM_SET) == PHYDM_SET_FAIL) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "check trx idle failed, please try again.\n"); + return; + } + + phydm_reset_bb_hw_cnt(dm); + phydm_set_pmac_tx_jgr3(dm, &tx_info, RF_PATH_A); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "pmac_tx enabled, please wait for tx_cnt = %d\n", + tx_info.packet_count); + while (1) { + if (phydm_is_cck_rate(dm, tx_info.tx_rate)) + tx_cnt = odm_get_bb_reg(dm, R_0x2de4, + MASKLWORD); + else + tx_cnt = odm_get_bb_reg(dm, R_0x2de0, + MASKLWORD); + + if (tx_cnt >= tx_info.packet_count || poll_cnt >= 10) + break; + + ODM_delay_ms(100); + poll_cnt++; + } + + if (tx_cnt < tx_info.packet_count) + PDM_SNPF(out_len, used, output + used, out_len - used, + "polling time out(1s), tx_cnt = %d\n", tx_cnt); + else + PDM_SNPF(out_len, used, output + used, out_len - used, + "pmac_tx finished, poll_cnt = %d\n", poll_cnt); + + tx_info.en_pmac_tx = false; + phydm_set_pmac_tx(dm, &tx_info, RF_PATH_A); + phydm_set_tmac_tx(dm); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Stop pmac_tx and turn on true mac mode.\n"); + + phydm_stop_ic_trx(dm, PHYDM_REVERT); + } + *_used = used; + *_out_len = out_len; +} +#endif \ No newline at end of file diff --git a/hal/phydm/phydm_pmac_tx_setting.h b/hal/phydm/phydm_pmac_tx_setting.h index f84cd6e..532219b 100644 --- a/hal/phydm/phydm_pmac_tx_setting.h +++ b/hal/phydm/phydm_pmac_tx_setting.h @@ -26,38 +26,35 @@ #ifndef __PHYDM_PMAC_TX_SETTING_H__ #define __PHYDM_PMAC_TX_SETTING_H__ -#define PMAC_TX_SETTING_VERSION "1.3" +/*2020.03.16 Fix TxInfo content in B mode*/ +#define PMAC_TX_SETTING_VERSION "2.1" -/* @1 ============================================================ +/* 1 ============================================================ * 1 Definition * 1 ============================================================ */ -#define RANDOM_BY_PN32 0x12 -/* @1 ============================================================ + +/* 1 ============================================================ * 1 structure * 1 ============================================================ */ struct phydm_pmac_info { - u8 en_pmac_tx:1; /*@ disable pmac 1: enable pmac */ - u8 mode:3; /*@ 0: Packet TX 3:Continuous TX */ - /* @u8 Ntx:4; */ - u8 tx_rate; /* @should be HW rate*/ - /* @u8 TX_RATE_HEX; */ + u8 en_pmac_tx:1; /*0: disable pmac 1: enable pmac */ + u8 mode:3; /*0: Packet TX 3:Continuous TX */ + u8 tx_rate; /*should be HW rate*/ u8 tx_sc; - /* @u8 bSGI:1; */ u8 is_short_preamble:1; - /* @u8 bSTBC:1; */ - /* @u8 bLDPC:1; */ u8 ndp_sound:1; - u8 bw:3; /* @0:20 1:40 2:80Mhz */ - u8 m_stbc; /* @bSTBC + 1 */ + u8 bw:3; /* 0:20 1:40 2:80Mhz */ + u8 m_stbc; /* bSTBC + 1 for WIN/CE, bSTBC for others*/ u16 packet_period; u32 packet_count; - /* @u32 PacketLength; */ + u32 packet_length; u8 packet_pattern; u16 sfd; u8 signal_field; u8 service_field; + u8 service_field_bit2:1; u16 length; u8 crc16[2]; u8 lsig[3]; @@ -66,7 +63,6 @@ struct phydm_pmac_info { u8 vht_sig_b[4]; u8 vht_sig_b_crc; u8 vht_delimiter[4]; - /* @u8 mac_addr[6]; */ }; struct phydm_pmac_tx { @@ -77,10 +73,9 @@ struct phydm_pmac_tx { boolean cck_cont_tx; boolean ofdm_cont_tx; u8 path; - u32 tx_scailing; }; -/* @1 ============================================================ +/* 1 ============================================================ * 1 enumeration * 1 ============================================================ */ @@ -94,7 +89,7 @@ enum phydm_pmac_mode { CCK_CARRIER_SIPPRESSION_TX }; -/* @1 ============================================================ +/* 1 ============================================================ * 1 function prototype * 1 ============================================================ */ @@ -106,12 +101,11 @@ void phydm_start_ofdm_cont_tx(void *dm_void); void phydm_stop_ofdm_cont_tx(void *dm_void); -void phydm_set_single_tone(void *dm_void, boolean is_single_tone, - boolean en_pmac_tx, u8 path); - void phydm_set_pmac_tx(void *dm_void, struct phydm_pmac_info *tx_info, enum rf_path mpt_rf_path); void phydm_set_tmac_tx(void *dm_void); +void phydm_pmac_tx_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); #endif diff --git a/hal/phydm/phydm_pre_define.h b/hal/phydm/phydm_pre_define.h index 393f65c..fa1a0df 100644 --- a/hal/phydm/phydm_pre_define.h +++ b/hal/phydm/phydm_pre_define.h @@ -32,8 +32,8 @@ * 1 ============================================================ ***************************************************************/ -#define PHYDM_CODE_BASE "PHYDM_V039" -#define PHYDM_RELEASE_DATE "20190410.0" +#define PHYDM_CODE_BASE "PHYDM_V050" +#define PHYDM_RELEASE_DATE "20201019.0" /*PHYDM API status*/ #define PHYDM_SET_FAIL 0 @@ -59,6 +59,7 @@ #define MAX_PATH_NUM_8197G 2 #define MAX_PATH_NUM_8721D 1 #define MAX_PATH_NUM_8710C 1 +#define MAX_PATH_NUM_8723F 2 /*@AC-IC*/ #define MAX_PATH_NUM_8821A 1 @@ -311,6 +312,17 @@ enum phydm_ctrl_info_rate { ODM_RATEVHTSS4MCS9 = 0x53, }; +enum phydm_legacy_spec_rate { + PHYDM_SPEC_RATE_6M = 0xb, + PHYDM_SPEC_RATE_9M = 0xf, + PHYDM_SPEC_RATE_12M = 0xa, + PHYDM_SPEC_RATE_18M = 0xe, + PHYDM_SPEC_RATE_24M = 0x9, + PHYDM_SPEC_RATE_36M = 0xd, + PHYDM_SPEC_RATE_48M = 0x8, + PHYDM_SPEC_RATE_54M = 0xc +}; + #define NUM_RATE_AC_4SS (ODM_RATEVHTSS4MCS9 + 1) #define NUM_RATE_AC_3SS (ODM_RATEVHTSS3MCS9 + 1) #define NUM_RATE_AC_2SS (ODM_RATEVHTSS2MCS9 + 1) @@ -345,7 +357,7 @@ enum phydm_ctrl_info_rate { /*[N-1SS]*/ #elif (RTL8723B_SUPPORT || RTL8703B_SUPPORT || RTL8188E_SUPPORT || \ RTL8188F_SUPPORT || RTL8723D_SUPPORT || RTL8195A_SUPPORT ||\ - RTL8710B_SUPPORT || RTL8721D_SUPPORT || RTL8710C_SUPPORT) + RTL8710B_SUPPORT || RTL8721D_SUPPORT || RTL8710C_SUPPORT || RTL8723F_SUPPORT) #define PHY_NUM_RATE_IDX NUM_RATE_N_1SS #else #define PHY_NUM_RATE_IDX NUM_RATE_AC_4SS @@ -400,7 +412,8 @@ enum phydm_ic { ODM_RTL8812F = BIT(20), ODM_RTL8197G = BIT(21), ODM_RTL8721D = BIT(22), - ODM_RTL8710C = BIT(23) + ODM_RTL8710C = BIT(23), + ODM_RTL8723F = BIT(24) }; #define ODM_IC_N_1SS (ODM_RTL8188E | ODM_RTL8188F | ODM_RTL8723B |\ @@ -416,7 +429,7 @@ enum phydm_ic { #define ODM_IC_AC_3SS 0 #define ODM_IC_AC_4SS (ODM_RTL8814A) -#define ODM_IC_JGR3_1SS 0 +#define ODM_IC_JGR3_1SS (ODM_RTL8723F) #define ODM_IC_JGR3_2SS (ODM_RTL8822C | ODM_RTL8812F | ODM_RTL8197G) #define ODM_IC_JGR3_3SS 0 #define ODM_IC_JGR3_4SS (ODM_RTL8198F | ODM_RTL8814B) @@ -450,7 +463,7 @@ enum phydm_ic { ODM_RTL8821C | ODM_RTL8710B | ODM_RTL8195B |\ ODM_RTL8192F | ODM_RTL8721D | ODM_RTL8710C) #define PHYSTS_3RD_TYPE_IC (ODM_RTL8198F | ODM_RTL8814B | ODM_RTL8822C |\ - ODM_RTL8812F | ODM_RTL8197G) + ODM_RTL8812F | ODM_RTL8197G | ODM_RTL8723F) /*@[FW Type]*/ #define PHYDM_IC_8051_SERIES (ODM_RTL8881A | ODM_RTL8812 | ODM_RTL8821 |\ ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8703B |\ @@ -459,12 +472,12 @@ enum phydm_ic { #define PHYDM_IC_3081_SERIES (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8197F |\ ODM_RTL8821C | ODM_RTL8195B | ODM_RTL8198F |\ ODM_RTL8822C | ODM_RTL8812F | ODM_RTL8814B |\ - ODM_RTL8197G) + ODM_RTL8197G | ODM_RTL8723F) /*@[LA mode]*/ #define PHYDM_IC_SUPPORT_LA_MODE (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8197F |\ ODM_RTL8821C | ODM_RTL8195B | ODM_RTL8198F |\ ODM_RTL8192F | ODM_RTL8822C | ODM_RTL8812F |\ - ODM_RTL8195B | ODM_RTL8814B | ODM_RTL8197G) + ODM_RTL8195B | ODM_RTL8814B | ODM_RTL8197G | ODM_RTL8723F) /*@[BF]*/ #define ODM_IC_TXBF_SUPPORT (ODM_RTL8192E | ODM_RTL8812 | ODM_RTL8821 |\ ODM_RTL8814A | ODM_RTL8881A | ODM_RTL8822B |\ @@ -473,7 +486,7 @@ enum phydm_ic { ODM_RTL8814B | ODM_RTL8197G) #define PHYDM_IC_SUPPORT_MU_BFEE (ODM_RTL8822B | ODM_RTL8821C | ODM_RTL8814B |\ ODM_RTL8195B | ODM_RTL8198F | ODM_RTL8822C |\ - ODM_RTL8812F) + ODM_RTL8812F | ODM_RTL8723F) #define PHYDM_IC_SUPPORT_MU_BFER (ODM_RTL8822B | ODM_RTL8814B | ODM_RTL8198F |\ ODM_RTL8822C | ODM_RTL8812F) @@ -483,19 +496,43 @@ enum phydm_ic { #define CMN_API_SUPPORT_IC (ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8192F |\ ODM_RTL8821C | ODM_RTL8195B | ODM_RTL8822C |\ ODM_RTL8198F | ODM_RTL8812F | ODM_RTL8814B |\ - ODM_RTL8197G | ODM_RTL8721D | ODM_RTL8710C) + ODM_RTL8197G | ODM_RTL8721D | ODM_RTL8710C | ODM_RTL8723F) + +/* fw offload ability*/ +#define PHYDM_IC_SUPPORT_FW_PARAM_OFFLOAD (ODM_RTL8814A | ODM_RTL8822B |\ + ODM_RTL8821C | ODM_RTL8822C) + +/* halmac offload ability*/ +#define PHYDM_IC_SUPPORT_HALMAC_PARAM_OFFLOAD (ODM_RTL8822C | ODM_RTL8812F |\ + ODM_RTL8814B | ODM_RTL8723F) + +/*[CCX]*/ +#define PHYDM_IC_SUPPORT_FAHM (ODM_RTL8822B | ODM_RTL8821C | ODM_RTL8198F |\ + ODM_RTL8814B | ODM_RTL8822C | ODM_RTL8812F |\ + ODM_RTL8197G | ODM_RTL8723F) +#define PHYDM_IC_SUPPORT_IFS_CLM (ODM_RTL8822C | ODM_RTL8812F | ODM_RTL8197G | ODM_RTL8723F) + +/*[ARFR]*/ +/*for MAC HW control rate_id=0~12 and 2.4g vht mode(1ss/2ss) support*/ +#define PHYDM_IC_RATEID_IDX_TYPE2 (ODM_RTL8822B | ODM_RTL8822C | ODM_RTL8195B |\ + ODM_RTL8821C) /*@========[Compile time IC flag] ========================*/ /*@========[AC-3/AC/N Support] ===========================*/ #if (RTL8814B_SUPPORT || RTL8198F_SUPPORT || RTL8822C_SUPPORT ||\ - RTL8812F_SUPPORT || RTL8197G_SUPPORT) + RTL8812F_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_IC_JGR3_SERIES_SUPPORT #if (RTL8814B_SUPPORT || RTL8822C_SUPPORT || RTL8812F_SUPPORT) #define PHYDM_IC_JGR3_80M_SUPPORT #endif #endif +#if (RTL8822C_SUPPORT || RTL8812F_SUPPORT || RTL8814B_SUPPORT ||\ + RTL8723F_SUPPORT) + #define PHYDM_IC_HALMAC_PARAM_SUPPORT +#endif + #if (DM_ODM_SUPPORT_TYPE == ODM_AP) #ifdef RTK_AC_SUPPORT @@ -540,7 +577,7 @@ enum phydm_ic { RTL8703B_SUPPORT || RTL8723D_SUPPORT || RTL8881A_SUPPORT ||\ RTL8821A_SUPPORT || RTL8821C_SUPPORT || RTL8195A_SUPPORT ||\ RTL8710B_SUPPORT || RTL8195B_SUPPORT || RTL8721D_SUPPORT ||\ - RTL8710C_SUPPORT) + RTL8710C_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_COMPILE_IC_1SS #endif @@ -599,12 +636,16 @@ enum phydm_ic { #endif #if (RTL8198F_SUPPORT || RTL8814B_SUPPORT || RTL8822C_SUPPORT ||\ - RTL8812F_SUPPORT || RTL8197G_SUPPORT) + RTL8812F_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) #define PHYSTS_3RD_TYPE_SUPPORT #endif +#ifdef PHYSTS_3RD_TYPE_SUPPORT + #define PHYSTS_AUTO_SWITCH_IC (ODM_RTL8822C) +#endif + #if (RTL8198F_SUPPORT || RTL8814B_SUPPORT || RTL8822C_SUPPORT ||\ - RTL8812F_SUPPORT || RTL8197G_SUPPORT) + RTL8812F_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) #define BB_RAM_SUPPORT #endif @@ -618,14 +659,14 @@ enum phydm_ic { #define CONFIG_MU_JAGUAR_2 #endif -#if (RTL8814B_SUPPORT || RTL8822C_SUPPORT) +#if (RTL8814B_SUPPORT || RTL8822C_SUPPORT || RTL8812F_SUPPORT) #define CONFIG_MU_JAGUAR_3 #endif #if (defined(CONFIG_MU_JAGUAR_2) || defined(CONFIG_MU_JAGUAR_3)) #if (RTL8814B_SUPPORT) #define MU_EX_MACID 76 - #elif (RTL8822B_SUPPORT || RTL8822C_SUPPORT) + #elif (RTL8822B_SUPPORT || RTL8822C_SUPPORT || RTL8812F_SUPPORT) #define MU_EX_MACID 30 #endif #endif @@ -634,11 +675,21 @@ enum phydm_ic { #if (RTL8822B_SUPPORT || RTL8197F_SUPPORT || RTL8821C_SUPPORT ||\ RTL8192F_SUPPORT || RTL8195B_SUPPORT || RTL8822C_SUPPORT ||\ RTL8198F_SUPPORT || RTL8812F_SUPPORT || RTL8814B_SUPPORT ||\ - RTL8197G_SUPPORT || RTL8721D_SUPPORT || RTL8710C_SUPPORT) + RTL8197G_SUPPORT || RTL8721D_SUPPORT || RTL8710C_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_COMMON_API_SUPPORT #endif -#if (RTL8821C_SUPPORT || RTL8197F_SUPPORT || RTL8814B_SUPPORT) +#define PHYDM_COMMON_API_IC (ODM_IC_JGR3_SERIES | ODM_RTL8822B |\ + ODM_RTL8197F | ODM_RTL8821C | ODM_RTL8192F | ODM_RTL8195B |\ + ODM_RTL8721D | ODM_RTL8710C) + +#if (RTL8188E_SUPPORT || RTL8192E_SUPPORT || RTL8821A_SUPPORT ||\ + RTL8812A_SUPPORT || RTL8723B_SUPPORT || RTL8703B_SUPPORT ||\ + RTL8195A_SUPPORT || RTL8814A_SUPPORT) +#define PHYDM_COMMON_API_NOT_SUPPORT +#endif + +#if (RTL8821C_SUPPORT || RTL8197F_SUPPORT || RTL8197G_SUPPORT) #define CONFIG_RFE_BY_HW_INFO #endif @@ -674,6 +725,17 @@ enum phydm_ic { #define LOW_BW_RATE_NUM VHT_RATE_NUM +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +#define SECOND_CH_AT_LSB 2 /*@primary CH @ MSB, SD4: HAL_PRIME_CHNL_OFFSET_UPPER*/ +#define SECOND_CH_AT_USB 1 /*@primary CH @ LSB, SD4: HAL_PRIME_CHNL_OFFSET_LOWER*/ +#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#define SECOND_CH_AT_LSB 2 /*@primary CH @ MSB, SD7: HAL_PRIME_CHNL_OFFSET_UPPER*/ +#define SECOND_CH_AT_USB 1 /*@primary CH @ LSB, SD7: HAL_PRIME_CHNL_OFFSET_LOWER*/ +#else /*if (DM_ODM_SUPPORT_TYPE == ODM_AP)*/ +#define SECOND_CH_AT_LSB 1 /*@primary CH @ MSB, SD8: HT_2NDCH_OFFSET_BELOW*/ +#define SECOND_CH_AT_USB 2 /*@primary CH @ LSB, SD8: HT_2NDCH_OFFSET_ABOVE*/ +#endif + enum phydm_ic_ip { PHYDM_IC_N = 0, PHYDM_IC_AC = 1, @@ -767,6 +829,13 @@ enum odm_band_type { #endif }; +enum odm_rf_band { + ODM_RF_BAND_2G = 0, + ODM_RF_BAND_5G_LOW = 1, + ODM_RF_BAND_5G_MID = 2, + ODM_RF_BAND_5G_HIGH = 3, +}; + /* ODM_CMNINFO_SEC_CHNL_OFFSET */ enum phydm_sec_chnl_offset { PHYDM_DONT_CARE = 0, @@ -890,6 +959,26 @@ enum odm_power_voltage { ODM_POWER_18V = 0, ODM_POWER_33V = 1, }; + +/* ODM_CMNINFO_ANTDIV_GPIO */ +enum odm_antdiv_gpio { + ANTDIV_GPIO_PA2PA4 = 0, + ANTDIV_GPIO_PA5PA6 = 1, + ANTDIV_GPIO_PA12PA13 = 2, + ANTDIV_GPIO_PA14PA15 = 3, + ANTDIV_GPIO_PA16PA17 = 4, + ANTDIV_GPIO_PB1PB2 = 5, + ANTDIV_GPIO_PB26PB29 = 6, + ANTDIV_GPIO_PB1PB2PB26 = 7, // add by Jiao Qi for AmebaD SP3T only +}; + +/* ODM_CMNINFO_PEAK_DETECT_MODE */ +enum odm_peak_detect_mode { + ODM_PD_DIS = 0, + ODM_PD_ENG = 1, + ODM_PD_ENA = 2, + ODM_PD_ENALL = 3, +}; #endif #define PAUSE_FAIL 0 @@ -898,7 +987,9 @@ enum odm_power_voltage { enum odm_parameter_init { ODM_PRE_SETTING = 0, ODM_POST_SETTING = 1, - ODM_INIT_FW_SETTING + ODM_INIT_FW_SETTING = 2, + ODM_PRE_RF_SET = 3, + ODM_POST_RF_SET = 4 }; enum phydm_pause_type { diff --git a/hal/phydm/phydm_precomp.h b/hal/phydm/phydm_precomp.h index 545bee4..4fda5a3 100644 --- a/hal/phydm/phydm_precomp.h +++ b/hal/phydm/phydm_precomp.h @@ -169,7 +169,9 @@ #ifndef RTL8710C_SUPPORT #define RTL8710C_SUPPORT 0 #endif - +#ifndef RTL8723F_SUPPORT + #define RTL8723F_SUPPORT 0 +#endif #if (DM_ODM_SUPPORT_TYPE & ODM_CE) && \ (!defined(DM_ODM_CE_MAC80211) && !defined(DM_ODM_CE_MAC80211_V2)) @@ -183,6 +185,10 @@ void phy_set_tx_power_limit( u8 *channel, u8 *power_limit); +void phy_set_tx_power_limit_ex(struct dm_struct *dm, u8 regulation, u8 band, + u8 bandwidth, u8 rate_section, u8 rf_path, + u8 channel, s8 power_limit); + enum hal_status rtw_phydm_fw_iqk( struct dm_struct *dm, @@ -468,6 +474,7 @@ rtw_phydm_cfg_phy_para( #include "rtl8821c/halhwimg8821c_mac.h" #include "rtl8821c/halhwimg8821c_bb.h" #include "rtl8821c/phydm_regconfig8821c.h" + #include "rtl8821c/phydm_rtl8821c.h" #include "halrf/rtl8821c/halrf_8821c.h" #include "halrf/rtl8821c/halhwimg8821c_rf.h" #include "halrf/rtl8821c/version_rtl8821c_rf.h" @@ -593,6 +600,7 @@ rtw_phydm_cfg_phy_para( #include "halrf/rtl8814b/version_rtl8814b_rf.h" #include "rtl8814b/phydm_hal_api8814b.h" #include "rtl8814b/version_rtl8814b.h" + #include "rtl8814b/phydm_extraagc8814b.h" #if (DM_ODM_SUPPORT_TYPE == ODM_CE) #include /* @struct HAL_DATA_TYPE */ #include /* @RX_SMOOTH_FACTOR, reg definition and etc.*/ @@ -606,6 +614,7 @@ rtw_phydm_cfg_phy_para( #include "halrf/rtl8812f/version_rtl8812f_rf.h" #include "rtl8812f/phydm_hal_api8812f.h" #include "rtl8812f/version_rtl8812f.h" + #include "rtl8812f/phydm_rtl8812f.h" #endif #if (RTL8197G_SUPPORT) #include "rtl8197g/halhwimg8197g_bb.h" @@ -616,5 +625,28 @@ rtw_phydm_cfg_phy_para( #include "halrf/rtl8197g/version_rtl8197g_rf.h" #include "rtl8197g/phydm_hal_api8197g.h" #include "rtl8197g/version_rtl8197g.h" + #include "rtl8197g/phydm_rtl8197g.h" +#endif +#if (RTL8723F_SUPPORT) + #include "rtl8723f/halhwimg8723f_bb.h" + #include "rtl8723f/halhwimg8723f_mac.h" + #include "rtl8723f/phydm_regconfig8723f.h" + #include "halrf/rtl8723f/halrf_8723f.h" + #include "halrf/rtl8723f/halhwimg8723f_rf.h" + #include "halrf/rtl8723f/version_rtl8723f_rf.h" + #include "halrf/rtl8723f/halrf_iqk_8723f.h" + #include "halrf/rtl8723f/halrf_dpk_8723f.h" + #include "halrf/rtl8723f/halrf_txgapk_8723f.h" + #include "halrf/rtl8723f/halrf_tssi_8723f.h" + #include "halrf/rtl8723f/halrf_rfk_init_8723f.h" + #include "rtl8723f/phydm_hal_api8723f.h" + #include "rtl8723f/version_rtl8723f.h" + #include "rtl8723f/phydm_rtl8723f.h" + #if (DM_ODM_SUPPORT_TYPE == ODM_CE) + /* @struct HAL_DATA_TYPE */ + #include + /* @RX_SMOOTH_FACTOR, reg definition and etc.*/ + #include + #endif #endif #endif /* @__ODM_PRECOMP_H__ */ diff --git a/hal/phydm/phydm_primary_cca.h b/hal/phydm/phydm_primary_cca.h index 9a64750..1978586 100644 --- a/hal/phydm/phydm_primary_cca.h +++ b/hal/phydm/phydm_primary_cca.h @@ -33,17 +33,6 @@ /*@Definition */ /*@============================================================*/ -#if (DM_ODM_SUPPORT_TYPE == ODM_CE) -#define SECOND_CH_AT_LSB 2 /*@primary CH @ MSB, SD4: HAL_PRIME_CHNL_OFFSET_UPPER*/ -#define SECOND_CH_AT_USB 1 /*@primary CH @ LSB, SD4: HAL_PRIME_CHNL_OFFSET_LOWER*/ -#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) -#define SECOND_CH_AT_LSB 2 /*@primary CH @ MSB, SD7: HAL_PRIME_CHNL_OFFSET_UPPER*/ -#define SECOND_CH_AT_USB 1 /*@primary CH @ LSB, SD7: HAL_PRIME_CHNL_OFFSET_LOWER*/ -#else /*if (DM_ODM_SUPPORT_TYPE == ODM_AP)*/ -#define SECOND_CH_AT_LSB 1 /*@primary CH @ MSB, SD8: HT_2NDCH_OFFSET_BELOW*/ -#define SECOND_CH_AT_USB 2 /*@primary CH @ LSB, SD8: HT_2NDCH_OFFSET_ABOVE*/ -#endif - #define OFDMCCA_TH 500 #define bw_ind_bias 500 #define PRI_CCA_MONITOR_TIME 30 diff --git a/hal/phydm/phydm_psd.c b/hal/phydm/phydm_psd.c index d8d480c..8a19160 100644 --- a/hal/phydm/phydm_psd.c +++ b/hal/phydm/phydm_psd.c @@ -37,6 +37,17 @@ u32 phydm_get_psd_data(void *dm_void, u32 psd_tone_idx, u32 igi) u32 psd_report = 0; if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + #if(RTL8723F_SUPPORT) + if (dm->support_ic_type & (ODM_RTL8723F)) { + odm_set_bb_reg(dm, dm_psd_table->psd_reg, 0x3ff80000, psd_tone_idx & 0x7ff); + /*PSD trigger start*/ + odm_set_bb_reg(dm, dm_psd_table->psd_reg, BIT(16), 1); + ODM_delay_us(10 << (dm_psd_table->fft_smp_point >> 7)); + /*PSD trigger stop*/ + odm_set_bb_reg(dm, dm_psd_table->psd_reg, BIT(16), 0); + } + #endif + #if 0 odm_set_bb_reg(dm, R_0x1e8c, 0x3ff, psd_tone_idx & 0x3ff); odm_set_bb_reg(dm, R_0x1e88, BIT(27) | BIT(26), psd_tone_idx >> 10); @@ -45,6 +56,7 @@ u32 phydm_get_psd_data(void *dm_void, u32 psd_tone_idx, u32 igi) ODM_delay_us(10 << (dm_psd_table->fft_smp_point >> 7)); /*PSD trigger stop*/ odm_set_bb_reg(dm, dm_psd_table->psd_reg, BIT(18), 0); + #endif } else if (dm->support_ic_type & (ODM_RTL8721D | ODM_RTL8710C)) { odm_set_bb_reg(dm, dm_psd_table->psd_reg, 0xfff, psd_tone_idx); @@ -69,8 +81,16 @@ u32 phydm_get_psd_data(void *dm_void, u32 psd_tone_idx, u32 igi) 0xffffff); psd_report = psd_report >> 5; } else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + #if(RTL8723F_SUPPORT) + if (dm->support_ic_type & (ODM_RTL8723F)) { + psd_report = odm_get_bb_reg(dm, dm_psd_table->psd_report_reg, + 0x1ffffff); + } + #endif + #if 0 psd_report = odm_get_bb_reg(dm, dm_psd_table->psd_report_reg, 0xffffff); + #endif } else { psd_report = odm_get_bb_reg(dm, dm_psd_table->psd_report_reg, 0xffff); @@ -140,12 +160,21 @@ u8 phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point) is_5G = 1; if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8812F | ODM_RTL8197G)) { + #if 0 if (psd_fc_channel < 80) ag_rf_mode_reg = 0x1; else if (psd_fc_channel >= 80 && psd_fc_channel <= 140) ag_rf_mode_reg = 0x3; else if (psd_fc_channel > 140) ag_rf_mode_reg = 0x5; + #endif + } else if (dm->support_ic_type & ODM_RTL8723F) { + if (psd_fc_channel < 80) + ag_rf_mode_reg = 0x1; + else if (psd_fc_channel >= 80 && psd_fc_channel <= 144) + ag_rf_mode_reg = 0x5; + else if (psd_fc_channel > 144) + ag_rf_mode_reg = 0x9; } else if (dm->support_ic_type == ODM_RTL8721D) { if (psd_fc_channel >= 36 && psd_fc_channel <= 64) ag_rf_mode_reg = 0x1; @@ -170,6 +199,7 @@ u8 phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point) odm_set_rf_reg(dm, RF_PATH_B, RF_0x18, 0x300, is_5G); if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8812F | ODM_RTL8197G)) { + #if 0 /* @2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */ odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, 0x3000, dm_psd_table->psd_bw_rf_reg); @@ -180,6 +210,28 @@ u8 phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point) ag_rf_mode_reg); odm_set_rf_reg(dm, RF_PATH_B, RF_0x18, 0x70000, ag_rf_mode_reg); + #endif + } else if (dm->support_ic_type & ODM_RTL8723F) { + /* @2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */ + odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, 0x1c00, + dm_psd_table->psd_bw_rf_reg); + odm_set_rf_reg(dm, RF_PATH_B, RF_0x18, 0x1c00, + dm_psd_table->psd_bw_rf_reg); + /* Set RF ag fc mode*/ + odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, 0x30000, 1); + odm_set_rf_reg(dm, RF_PATH_B, RF_0x18, 0x30000, 1); + if(ag_rf_mode_reg == 1) { + odm_set_rf_reg(dm, RF_PATH_A, RF_0x19, 0xc0000, 0); + odm_set_rf_reg(dm, RF_PATH_B, RF_0x19, 0xc0000, 0); + } + else if(ag_rf_mode_reg == 5){ + odm_set_rf_reg(dm, RF_PATH_A, RF_0x19, 0xc0000, 1); + odm_set_rf_reg(dm, RF_PATH_B, RF_0x19, 0xc0000, 1); + } + else { + odm_set_rf_reg(dm, RF_PATH_A, RF_0x19, 0xc0000, 2); + odm_set_rf_reg(dm, RF_PATH_B, RF_0x19, 0xc0000, 2); + } } else { /* @2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */ if (dm->support_ic_type == ODM_RTL8721D) { @@ -187,7 +239,7 @@ u8 phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point) dm_psd_table->psd_bw_rf_reg); #if (RTL8710C_SUPPORT == 1) } else if (dm->support_ic_type == ODM_RTL8710C) { - config_phydm_write_rf_reg_8710c(dm, RF_PATH_A, + odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, 0x1c00, dm_psd_table->psd_bw_rf_reg); #endif @@ -203,10 +255,15 @@ u8 phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point) odm_set_rf_reg(dm, RF_PATH_B, RF_0x18, 0xf0000, ag_rf_mode_reg); } - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) + + if (dm->support_ic_type & ODM_IC_JGR3_SERIES){ + if (dm->support_ic_type & ODM_RTL8723F) { PHYDM_DBG(dm, ODM_COMP_API, "0x1d70=((0x%x))\n", odm_get_bb_reg(dm, R_0x1d70, MASKDWORD)); - else + PHYDM_DBG(dm, ODM_COMP_API, "RF0x19=((0x%x))\n", + odm_get_rf_reg(dm, RF_PATH_A, RF_0x19, RFREG_MASK)); + } + } else PHYDM_DBG(dm, ODM_COMP_API, "0xc50=((0x%x))\n", odm_get_bb_reg(dm, R_0xc50, MASKDWORD)); @@ -303,17 +360,35 @@ void phydm_psd_para_setting(void *dm_void, u8 sw_avg_time, u8 hw_avg_time, dm_psd_table->sw_avg_time = sw_avg_time; dm_psd_table->psd_fc_channel = channel; dm_psd_table->noise_k_en = noise_k_en; - - if (fft_smp_point == 128) - fft_smp_point_idx = 0; - else if (fft_smp_point == 256) - fft_smp_point_idx = 1; - else if (fft_smp_point == 512) - fft_smp_point_idx = 2; - else if (fft_smp_point == 1024) - fft_smp_point_idx = 3; - + if (dm->support_ic_type & ODM_RTL8723F) { + if (fft_smp_point == 128) + fft_smp_point_idx = 3; + else if (fft_smp_point == 256) + fft_smp_point_idx = 2; + else if (fft_smp_point == 512) + fft_smp_point_idx = 1; + else if (fft_smp_point == 1024) + fft_smp_point_idx = 0; + } + else { + if (fft_smp_point == 128) + fft_smp_point_idx = 0; + else if (fft_smp_point == 256) + fft_smp_point_idx = 1; + else if (fft_smp_point == 512) + fft_smp_point_idx = 2; + else if (fft_smp_point == 1024) + fft_smp_point_idx = 3; + } if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + #if (RTL8723F_SUPPORT) + odm_set_bb_reg(dm, R_0x1e8c, BIT(12) | BIT(11), hw_avg_time); + odm_set_bb_reg(dm, R_0x1e8c, BIT(14) | BIT(13), + fft_smp_point_idx); + odm_set_bb_reg(dm, R_0x1e8c, BIT(18) | BIT(17), ant_sel); + odm_set_bb_reg(dm, R_0x1e88, BIT(25) | BIT(24), psd_input); + #else + #if 0 odm_set_bb_reg(dm, R_0x1e8c, BIT(11) | BIT(10), i_q_setting); odm_set_bb_reg(dm, R_0x1e8c, BIT(13) | BIT(12), hw_avg_time); @@ -328,6 +403,8 @@ void phydm_psd_para_setting(void *dm_void, u8 sw_avg_time, u8 hw_avg_time, } odm_set_bb_reg(dm, R_0x1e8c, BIT(17) | BIT(16), ant_sel); odm_set_bb_reg(dm, R_0x1e8c, BIT(23) | BIT(22), psd_input); + #endif + #endif } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { odm_set_bb_reg(dm, R_0x910, BIT(11) | BIT(10), i_q_setting); odm_set_bb_reg(dm, R_0x910, BIT(13) | BIT(12), hw_avg_time); @@ -336,11 +413,12 @@ void phydm_psd_para_setting(void *dm_void, u8 sw_avg_time, u8 hw_avg_time, odm_set_bb_reg(dm, R_0x910, BIT(17) | BIT(16), ant_sel); odm_set_bb_reg(dm, R_0x910, BIT(23), psd_input); } else if (dm->support_ic_type & (ODM_RTL8721D | ODM_RTL8710C)) { - odm_set_bb_reg(dm, 0x808, BIT(19) | BIT(18), i_q_setting); - odm_set_bb_reg(dm, 0x808, BIT(21) | BIT(20), hw_avg_time); - odm_set_bb_reg(dm, 0x808, BIT(23) | BIT(22), fft_smp_point_idx); - odm_set_bb_reg(dm, 0x804, BIT(5) | BIT(4), ant_sel); - odm_set_bb_reg(dm, 0x80C, BIT(23), psd_input); + odm_set_bb_reg(dm, R_0x808, BIT(19) | BIT(18), i_q_setting); + odm_set_bb_reg(dm, R_0x808, BIT(21) | BIT(20), hw_avg_time); + odm_set_bb_reg(dm, R_0x808, BIT(23) | BIT(22), + fft_smp_point_idx); + odm_set_bb_reg(dm, R_0x804, BIT(5) | BIT(4), ant_sel); + odm_set_bb_reg(dm, R_0x80c, BIT(23), psd_input); #if 0 } else { /*ODM_IC_11N_SERIES*/ @@ -360,11 +438,25 @@ void phydm_psd_init(void *dm_void) dm_psd_table->psd_in_progress = false; if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + #if (RTL8723F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8723F) { + dm_psd_table->psd_reg = R_0x1e8c; + dm_psd_table->psd_report_reg = R_0x2d90; + + /*@2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */ + dm_psd_table->psd_bw_rf_reg = 2; + } + #else + #if 0 dm_psd_table->psd_reg = R_0x1e8c; dm_psd_table->psd_report_reg = R_0x2d90; /*@2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */ dm_psd_table->psd_bw_rf_reg = 1; + #endif + + return; + #endif } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { dm_psd_table->psd_reg = R_0x910; dm_psd_table->psd_report_reg = R_0xf44; @@ -401,10 +493,17 @@ void phydm_psd_debug(void *dm_void, char input[][16], u32 *_used, if ((strcmp(input[1], help) == 0)) { #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT + #if (RTL8723F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8723F) + PDM_SNPF(out_len, used, output + used, out_len - used, + "{0} {sw_avg} {hw_avg 0:3} {1:I,2:Q,3:IQ} {fft_point: 128*(1:4)}\n{path_sel 0~3} {0:ADC, 1:rxdata_fir_in, 2:rx_nbi_nf_stage2} {CH} {noise_k}\n\n"); + #endif + #if 0 if (dm->support_ic_type & ODM_IC_JGR3_SERIES) PDM_SNPF(out_len, used, output + used, out_len - used, "{0} {sw_avg} {hw_avg 0:3} {1:I,2:Q,3:IQ} {fft_point: 128*(1:4) 2048 4096}\n{path_sel 0~3} {0:ADC, 1:rxdata_fir_in, 2:rx_nbi_nf_stage2} {CH} {noise_k}\n\n"); else + #endif #endif PDM_SNPF(out_len, used, output + used, out_len - used, "{0} {sw_avg} {hw_avg 0:3} {1:I,2:Q,3:IQ} {fft_point: 128*(1:4)} {path_sel 0~3} {0:ADC, 1:RXIQC} {CH} {noise_k}\n"); @@ -418,9 +517,8 @@ void phydm_psd_debug(void *dm_void, char input[][16], u32 *_used, if (var1[0] == 0) { for (i = 1; i < 10; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, - &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); } PDM_SNPF(out_len, used, output + used, out_len - used, "sw_avg_time=((%d)), hw_avg_time=((%d)), IQ=((%d)), fft=((%d)), path=((%d)), input =((%d)) ch=((%d)), noise_k=((%d))\n", diff --git a/hal/phydm/phydm_psd.h b/hal/phydm/phydm_psd.h index 635a887..dec384a 100644 --- a/hal/phydm/phydm_psd.h +++ b/hal/phydm/phydm_psd.h @@ -27,7 +27,9 @@ #define __PHYDMPSD_H__ /*@#define PSD_VERSION "1.0"*/ /*@2016.09.22 Dino*/ -#define PSD_VERSION "1.1" /*@2016.10.07 Dino, Add Option for PSD Tone index Selection */ +/*@2016.10.07 Dino, Add Option for PSD Tone index Selection */ +/*@2019.04.26 Early return & "IF0" for JGR3 ICs */ +#define PSD_VERSION "1.2" #ifdef CONFIG_PSD_TOOL diff --git a/hal/phydm/phydm_rainfo.c b/hal/phydm/phydm_rainfo.c index 59d4804..d4a6215 100644 --- a/hal/phydm/phydm_rainfo.c +++ b/hal/phydm/phydm_rainfo.c @@ -51,6 +51,19 @@ boolean phydm_is_cck_rate(void *dm_void, u8 rate) return ((rate & 0x7f) <= ODM_RATE11M) ? true : false; } +u8 phydm_legacy_rate_2_spec_rate(void *dm_void, u8 rate) +{ + u8 rate_idx = 0x0; + u8 legacy_spec_rate_t[8] = {PHYDM_SPEC_RATE_6M, PHYDM_SPEC_RATE_9M, + PHYDM_SPEC_RATE_12M, PHYDM_SPEC_RATE_18M, + PHYDM_SPEC_RATE_24M, PHYDM_SPEC_RATE_36M, + PHYDM_SPEC_RATE_48M, PHYDM_SPEC_RATE_54M}; + + if ((rate >= ODM_RATE6M) && (rate <= ODM_RATE54M)) + rate_idx = rate - ODM_RATE6M; + return legacy_spec_rate_t[rate_idx]; +} + u8 phydm_rate_2_rate_digit(void *dm_void, u8 rate) { u8 legacy_table[12] = {1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54}; @@ -125,10 +138,8 @@ void phydm_h2C_debug(void *dm_void, char input[][16], u32 *_used, u8 phydm_h2c_id = 0; for (i = 0; i < 8; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &dm_value[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &dm_value[i]); + input_idx++; } if (input_idx == 0) @@ -158,7 +169,7 @@ void phydm_fw_fix_rate(void *dm_void, u8 en, u8 macid, u8 bw, u8 rate) if (dm->support_ic_type & PHYDM_IC_8051_SERIES) { reg_u32_tmp = (bw << 24) | (rate << 16) | (macid << 8) | en; - odm_set_bb_reg(dm, R_0x4a0, MASKDWORD, reg_u32_tmp); + odm_set_mac_reg(dm, R_0x4a0, MASKDWORD, reg_u32_tmp); } else { if (en == 1) @@ -166,9 +177,9 @@ void phydm_fw_fix_rate(void *dm_void, u8 en, u8 macid, u8 bw, u8 rate) else reg_u32_tmp = 0x40000000; if (dm->support_ic_type & ODM_RTL8814B) - odm_set_bb_reg(dm, R_0x448, MASKDWORD, reg_u32_tmp); + odm_set_mac_reg(dm, R_0x448, MASKDWORD, reg_u32_tmp); else - odm_set_bb_reg(dm, R_0x450, MASKDWORD, reg_u32_tmp); + odm_set_mac_reg(dm, R_0x450, MASKDWORD, reg_u32_tmp); } if (en == 1) { PHYDM_DBG(dm, ODM_COMP_API, @@ -190,11 +201,11 @@ void phydm_ra_debug(void *dm_void, char input[][16], u32 *_used, char *output, char help[] = "-h"; u32 var[5] = {0}; u8 macid = 0, bw = 0, rate = 0; + u8 tx_cls_en = 0, tx_cls_th = 0, tmp = 0; u8 i = 0; for (i = 0; i < 5; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var[i]); } if ((strcmp(input[1], help) == 0)) { @@ -206,7 +217,12 @@ void phydm_ra_debug(void *dm_void, char input[][16], u32 *_used, char *output, "{2} {en} {macid} {bw} {rate}: fw fix rate\n"); PDM_SNPF(out_len, used, output + used, out_len - used, "{3} {en}: Dynamic RRSR\n"); - + PDM_SNPF(out_len, used, output + used, out_len - used, + "{4} {0:pkt RA, 1:TBTT RA, 100:query RA mode}\n"); +#ifdef CONFIG_DYNAMIC_TXCOLLISION_TH + PDM_SNPF(out_len, used, output + used, out_len - used, + "{5} {0:dis, 1:en}{th; 255:auto, xx:dB}: Tx CLS\n"); +#endif } else if (var[0] == 1) { /*@Adjust PCR offset*/ if (var[1] == 100) { @@ -237,10 +253,46 @@ void phydm_ra_debug(void *dm_void, char input[][16], u32 *_used, char *output, var[1], macid, bw, rate); phydm_fw_fix_rate(dm, (u8)var[1], macid, bw, rate); - } else if (var[0] == 3) { /*@FW fix rate*/ + } else if (var[0] == 3) { /*@Dynamic RRSR*/ ra_tab->dynamic_rrsr_en = (boolean)var[1]; PDM_SNPF(out_len, used, output + used, out_len - used, "[Dynamic RRSR] enable=%d", ra_tab->dynamic_rrsr_en); + } else if (var[0] == 4) { /*@RA trigger mode*/ + if (var[1] == 0 || var[1] == 1) + ra_tab->ra_trigger_mode = (u8)var[1]; + PDM_SNPF(out_len, used, output + used, out_len - used, + "[RA trigger] mode=%d\n", ra_tab->ra_trigger_mode); +#ifdef CONFIG_DYNAMIC_TXCOLLISION_TH + } else if (var[0] == 5) { /*@Tx Collision Detection*/ + tx_cls_en = (u8)var[1]; + ra_tab->ra_tx_cls_th = (u8)var[2]; + tmp = (u8)var[2]; + tx_cls_th = (tmp < 50) ? 0 : (tmp > 81) ? 31 : tmp - 50; + if (tx_cls_en) { + odm_set_bb_reg(dm, R_0x8f8, BIT(16), 1); + if (ra_tab->ra_tx_cls_th != 255) { + phydm_tx_collsion_th_set(dm, tx_cls_th, + tx_cls_th); + } + + } else { + odm_set_bb_reg(dm, R_0x8f8, BIT(16), 0); + } + + if (tx_cls_en & ra_tab->ra_tx_cls_th != 255) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "[Tx Collision Detec] {en, th}={%d, %d}\n", + tx_cls_en, tx_cls_th + 50); + } else if (tx_cls_en & ra_tab->ra_tx_cls_th == 255) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "[Tx Collision Detec] {en, th}={%d, auto}\n", + tx_cls_en); + } else { + PDM_SNPF(out_len, used, output + used, out_len - used, + "[Tx Collision Detec] {en, th}={%d, xx}\n", + tx_cls_en); + } +#endif } else { PDM_SNPF(out_len, used, output + used, out_len - used, "[Set] Error\n"); @@ -249,9 +301,31 @@ void phydm_ra_debug(void *dm_void, char input[][16], u32 *_used, char *output, *_out_len = out_len; } +void phydm_ra_mask_report_h2c_trigger(void *dm_void, + struct ra_mask_rpt_trig *trig_rpt) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + + phydm_fw_trace_en_h2c(dm, true, 1, 2, trig_rpt->macid); + + trig_rpt->ra_mask_rpt_stamp = ra_tab->ra_mask_rpt_stamp; +} +void phydm_ra_mask_report_c2h_result(void *dm_void, struct ra_mask_rpt *rpt) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + u8 i = 0; + + rpt->ra_mask_rpt_stamp = ra_tab->ra_mask_rpt_stamp; + + odm_move_memory(dm, &rpt->ra_mask_buf[0], &ra_tab->ra_mask_buf[0], 8); +} + void odm_c2h_ra_para_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) { struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; u8 mode = cmd_buf[0]; /*Retry Penalty, NH, NL*/ u8 i; @@ -314,6 +388,9 @@ void odm_c2h_ra_para_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) for (i = 4; i <= 11; i++) PHYDM_DBG(dm, DBG_FW_TRACE, "RAMASK = 0x%x\n", cmd_buf[i]); + + odm_move_memory(dm, &ra_tab->ra_mask_buf[0], &cmd_buf[4], 8); + ra_tab->ra_mask_rpt_stamp++; } else { PHYDM_DBG(dm, DBG_FW_TRACE, "%5s %x%x %x%x %x%x %x%x\n", "RA Mask:", @@ -353,9 +430,8 @@ void phydm_ra_dynamic_retry_count(void *dm_void) if (!(dm->support_ability & ODM_BB_DYNAMIC_ARFR)) return; -#if 0 /*PHYDM_DBG(dm, DBG_RA, "dm->pre_b_noisy = %d\n", dm->pre_b_noisy );*/ -#endif + if (dm->pre_b_noisy != dm->noisy_decision) { if (dm->noisy_decision) { PHYDM_DBG(dm, DBG_DYN_ARFR, "Noisy Env. RA fallback\n"); @@ -399,10 +475,11 @@ void phydm_print_rate_2_buff(void *dm_void, u8 rate, char *buf, u16 buf_size) u8 rate_ss = phydm_rate_to_num_ss(dm, rate_idx); u8 rate_digit = phydm_rate_2_rate_digit(dm, rate_idx); - PHYDM_SNPRINTF(buf, buf_size, "( %s%s%s%s%d%s%s)", + PHYDM_SNPRINTF(buf, buf_size, "( %s%s%s%s%s%d%s%s)", (vht_en && (rate_ss == 1)) ? "VHT 1ss " : "", (vht_en && (rate_ss == 2)) ? "VHT 2ss " : "", (vht_en && (rate_ss == 3)) ? "VHT 3ss " : "", + (vht_en && (rate_ss == 4)) ? "VHT 4ss " : "", (rate_idx >= ODM_RATEMCS0) ? "MCS " : "", rate_digit, (b_sgi) ? "-S" : " ", @@ -421,6 +498,7 @@ void phydm_c2h_ra_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) u8 rate_idx = rate & 0x7f; /*remove bit7 SGI*/ u8 rate_order; u8 gid_index = 0; + u8 txcls_rate = 0; char dbg_buf[PHYDM_SNPRINT_SIZE] = {0}; #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) @@ -429,10 +507,16 @@ void phydm_c2h_ra_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) sta = dm->phydm_sta_info[macid]; #endif - if (cmd_len >= 7) { + if (cmd_len == 7) { ra_ratio = cmd_buf[5]; curr_bw = cmd_buf[6]; PHYDM_DBG(dm, DBG_RA, "[%d] PER=%d\n", macid, ra_ratio); + } else if (cmd_len == 8) { + ra_ratio = cmd_buf[5]; + curr_bw = cmd_buf[6]; + txcls_rate = cmd_buf[7]; + PHYDM_DBG(dm, DBG_RA, "[%d] PER=%d TxCLS=%d\n", macid, ra_ratio, + txcls_rate); } if (cmd_buf[3] != 0) { @@ -450,13 +534,15 @@ void phydm_c2h_ra_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) PHYDM_DBG(dm, DBG_RA, "Try rate\n"); } phydm_print_rate_2_buff(dm, rate, dbg_buf, PHYDM_SNPRINT_SIZE); - PHYDM_DBG(dm, DBG_RA, "Tx Rate=%s (%d)", dbg_buf, rate); + PHYDM_DBG(dm, DBG_RA, "Tx Rate=%s (%d)\n", dbg_buf, rate); #ifdef MU_EX_MACID if (macid >= 128 && macid < (128 + MU_EX_MACID)) { gid_index = macid - 128; ra_tab->mu1_rate[gid_index] = rate; } + if (macid >= ODM_ASSOCIATE_ENTRY_NUM) + return; #endif if (is_sta_active(sta)) { sta->ra_info.curr_tx_rate = rate; @@ -487,13 +573,6 @@ void phydm_c2h_ra_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) void odm_ra_post_action_on_assoc(void *dm_void) { -#if 0 - struct dm_struct *dm = (struct dm_struct *)dm_void; - - dm->h2c_rarpt_connect = 1; - phydm_rssi_monitor_check(dm); - dm->h2c_rarpt_connect = 0; -#endif } void phydm_modify_RA_PCR_threshold(void *dm_void, u8 ra_ofst_direc, @@ -857,10 +936,14 @@ u8 phydm_get_tx_stream_num(void *dm_void, enum rf_type type) u64 phydm_get_bb_mod_ra_mask(void *dm_void, u8 sta_idx) { struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_iot_center *iot_table = &dm->iot_table; struct cmn_sta_info *sta = dm->phydm_sta_info[sta_idx]; struct ra_sta_info *ra = NULL; enum channel_width bw = 0; enum wireless_set wrls_mode = 0; +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + struct rtl8192cd_priv *priv = dm->priv; +#endif u8 tx_stream_num = 1; u8 rssi_lv = 0; u64 ra_mask_bitmap = 0; @@ -972,8 +1055,21 @@ u64 phydm_get_bb_mod_ra_mask(void *dm_void, u8 sta_idx) PHYDM_DBG(dm, DBG_RA, "Mod by mode=0x%llx\n", ra_mask_bitmap); +#if ((DM_ODM_SUPPORT_TYPE == ODM_AP) && defined(PHYDM_IC_JGR3_SERIES_SUPPORT)) + if (priv->pshare->veriwave_sta_num > 0) { + PHYDM_DBG(dm, DBG_RA, "Mod by RSSI=0x%llx\n", ra_mask_bitmap); + return ra_mask_bitmap; + } +#endif /*@[Modify RA Mask by RSSI level]*/ if (wrls_mode != WIRELESS_CCK) { + if (iot_table->patch_id_40010700) { + ra_mask_bitmap &= (rssi_lv == 0 ? + 0xffffffffffffffff : + 0xfffffffffffffff0); + return ra_mask_bitmap; + } + if (rssi_lv == 0) ra_mask_bitmap &= 0xffffffffffffffff; else if (rssi_lv == 1) @@ -1127,14 +1223,21 @@ u8 phydm_get_rate_id(void *dm_void, u8 sta_idx) else if (tx_stream_num == 4) rate_id_idx = PHYDM_ARFR6_AC_4SS; } else { - if (tx_stream_num == 1) - rate_id_idx = PHYDM_ARFR2_AC_2G_1SS; - else if (tx_stream_num == 2) - rate_id_idx = PHYDM_ARFR3_AC_2G_2SS; - else if (tx_stream_num == 3) + if (tx_stream_num == 1) { + if (dm->support_ic_type & PHYDM_IC_RATEID_IDX_TYPE2) + rate_id_idx = PHYDM_TYPE2_ARFR5_AC_2G_1SS; + else + rate_id_idx = PHYDM_ARFR2_AC_2G_1SS; + } else if (tx_stream_num == 2) { + if (dm->support_ic_type & PHYDM_IC_RATEID_IDX_TYPE2) + rate_id_idx = PHYDM_TYPE2_ARFR3_AC_2G_2SS; + else + rate_id_idx = PHYDM_ARFR3_AC_2G_2SS; + } else if (tx_stream_num == 3) { rate_id_idx = PHYDM_ARFR4_AC_3SS; - else if (tx_stream_num == 4) + } else if (tx_stream_num == 4) { rate_id_idx = PHYDM_ARFR6_AC_4SS; + } } } else { PHYDM_DBG(dm, DBG_RA, "[Warrning] No rate_id is found\n"); @@ -1146,6 +1249,24 @@ u8 phydm_get_rate_id(void *dm_void, u8 sta_idx) return rate_id_idx; } +#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT +void phydm_ra_mode_selection(void *dm_void, u8 mode) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + u8 pre_mode = ra_tab->ra_trigger_mode; /* 0:pkt RA, 1:TBTT RA */ + + if (mode >= 2) { + PHYDM_DBG(dm, DBG_RA, "RA mode selection Fail\n"); + } else { + ra_tab->ra_trigger_mode = mode; + PHYDM_DBG(dm, DBG_RA, "RA mode, 0:pkt RA, 1:TBTT RA\n"); + PHYDM_DBG(dm, DBG_RA, "PreMode=%d,CurMode=%d\n", pre_mode, + mode); + } +} +#endif + void phydm_ra_h2c(void *dm_void, u8 sta_idx, u8 dis_ra, u8 dis_pt, u8 no_update_bw, u8 init_ra_lv, u64 ra_mask) { @@ -1153,6 +1274,7 @@ void phydm_ra_h2c(void *dm_void, u8 sta_idx, u8 dis_ra, u8 dis_pt, struct cmn_sta_info *sta = dm->phydm_sta_info[sta_idx]; struct ra_sta_info *ra = NULL; u8 h2c_val[H2C_MAX_LENGTH] = {0}; + u8 rate_id_idx = 0; if (is_sta_active(sta)) { ra = &sta->ra_info; @@ -1164,14 +1286,30 @@ void phydm_ra_h2c(void *dm_void, u8 sta_idx, u8 dis_ra, u8 dis_pt, PHYDM_DBG(dm, DBG_RA, "%s ======>\n", __func__); PHYDM_DBG(dm, DBG_RA, "MACID=%d\n", sta->mac_id); + - if (dm->is_disable_power_training) - dis_pt = true; - else if (!dm->is_disable_power_training) +#ifdef PHYDM_POWER_TRAINING_SUPPORT + if ((dm->support_ability & ODM_BB_PWR_TRAIN) && !dm->is_disable_power_training) dis_pt = false; + else + dis_pt = true; + +#else + dis_pt= true; +#endif + + rate_id_idx = ra->rate_id; + + /*for compatibility issues with FW RA [PHYDM-405]*/ + if (dm->support_ic_type & PHYDM_IC_RATEID_IDX_TYPE2) { + if (rate_id_idx == PHYDM_TYPE2_ARFR5_AC_2G_1SS) + rate_id_idx = PHYDM_ARFR2_AC_2G_1SS; + else if (rate_id_idx == PHYDM_TYPE2_ARFR3_AC_2G_2SS) + rate_id_idx = PHYDM_ARFR3_AC_2G_2SS; + } h2c_val[0] = sta->mac_id; - h2c_val[1] = (ra->rate_id & 0x1f) | ((init_ra_lv & 0x3) << 5) | + h2c_val[1] = (rate_id_idx & 0x1f) | ((init_ra_lv & 0x3) << 5) | (ra->is_support_sgi << 7); h2c_val[2] = (u8)((ra->ra_bw_mode) | (((sta->ldpc_en) ? 1 : 0) << 2) | ((no_update_bw & 0x1) << 3) | @@ -1878,6 +2016,21 @@ void phydm_rrsr_en(void *dm_void, boolean en_rrsr) ra_tab->dynamic_rrsr_en = en_rrsr; } +void phydm_arfr_table_init(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + if (dm->support_ic_type & PHYDM_IC_RATEID_IDX_TYPE2) { + /*ARFR table3(2.4g ac 2ss) for rate_id = 16*/ + odm_set_mac_reg(dm, R_0x494, MASKDWORD, 0xfe01f015); + odm_set_mac_reg(dm, R_0x498, MASKDWORD, 0x40000000); + + /*ARFR table5(2.4g ac 1ss) for rate_id = 18*/ + odm_set_mac_reg(dm, R_0x4a4, MASKDWORD, 0x3ff015); + odm_set_mac_reg(dm, R_0x4a8, MASKDWORD, 0x40000000); + } +} + void phydm_ra_info_init(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -1888,14 +2041,15 @@ void phydm_ra_info_init(void *dm_void) ra_tab->ra_th_ofst = 0; ra_tab->ra_ofst_direc = 0; ra_tab->rrsr_val_init = odm_get_mac_reg(dm, R_0x440, MASKDWORD); - ra_tab->dynamic_rrsr_en = true; - + ra_tab->dynamic_rrsr_en = false; + ra_tab->ra_trigger_mode = 1; // default TBTT RA + ra_tab->ra_tx_cls_th = 255; #if (RTL8822B_SUPPORT == 1) if (dm->support_ic_type == ODM_RTL8822B) { u32 ret_value; - ret_value = odm_get_bb_reg(dm, R_0x4c8, MASKBYTE2); - odm_set_bb_reg(dm, R_0x4cc, MASKBYTE3, (ret_value - 1)); + ret_value = odm_get_mac_reg(dm, R_0x4c8, MASKBYTE2); + odm_set_mac_reg(dm, R_0x4cc, MASKBYTE3, (ret_value - 1)); } #endif @@ -1907,6 +2061,8 @@ void phydm_ra_info_init(void *dm_void) phydm_ra_dynamic_rate_id_init(dm); #endif + phydm_arfr_table_init(dm); + phydm_rate_adaptive_mask_init(dm); } diff --git a/hal/phydm/phydm_rainfo.h b/hal/phydm/phydm_rainfo.h index ea503d6..5cef3ce 100644 --- a/hal/phydm/phydm_rainfo.h +++ b/hal/phydm/phydm_rainfo.h @@ -26,8 +26,8 @@ #ifndef __PHYDMRAINFO_H__ #define __PHYDMRAINFO_H__ -/* 2019.3.5 add dynamic RRSR en API*/ -#define RAINFO_VERSION "8.2" +/* 2020.08.05 Fix ARFR bug due to rate_id error for 2.4G VHT mode*/ +#define RAINFO_VERSION "8.8" #define FORCED_UPDATE_RAMASK_PERIOD 5 @@ -41,6 +41,9 @@ #define RA_RETRY_LIMIT_LOW 4 #define RA_RETRY_LIMIT_HIGH 32 +#define PHYDM_IS_LEGACY_RATE(rate) ((rate <= ODM_RATE54M) ? true : false) +#define PHYDM_IS_CCK_RATE(rate) ((rate <= ODM_RATE11M) ? true : false) + #if (DM_ODM_SUPPORT_TYPE == ODM_AP) #define FIRST_MACID 1 #else @@ -107,6 +110,16 @@ enum phydm_rateid_idx { PHYDM_ARFR6_AC_4SS = 16 }; +/*ARFR4(0x49c/0x4a0) can not be used because FW BT would use.*/ +enum phydm_rateid_idx_type_2 { + PHYDM_TYPE2_AC_2SS = 9, + PHYDM_TYPE2_AC_1SS = 10, + PHYDM_TYPE2_MIX_1SS = 11, + PHYDM_TYPE2_MIX_2SS = 12, + PHYDM_TYPE2_ARFR3_AC_2G_2SS = 16, /*0x494/0x498*/ + PHYDM_TYPE2_ARFR5_AC_2G_1SS = 18 /*0x4a4/0x4a8*/ +}; + enum phydm_qam_order { PHYDM_QAM_CCK = 0, PHYDM_QAM_BPSK = 1, @@ -189,6 +202,8 @@ struct ra_table { u32 rrsr_val_init; /*0x440*/ u32 rrsr_val_curr; /*0x440*/ boolean dynamic_rrsr_en; + u8 ra_trigger_mode; /*0: pkt RA, 1: TBTT RA*/ + u8 ra_tx_cls_th; /*255: auto, xx: in dB*/ #if 0 /*@CONFIG_RA_DYNAMIC_RTY_LIMIT*/ u8 per_rate_retrylimit_20M[PHY_NUM_RATE_IDX]; u8 per_rate_retrylimit_40M[PHY_NUM_RATE_IDX]; @@ -199,6 +214,18 @@ struct ra_table { u8 ldpc_thres; /* @if RSSI > ldpc_th => switch from LPDC to BCC */ void (*record_ra_info)(void *dm_void, u8 macid, struct cmn_sta_info *sta, u64 ra_mask); + u8 ra_mask_rpt_stamp; + u8 ra_mask_buf[8]; +}; + +struct ra_mask_rpt_trig { + u8 ra_mask_rpt_stamp; + u8 macid; +}; + +struct ra_mask_rpt { + u8 ra_mask_rpt_stamp; + u8 ra_mask_buf[8]; }; /* @1 ============================================================ @@ -213,6 +240,10 @@ boolean phydm_is_ht_rate(void *dm_void, u8 rate); boolean phydm_is_vht_rate(void *dm_void, u8 rate); +u8 phydm_legacy_rate_2_spec_rate(void *dm_void, u8 rate); + +u8 phydm_rate_2_rate_digit(void *dm_void, u8 rate); + u8 phydm_rate_type_2_num_ss(void *dm_void, enum PDM_RATE_TYPE type); u8 phydm_rate_to_num_ss(void *dm_void, u8 data_rate); @@ -223,6 +254,11 @@ void phydm_h2C_debug(void *dm_void, char input[][16], u32 *_used, void phydm_ra_debug(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len); +void phydm_ra_mask_report_h2c_trigger(void *dm_void, + struct ra_mask_rpt_trig *trig_rpt); + +void phydm_ra_mask_report_c2h_result(void *dm_void, struct ra_mask_rpt *rpt); + void odm_c2h_ra_para_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len); void phydm_print_rate(void *dm_void, u8 rate, u32 dbg_component); @@ -289,4 +325,9 @@ void phydm_ra_mask_watchdog(void *dm_void); void odm_refresh_basic_rate_mask( void *dm_void); #endif + +#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT +void phydm_ra_mode_selection(void *dm_void, u8 mode); +#endif + #endif /*@#ifndef __PHYDMRAINFO_H__*/ diff --git a/hal/phydm/phydm_regtable.h b/hal/phydm/phydm_regtable.h index 5fe5f44..155d2e4 100644 --- a/hal/phydm/phydm_regtable.h +++ b/hal/phydm/phydm_regtable.h @@ -1,5 +1,30 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2019 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * + *****************************************************************************/ + #define R_0x0 0x0 #define R_0x00 0x00 +#define R_0x08 0x08 #define R_0x0106 0x0106 #define R_0x0140 0x0140 #define R_0x0144 0x0144 @@ -7,11 +32,23 @@ #define R_0x040 0x040 #define R_0x10 0x10 #define R_0x100 0x100 +#define R_0x1000 0x1000 +#define R_0x1008 0x1008 #define R_0x1038 0x1038 #define R_0x103c 0x103c #define R_0x1040 0x1040 #define R_0x1048 0x1048 +#define R_0x1064 0x1064 #define R_0x1080 0x1080 +#define R_0x10d8 0x10d8 +#define R_0x10dc 0x10dc +#define R_0x1200 0x1200 +#define R_0x1204 0x1204 +#define R_0x1208 0x1208 +#define R_0x1210 0x1210 +#define R_0x1214 0x1214 +#define R_0x1218 0x1218 +#define R_0x121c 0x121c #define R_0x14 0x14 #define R_0x14c0 0x14c0 #define R_0x14c4 0x14c4 @@ -65,6 +102,7 @@ #define R_0x1918 0x1918 #define R_0x191c 0x191c #define R_0x1928 0x1928 +#define R_0x1938 0x1938 #define R_0x1940 0x1940 #define R_0x1944 0x1944 #define R_0x1950 0x1950 @@ -86,12 +124,20 @@ #define R_0x19f8 0x19f8 #define R_0x1a00 0x1a00 #define R_0x1a04 0x1a04 +#define R_0x1a08 0x1a08 +#define R_0x1a0c 0x1a0c #define R_0x1a10 0x1a10 #define R_0x1a14 0x1a14 +#define R_0x1a18 0x1a18 +#define R_0x1a1c 0x1a1c #define R_0x1a20 0x1a20 #define R_0x1a24 0x1a24 #define R_0x1a28 0x1a28 #define R_0x1a2c 0x1a2c +#define R_0x1a30 0x1a30 +#define R_0x1a34 0x1a34 +#define R_0x1a38 0x1a38 +#define R_0x1a48 0x1a48 #define R_0x1a5c 0x1a5c #define R_0x1a70 0x1a70 #define R_0x1a74 0x1a74 @@ -111,6 +157,7 @@ #define R_0x1acc 0x1acc #define R_0x1ad0 0x1ad0 #define R_0x1ad4 0x1ad4 +#define R_0x1ae0 0x1ae0 #define R_0x1ae8 0x1ae8 #define R_0x1aec 0x1aec #define R_0x1b00 0x1b00 @@ -167,6 +214,7 @@ #define R_0x1bb8 0x1bb8 #define R_0x1bbc 0x1bbc #define R_0x1bc0 0x1bc0 +#define R_0x1bc4 0x1bc4 #define R_0x1bc8 0x1bc8 #define R_0x1bca 0x1bca #define R_0x1bcb 0x1bcb @@ -177,6 +225,7 @@ #define R_0x1bd6 0x1bd6 #define R_0x1bd8 0x1bd8 #define R_0x1bdc 0x1bdc +#define R_0x1be3 0x1be3 #define R_0x1be4 0x1be4 #define R_0x1be8 0x1be8 #define R_0x1beb 0x1beb @@ -197,10 +246,12 @@ #define R_0x1c3c 0x1c3c #define R_0x1c64 0x1c64 #define R_0x1c68 0x1c68 +#define R_0x1c6c 0x1c6c #define R_0x1c74 0x1c74 #define R_0x1c78 0x1c78 #define R_0x1c7c 0x1c7c #define R_0x1c80 0x1c80 +#define R_0x1c8c 0x1c8c #define R_0x1c90 0x1c90 #define R_0x1c94 0x1c94 #define R_0x1c98 0x1c98 @@ -209,8 +260,10 @@ #define R_0x1ca4 0x1ca4 #define R_0x1cb0 0x1cb0 #define R_0x1cb8 0x1cb8 +#define R_0x1cbc 0x1cbc #define R_0x1cc0 0x1cc0 #define R_0x1cd0 0x1cd0 +#define R_0x1cd8 0x1cd8 #define R_0x1ce4 0x1ce4 #define R_0x1ce8 0x1ce8 #define R_0x1cec 0x1cec @@ -224,6 +277,7 @@ #define R_0x1d2c 0x1d2c #define R_0x1d30 0x1d30 #define R_0x1d3c 0x1d3c +#define R_0x1d40 0x1d40 #define R_0x1d44 0x1d44 #define R_0x1d48 0x1d48 #define R_0x1d58 0x1d58 @@ -247,6 +301,10 @@ #define R_0x1e40 0x1e40 #define R_0x1e44 0x1e44 #define R_0x1e48 0x1e48 +#define R_0x1e4c 0x1e4c +#define R_0x1e50 0x1e50 +#define R_0x1e54 0x1e54 +#define R_0x1e58 0x1e58 #define R_0x1e5c 0x1e5c #define R_0x1e60 0x1e60 #define R_0x1e64 0x1e64 @@ -254,29 +312,54 @@ #define R_0x1e6c 0x1e6c #define R_0x1e70 0x1e70 #define R_0x1e7c 0x1e7c +#define R_0x1e80 0x1e80 #define R_0x1e84 0x1e84 #define R_0x1e88 0x1e88 #define R_0x1e8c 0x1e8c #define R_0x1ea4 0x1ea4 #define R_0x1eb4 0x1eb4 +#define R_0x1eb8 0x1eb8 +#define R_0x1ed4 0x1ed4 +#define R_0x1ed8 0x1ed8 +#define R_0x1edc 0x1edc +#define R_0x1ee0 0x1ee0 +#define R_0x1ee4 0x1ee4 #define R_0x1ee8 0x1ee8 #define R_0x1eec 0x1eec #define R_0x1ef0 0x1ef0 #define R_0x1ef4 0x1ef4 +#define R_0x1ef8 0x1ef8 #define R_0x1efc 0x1efc +#define R_0x1f80 0x1f80 +#define R_0x1f98 0x1f98 #define R_0x24 0x24 #define R_0x28 0x28 +#define R_0x2a00 0x2a00 +#define R_0x2a04 0x2a04 +#define R_0x2a08 0x2a08 +#define R_0x2a24 0x2a24 +#define R_0x2a38 0x2a38 +#define R_0x2a3c 0x2a3c +#define R_0x2a44 0x2a44 +#define R_0x2aa0 0x2aa0 +#define R_0x2aa8 0x2aa8 +#define R_0x2aac 0x2aac +#define R_0x2ad0 0x2ad0 #define R_0x2c 0x2c #define R_0x28a4 0x28a4 +#define R_0x28bc 0x28bc #define R_0x2c04 0x2c04 #define R_0x2c08 0x2c08 #define R_0x2c0c 0x2c0c #define R_0x2c10 0x2c10 #define R_0x2c14 0x2c14 +#define R_0x2c18 0x2c18 +#define R_0x2c1c 0x2c1c #define R_0x2c20 0x2c20 #define R_0x2c2c 0x2c2c #define R_0x2c30 0x2c30 #define R_0x2c34 0x2c34 +#define R_0x2c54 0x2c54 #define R_0x2d00 0x2d00 #define R_0x2d04 0x2d04 #define R_0x2d08 0x2d08 @@ -288,6 +371,8 @@ #define R_0x2d44 0x2d44 #define R_0x2d48 0x2d48 #define R_0x2d4c 0x2d4c +#define R_0x2d6c 0x2d6c +#define R_0x2d84 0x2d84 #define R_0x2d88 0x2d88 #define R_0x2d90 0x2d90 #define R_0x2d9c 0x2d9c @@ -299,6 +384,15 @@ #define R_0x2de8 0x2de8 #define R_0x2e00 0x2e00 #define R_0x2e20 0x2e20 +#define R_0x2e60 0x2e60 +#define R_0x2e64 0x2e64 +#define R_0x2e68 0x2e68 +#define R_0x2e6c 0x2e6c +#define R_0x2e70 0x2e70 +#define R_0x2e74 0x2e74 +#define R_0x2e78 0x2e78 +#define R_0x2e7c 0x2e7c +#define R_0x2e80 0x2e80 #define R_0x300 0x300 #define R_0x38 0x38 #define R_0x3a00 0x3a00 @@ -386,12 +480,64 @@ #define R_0x42 0x42 #define R_0x430 0x430 #define R_0x434 0x434 +#define R_0x42b0 0x42b0 +#define R_0x42b4 0x42b4 +#define R_0x42f0 0x42f0 +#define R_0x4300 0x4300 +#define R_0x4304 0x4304 +#define R_0x4308 0x4308 +#define R_0x430c 0x430c +#define R_0x4310 0x4310 +#define R_0x4314 0x4314 +#define R_0x4318 0x4318 +#define R_0x431c 0x431c +#define R_0x4320 0x4320 +#define R_0x4324 0x4324 +#define R_0x4328 0x4328 +#define R_0x432c 0x432c +#define R_0x4330 0x4330 +#define R_0x4334 0x4334 +#define R_0x4338 0x4338 +#define R_0x433c 0x433c +#define R_0x4340 0x4340 +#define R_0x4344 0x4344 +#define R_0x4348 0x4348 +#define R_0x434c 0x434c +#define R_0x4350 0x4350 +#define R_0x4354 0x4354 +#define R_0x4358 0x4358 +#define R_0x435c 0x435c +#define R_0x4360 0x4360 +#define R_0x4364 0x4364 +#define R_0x4368 0x4368 +#define R_0x436c 0x436c +#define R_0x4370 0x4370 +#define R_0x4374 0x4374 +#define R_0x4378 0x4378 +#define R_0x437c 0x437c +#define R_0x4380 0x4380 +#define R_0x4384 0x4384 +#define R_0x4388 0x4388 +#define R_0x438c 0x438c +#define R_0x4390 0x4390 +#define R_0x4394 0x4394 +#define R_0x4398 0x4398 +#define R_0x439c 0x439c +#define R_0x43a0 0x43a0 +#define R_0x43a4 0x43a4 +#define R_0x43a8 0x43a8 +#define R_0x43ac 0x43ac +#define R_0x43b0 0x43b0 +#define R_0x43b4 0x43b4 +#define R_0x43b8 0x43b8 #define R_0x44 0x44 #define R_0x440 0x440 #define R_0x444 0x444 #define R_0x448 0x448 #define R_0x450 0x450 #define R_0x454 0x454 +#define R_0x494 0x494 +#define R_0x498 0x498 #define R_0x49c 0x49c #define R_0x4a0 0x4a0 #define R_0x4a4 0x4a4 @@ -465,6 +611,7 @@ #define R_0x6a0 0x6a0 #define R_0x6d8 0x6d8 #define R_0x6dc 0x6dc +#define R_0x6f8 0x6f8 #define R_0x70 0x70 #define R_0x74 0x74 #define R_0x700 0x700 @@ -567,6 +714,7 @@ #define R_0x974 0x974 #define R_0x978 0x978 #define R_0x97c 0x97c +#define R_0x980 0x980 #define R_0x988 0x988 #define R_0x98c 0x98c #define R_0x990 0x990 @@ -581,6 +729,7 @@ #define R_0x9b8 0x9b8 #define R_0x9cc 0x9cc #define R_0x9d0 0x9d0 +#define R_0x9d8 0x9d8 #define R_0x9e4 0x9e4 #define R_0x9e8 0x9e8 #define R_0x9f0 0x9f0 @@ -617,6 +766,7 @@ #define R_0xaac 0xaac #define R_0xab4 0xab4 #define R_0xabc 0xabc +#define R_0xac 0xac #define R_0xac8 0xac8 #define R_0xacc 0xacc #define R_0xad0 0xad0 @@ -695,7 +845,9 @@ #define R_0xc1c 0xc1c #define R_0xc20 0xc20 #define R_0xc24 0xc24 +#define R_0xc2c 0xc2c #define R_0xc30 0xc30 +#define R_0xc34 0xc34 #define R_0xc38 0xc38 #define R_0xc3c 0xc3c #define R_0xc40 0xc40 @@ -764,6 +916,7 @@ #define R_0xdb4 0xdb4 #define R_0xdb8 0xdb8 #define R_0xdbc 0xdbc +#define R_0xdc 0xdc #define R_0xdcc 0xdcc #define R_0xdd0 0xdd0 #define R_0xdd4 0xdd4 @@ -833,7 +986,10 @@ #define R_0xf0c 0xf0c #define R_0xf10 0xf10 #define R_0xf14 0xf14 +#define R_0xf18 0xf18 +#define R_0xf1c 0xf1c #define R_0xf20 0xf20 +#define R_0xf24 0xf24 #define R_0xf2c 0xf2c #define R_0xf30 0xf30 #define R_0xf34 0xf34 @@ -855,6 +1011,7 @@ #define R_0xf90 0xf90 #define R_0xf94 0xf94 #define R_0xf98 0xf98 +#define R_0xf9c 0xf9c #define R_0xfa0 0xfa0 #define R_0xfa4 0xfa4 #define R_0xfa8 0xfa8 @@ -872,6 +1029,7 @@ #define RF_0x0 0x0 #define RF_0x00 0x00 #define RF_0x08 0x08 +#define RF_0x09 0x09 #define RF_0x0c 0x0c #define RF_0x0d 0x0d #define RF_0x1 0x1 @@ -881,6 +1039,9 @@ #define RF_0x1bf0 0x1bf0 #define RF_0x2 0x2 #define RF_0x3 0x3 +#define RF_0x1e 0x1e +#define RF_0x1f 0x1f +#define RF_0x20 0x20 #define RF_0x30 0x30 #define RF_0x31 0x31 #define RF_0x32 0x32 @@ -891,6 +1052,7 @@ #define RF_0x4 0x4 #define RF_0x42 0x42 #define RF_0x43 0x43 +#define RF_0x5 0x5 #define RF_0x51 0x51 #define RF_0x52 0x52 #define RF_0x53 0x53 @@ -901,12 +1063,15 @@ #define RF_0x58 0x58 #define RF_0x5c 0x5c #define RF_0x5d 0x5d +#define RF_0x5e 0x5e +#define RF_0x60 0x60 #define RF_0x61 0x61 #define RF_0x63 0x63 #define RF_0x64 0x64 #define RF_0x65 0x65 #define RF_0x66 0x66 #define RF_0x67 0x67 +#define RF_0x6d 0x6d #define RF_0x6e 0x6e #define RF_0x6f 0x6f #define RF_0x75 0x75 @@ -922,11 +1087,17 @@ #define RF_0x85 0x85 #define RF_0x86 0x86 #define RF_0x87 0x87 +#define RF_0x88 0x88 #define RF_0x8a 0x8a +#define RF_0x8b 0x8b #define RF_0x8c 0x8c #define RF_0x8d 0x8d #define RF_0x8f 0x8f +#define RF_0x92 0x92 #define RF_0x93 0x93 +#define RF_0x9e 0x9e +#define RF_0x9f 0x9f +#define RF_0xa3 0xa3 #define RF_0xa9 0xa9 #define RF_0xae 0xae #define RF_0xb0 0xb0 @@ -936,6 +1107,7 @@ #define RF_0xbc 0xbc #define RF_0xbe 0xbe #define RF_0xc4 0xc4 +#define RF_0xc8 0xc8 #define RF_0xc9 0xc9 #define RF_0xca 0xca #define RF_0xcc 0xcc diff --git a/hal/phydm/phydm_rssi_monitor.c b/hal/phydm/phydm_rssi_monitor.c index f9c081b..1fde036 100644 --- a/hal/phydm/phydm_rssi_monitor.c +++ b/hal/phydm/phydm_rssi_monitor.c @@ -80,7 +80,7 @@ void phydm_rssi_monitor_h2c(void *dm_void, u8 macid) h2c[4] = (ra_t->ra_th_ofst & 0x7f) | ((ra_t->ra_ofst_direc & 0x1) << 7); h2c[5] = 0; - h2c[6] = 0; + h2c[6] = ((ra_t->ra_trigger_mode) << 2); PHYDM_DBG(dm, DBG_RSSI_MNTR, "PHYDM h2c[0x42]=0x%x %x %x %x %x %x %x\n", h2c[6], h2c[5], h2c[4], h2c[3], h2c[2], h2c[1], h2c[0]); @@ -95,6 +95,22 @@ void phydm_rssi_monitor_h2c(void *dm_void, u8 macid) } } +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) +void phydm_sta_rssi_init(void *dm_void, u8 macid, u8 init_rssi) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct cmn_sta_info *sta = NULL; + struct rssi_info *rssi_t = NULL; + + PHYDM_DBG(dm, DBG_RSSI_MNTR, "%s ======>\n", __func__); + + sta = dm->phydm_sta_info[macid]; + rssi_t = &sta->rssi_stat; + + rssi_t->rssi_acc = (init_rssi << RSSI_MA); + rssi_t->rssi = init_rssi; +} +#endif void phydm_calculate_rssi_min_max(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -133,6 +149,10 @@ void phydm_calculate_rssi_min_max(void *dm_void) } dm->pre_rssi_min = dm->rssi_min; +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + if (dm->number_linked_client == 0) + return; +#endif dm->rssi_max = (u8)rssi_max_tmp; dm->rssi_min = (u8)rssi_min_tmp; } diff --git a/hal/phydm/phydm_rssi_monitor.h b/hal/phydm/phydm_rssi_monitor.h index ac997e3..b0f446e 100644 --- a/hal/phydm/phydm_rssi_monitor.h +++ b/hal/phydm/phydm_rssi_monitor.h @@ -51,5 +51,8 @@ void phydm_rssi_monitor_check(void *dm_void); void phydm_rssi_monitor_init(void *dm_void); +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) +void phydm_sta_rssi_init(void *dm_void, u8 macid, u8 init_rssi); +#endif #endif diff --git a/hal/phydm/phydm_soml.c b/hal/phydm/phydm_soml.c index cba806e..cd4001a 100644 --- a/hal/phydm/phydm_soml.c +++ b/hal/phydm/phydm_soml.c @@ -312,6 +312,9 @@ void phydm_soml_debug(void *dm_void, char input[][16], u32 *_used, u32 dm_value[10] = {0}; u8 i = 0, input_idx = 0; + if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML)) + return; + for (i = 0; i < 5; i++) { if (input[i + 1]) { PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &dm_value[i]); @@ -560,10 +563,6 @@ void phydm_adsl_init_state(void *dm_void) } soml_tab->is_soml_method_enable = 1; - #if (DM_ODM_SUPPORT_TYPE == ODM_AP) - odm_set_mac_reg(dm, R_0x608, BIT(8), 1); - /*RCR accepts CRC32-Error packets*/ - #endif soml_tab->get_stats = false; soml_tab->soml_state_cnt++; next_on_off = (soml_tab->soml_on_off == SOML_ON) ? SOML_ON : SOML_OFF; @@ -679,10 +678,6 @@ void phydm_adsl_decision_state(void *dm_void) pr_debug("%s: mismatch IC type %x\n", __func__, dm->support_ic_type); soml_tab->get_stats = false; - #if (DM_ODM_SUPPORT_TYPE == ODM_AP) - odm_set_mac_reg(dm, R_0x608, BIT(8), 0); - /* NOT Accept CRC32 Error packets. */ - #endif PHYDM_DBG(dm, DBG_ADPTV_SOML, "[Decisoin state ]\n"); phydm_soml_statistics(dm, soml_tab->soml_on_off); if (*dm->channel <= 14) { @@ -1149,6 +1144,9 @@ void phydm_set_adsl_val(void *dm_void, u32 *val_buf, u8 val_len) { struct dm_struct *dm = (struct dm_struct *)dm_void; + if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML)) + return; + if (val_len != 1) { PHYDM_DBG(dm, ODM_COMP_API, "[Error][ADSL]Need val_len=1\n"); return; @@ -1163,6 +1161,9 @@ void phydm_soml_crc_acq(void *dm_void, u8 rate_id, boolean crc32, u32 length) struct adaptive_soml *soml_tab = &dm->dm_soml_table; u8 offset = 0; + if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML)) + return; + if (!soml_tab->get_stats) return; if (length < 1400) @@ -1207,6 +1208,8 @@ void phydm_soml_bytes_acq(void *dm_void, u8 rate_id, u32 length) struct adaptive_soml *soml_tab = &dm->dm_soml_table; u8 offset = 0; + if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML)) + return; if (rate_id >= ODM_RATEMCS0 && rate_id <= ODM_RATEMCS31) { offset = rate_id - ODM_RATEMCS0; @@ -1270,6 +1273,9 @@ void phydm_adaptive_soml_timers(void *dm_void, u8 state) struct dm_struct *dm = (struct dm_struct *)dm_void; struct adaptive_soml *soml_tab = &dm->dm_soml_table; + if (!(dm->support_ic_type & PHYDM_ADAPTIVE_SOML_IC)) + return; + #if defined(CONFIG_RTL_TRIBAND_SUPPORT) && defined(CONFIG_USB_HCI) struct rtl8192cd_priv *priv = dm->priv; @@ -1301,6 +1307,10 @@ void phydm_adaptive_soml_init(void *dm_void) return; } #endif + + if (!(dm->support_ic_type & PHYDM_ADAPTIVE_SOML_IC)) + return; + PHYDM_DBG(dm, DBG_ADPTV_SOML, "%s\n", __func__); soml_tab->soml_state_cnt = 0; diff --git a/hal/phydm/phydm_types.h b/hal/phydm/phydm_types.h index a13f506..4db8da5 100644 --- a/hal/phydm/phydm_types.h +++ b/hal/phydm/phydm_types.h @@ -158,6 +158,46 @@ enum rt_spinlock_type { #define phydm_timer_list _RT_TIMER + // for power limit table + enum odm_pw_lmt_regulation_type { + PW_LMT_REGU_FCC = 0, + PW_LMT_REGU_ETSI = 1, + PW_LMT_REGU_MKK = 2, + PW_LMT_REGU_WW13 = 3, + PW_LMT_REGU_IC = 4, + PW_LMT_REGU_KCC = 5, + PW_LMT_REGU_ACMA = 6, + PW_LMT_REGU_CHILE = 7, + PW_LMT_REGU_UKRAINE = 8, + PW_LMT_REGU_MEXICO = 9, + PW_LMT_REGU_CN = 10 + }; + + enum odm_pw_lmt_band_type { + PW_LMT_BAND_2_4G = 0, + PW_LMT_BAND_5G = 1 + }; + + enum odm_pw_lmt_bandwidth_type { + PW_LMT_BW_20M = 0, + PW_LMT_BW_40M = 1, + PW_LMT_BW_80M = 2, + PW_LMT_BW_160M = 3 + }; + + enum odm_pw_lmt_ratesection_type { + PW_LMT_RS_CCK = 0, + PW_LMT_RS_OFDM = 1, + PW_LMT_RS_HT = 2, + PW_LMT_RS_VHT = 3 + }; + + enum odm_pw_lmt_rfpath_type { + PW_LMT_PH_1T = 0, + PW_LMT_PH_2T = 1, + PW_LMT_PH_3T = 2, + PW_LMT_PH_4T = 3 + }; #elif (DM_ODM_SUPPORT_TYPE == ODM_AP) #include "../typedef.h" @@ -180,7 +220,9 @@ enum rt_spinlock_type { #define boolean bool #define phydm_timer_list timer_list - + #if defined(__ECOS) + #define s64 s8Byte + #endif #elif (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211) #include @@ -251,6 +293,47 @@ enum rt_spinlock_type { #define phydm_timer_list rtw_timer_list + // for power limit table + enum odm_pw_lmt_regulation_type { + PW_LMT_REGU_FCC = 0, + PW_LMT_REGU_ETSI = 1, + PW_LMT_REGU_MKK = 2, + PW_LMT_REGU_WW13 = 3, + PW_LMT_REGU_IC = 4, + PW_LMT_REGU_KCC = 5, + PW_LMT_REGU_ACMA = 6, + PW_LMT_REGU_CHILE = 7, + PW_LMT_REGU_UKRAINE = 8, + PW_LMT_REGU_MEXICO = 9, + PW_LMT_REGU_CN = 10 + }; + + enum odm_pw_lmt_band_type { + PW_LMT_BAND_2_4G = 0, + PW_LMT_BAND_5G = 1 + }; + + enum odm_pw_lmt_bandwidth_type { + PW_LMT_BW_20M = 0, + PW_LMT_BW_40M = 1, + PW_LMT_BW_80M = 2, + PW_LMT_BW_160M = 3 + }; + + enum odm_pw_lmt_ratesection_type { + PW_LMT_RS_CCK = 0, + PW_LMT_RS_OFDM = 1, + PW_LMT_RS_HT = 2, + PW_LMT_RS_VHT = 3 + }; + + enum odm_pw_lmt_rfpath_type { + PW_LMT_PH_1T = 0, + PW_LMT_PH_2T = 1, + PW_LMT_PH_3T = 2, + PW_LMT_PH_4T = 3 + }; + #elif (DM_ODM_SUPPORT_TYPE == ODM_IOT) #define boolean bool #define true _TRUE diff --git a/hal/phydm/rtl8822b/phydm_hal_api8822b.c b/hal/phydm/rtl8822b/phydm_hal_api8822b.c index 0423d6d..b360b7d 100644 --- a/hal/phydm/rtl8822b/phydm_hal_api8822b.c +++ b/hal/phydm/rtl8822b/phydm_hal_api8822b.c @@ -137,8 +137,8 @@ void phydm_8822b_type18_rfe(struct dm_struct *dm, u8 channel) if (dm->rx_ant_status == BB_PATH_AB || dm->tx_ant_status == BB_PATH_AB) { /* 2TX or 2RX */ - odm_set_bb_reg(dm, R_0xca0, MASKLWORD, 0xa501); - odm_set_bb_reg(dm, R_0xea0, MASKLWORD, 0xa501); + odm_set_bb_reg(dm, R_0xca0, MASKLWORD, 0x0501); + odm_set_bb_reg(dm, R_0xea0, MASKLWORD, 0x0501); } else if (dm->rx_ant_status == dm->tx_ant_status) { /* TXA+RXA or TXB+RXB */ odm_set_bb_reg(dm, R_0xca0, MASKLWORD, 0xa500); @@ -775,7 +775,7 @@ void phydm_ccapar_by_rfe_8822b(struct dm_struct *dm) } else { odm_move_memory(dm, cca_ifem, cca_ifem_ccut, 12 * 4); } - PHYDM_DBG(dm, ODM_PHY_CONFIG, "Update CCA para for Ccut\n"); + PHYDM_DBG(dm, ODM_PHY_CONFIG, "Update CCA para for C-cart\n"); if (central_ch_8822b <= 14) { if (dm->rx_ant_status == BB_PATH_A || @@ -835,7 +835,7 @@ void phydm_ccapar_by_rfe_8822b(struct dm_struct *dm) if ((*dm->band_width == CHANNEL_WIDTH_20) && (((*dm->channel >= 52) && (*dm->channel <= 64)) || ((*dm->channel >= 100) && (*dm->channel <= 144)))) - odm_set_bb_reg(dm, 0x838, 0xf0, 0x4); + odm_set_bb_reg(dm, 0x838, 0xf0, 0x5); PHYDM_DBG(dm, ODM_PHY_CONFIG, "(Pkt%d, Intf%d, RFE%d), col=%d\n", dm->package_type, dm->support_interface, dm->rfe_type, col); } @@ -1659,7 +1659,7 @@ config_phydm_switch_band_8822b(struct dm_struct *dm, /*@CCA mask = 13.6us*/ odm_set_bb_reg(dm, R_0x814, 0x0000FC00, 34); else - /*@default value*/ + /*@default value = 6us*/ odm_set_bb_reg(dm, R_0x814, 0x0000FC00, 15); #endif @@ -1829,7 +1829,9 @@ config_phydm_switch_channel_8822b(struct dm_struct *dm, } #if (DM_ODM_SUPPORT_TYPE & ODM_AP) /*@Make protection*/ - if (central_ch == 165 && bw_8822b != CHANNEL_WIDTH_20) + if (central_ch == 165 && + bw_8822b != CHANNEL_WIDTH_20 && + !(*dm->mp_mode)) config_phydm_switch_bandwidth_8822b(dm, 0, CHANNEL_WIDTH_20); #endif central_ch_8822b = central_ch; @@ -2017,6 +2019,7 @@ config_phydm_switch_bandwidth_8822b(struct dm_struct *dm, u8 primary_ch_idx, enum channel_width bw) { + struct phydm_api_stuc *api = &dm->api_table; u32 rf_reg18, val32; boolean rf_reg_status = true; u8 rfe_type = dm->rfe_type; @@ -2043,6 +2046,7 @@ config_phydm_switch_bandwidth_8822b(struct dm_struct *dm, bandwidth = CHANNEL_WIDTH_20; #endif bw_8822b = bandwidth; + api->pri_ch_idx = primary_ch_idx; rf_reg18 = config_phydm_read_rf_reg_8822b(dm, RF_PATH_A, 0x18, RFREG_MASK); rf_reg_status = rf_reg_status & @@ -2262,6 +2266,12 @@ config_phydm_switch_bandwidth_8822b(struct dm_struct *dm, phydm_spur_calibration_8822b(dm); } + /*fix bw setting*/ + #ifdef CONFIG_BW_INDICATION + if (!(*dm->mp_mode)) + phydm_bw_fixed_setting(dm); + #endif + /* Toggle RX path to avoid RX dead zone issue */ odm_set_bb_reg(dm, R_0x808, MASKBYTE0, 0x0); odm_set_bb_reg(dm, R_0x808, MASKBYTE0, (dm->rx_ant_status | diff --git a/hal/phydm/txbf/haltxbfjaguar.c b/hal/phydm/txbf/haltxbfjaguar.c index 18a47d4..6f18928 100644 --- a/hal/phydm/txbf/haltxbfjaguar.c +++ b/hal/phydm/txbf/haltxbfjaguar.c @@ -93,10 +93,9 @@ void hal_txbf_jaguar_download_ndpa( #endif PHYDM_DBG(dm, DBG_TXBF, "[%s] Start!\n", __func__); - if (idx == 0) - head_page = 0xFE; - else - head_page = 0xFE; + /* if (idx == 0) head_page = 0xFE; */ + /* else head_page = 0xFE;*/ + head_page = 0xFE; phydm_get_hal_def_var_handler_interface(dm, HAL_DEF_TX_PAGE_BOUNDARY, (u8 *)&tx_page_bndy); diff --git a/hal/phydm/txbf/phydm_hal_txbf_api.c b/hal/phydm/txbf/phydm_hal_txbf_api.c index 6c268c1..33a7e71 100644 --- a/hal/phydm/txbf/phydm_hal_txbf_api.c +++ b/hal/phydm/txbf/phydm_hal_txbf_api.c @@ -17,7 +17,7 @@ #include "phydm_precomp.h" #if (defined(CONFIG_BB_TXBF_API)) -#if (RTL8822B_SUPPORT == 1 || RTL8192F_SUPPORT == 1 ||\ +#if (RTL8822B_SUPPORT == 1 || RTL8192F_SUPPORT == 1 || RTL8812F_SUPPORT == 1 ||\ RTL8822C_SUPPORT == 1 || RTL8198F_SUPPORT == 1 || RTL8814B_SUPPORT == 1) /*@Add by YuChen for 8822B MU-MIMO API*/ @@ -121,7 +121,6 @@ u8 beamforming_get_htndp_tx_rate(void *dm_void, u8 bfer_str_num) if (dm->support_ic_type & ODM_RTL8814A) nr_index = tx_bf_nr(hal_txbf_8814a_get_ntx(dm), bfer_str_num); else -#endif nr_index = tx_bf_nr(1, bfer_str_num); switch (nr_index) { @@ -141,6 +140,9 @@ u8 beamforming_get_htndp_tx_rate(void *dm_void, u8 bfer_str_num) ndp_tx_rate = ODM_MGN_MCS8; break; } +#else + ndp_tx_rate = ODM_MGN_MCS8; +#endif return ndp_tx_rate; } @@ -155,7 +157,6 @@ u8 beamforming_get_vht_ndp_tx_rate(void *dm_void, u8 bfer_str_num) if (dm->support_ic_type & ODM_RTL8814A) nr_index = tx_bf_nr(hal_txbf_8814a_get_ntx(dm), bfer_str_num); else -#endif nr_index = tx_bf_nr(1, bfer_str_num); switch (nr_index) { @@ -175,6 +176,9 @@ u8 beamforming_get_vht_ndp_tx_rate(void *dm_void, u8 bfer_str_num) ndp_tx_rate = ODM_MGN_VHT2SS_MCS0; break; } +#else + ndp_tx_rate = ODM_MGN_VHT2SS_MCS0; +#endif return ndp_tx_rate; } @@ -338,16 +342,16 @@ void phydm_txbf_rfmode(void *dm_void, u8 su_bfee_cnt, u8 mu_bfee_cnt) /* logic mapping */ /* TX BF logic map and TX path en for Nsts = 1~4 */ - odm_set_bb_reg(dm, R_0x820, 0xffff0000, 0xffff); + //odm_set_bb_reg(dm, R_0x820, 0xffff0000, 0xffff); /*verification path-AC*/ - odm_set_bb_reg(dm, R_0x1e30, 0xffffffff, 0xe4e4e4e4); + //odm_set_bb_reg(dm, R_0x1e30, 0xffffffff, 0xe4e4e4e4); } else { /*@Disable BB TxBF ant mapping register*/ odm_set_bb_reg(dm, R_0x1e24, BIT(28) | BIT29, 0x0); odm_set_bb_reg(dm, R_0x1e24, BIT(31), 0); /*@1SS~4ss A, AB, ABC, ABCD*/ - odm_set_bb_reg(dm, R_0x820, 0xffff, 0xf731); - odm_set_bb_reg(dm, R_0x1e2c, 0xffffffff, 0xe4240400); + //odm_set_bb_reg(dm, R_0x820, 0xffff, 0xf731); + //odm_set_bb_reg(dm, R_0x1e2c, 0xffffffff, 0xe4240400); } } #endif @@ -472,12 +476,27 @@ void phydm_mu_rsoml_init(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_bf_rate_info_jgr3 *rateinfo = &dm->bf_rate_info_jgr3; + u32 val = 0; - PHYDM_DBG(dm, DBG_TXBF, "[MU RSOML] %s - cnt init\n", __func__); + PHYDM_DBG(dm, DBG_TXBF, "[MU RSOML] %s\n", __func__); + + /*OFDM Tx*/ + val = odm_get_bb_reg(dm, R_0x820, MASKDWORD); + rateinfo->tx_path_en_ofdm_2sts = (u8)((val & 0xf0) >> 4); + rateinfo->tx_path_en_ofdm_1sts = (u8)(val & 0xf); + /*OFDM Rx*/ + rateinfo->rx_path_en_ofdm = (u8)odm_get_bb_reg(dm, R_0x824, 0xf0000); rateinfo->enable = 1; rateinfo->mu_ratio_th = 30; rateinfo->pre_mu_ratio = 0; + rateinfo->mu_set_trxpath = 0; + rateinfo->mu_been_iot = 0; + + PHYDM_DBG(dm, DBG_TXBF, "[MU RSOML] %s tx1ss=%d, tx2ss=%d, rx=%d\n", + __func__, rateinfo->tx_path_en_ofdm_1sts, + rateinfo->tx_path_en_ofdm_2sts, rateinfo->rx_path_en_ofdm); + phydm_mu_rsoml_reset(dm); } @@ -485,12 +504,19 @@ void phydm_mu_rsoml_decision(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_bf_rate_info_jgr3 *rateinfo = &dm->bf_rate_info_jgr3; + struct phydm_iot_center *iot_table = &dm->iot_table; u8 offset = 0; u32 mu_ratio = 0; u32 su_pkt = 0; u32 mu_pkt = 0; u32 total_pkt = 0; + if (rateinfo->tx_path_en_ofdm_2sts != 3 || + rateinfo->rx_path_en_ofdm != 3) { + PHYDM_DBG(dm, DBG_TXBF, "[MU RSOML] Init Not 2T2R 22CE\n"); + return; + } + PHYDM_DBG(dm, DBG_TXBF, "[MU RSOML] RSOML Decision eanble: %d\n", rateinfo->enable); @@ -512,28 +538,46 @@ void phydm_mu_rsoml_decision(void *dm_void) mu_ratio, total_pkt); if (mu_ratio > rateinfo->mu_ratio_th && - rateinfo->pre_mu_ratio > rateinfo->mu_ratio_th) + rateinfo->pre_mu_ratio > rateinfo->mu_ratio_th) { PHYDM_DBG(dm, DBG_TXBF, "[MU RSOML] RSOML status remain\n"); - else if (mu_ratio <= rateinfo->mu_ratio_th && - rateinfo->pre_mu_ratio <= rateinfo->mu_ratio_th) + } else if (mu_ratio <= rateinfo->mu_ratio_th && + rateinfo->pre_mu_ratio <= rateinfo->mu_ratio_th) { PHYDM_DBG(dm, DBG_TXBF, "[MU RSOML] RSOML status remain\n"); - else if (mu_ratio > rateinfo->mu_ratio_th) + } else if (mu_ratio > rateinfo->mu_ratio_th) { odm_set_bb_reg(dm, R_0xc00, BIT(26), 0); - else + PHYDM_DBG(dm, DBG_TXBF, "[MU RSOML] RSOML OFF\n"); + } else { odm_set_bb_reg(dm, R_0xc00, BIT(26), 1); + PHYDM_DBG(dm, DBG_TXBF, "[MU RSOML] RSOML ON\n"); + } + + PHYDM_DBG(dm, DBG_TXBF, "[MU IOT] set_trxpath=%d, patch_10120200=%d\n", + rateinfo->mu_set_trxpath, iot_table->patch_id_10120200); + if (rateinfo->mu_set_trxpath && iot_table->patch_id_10120200) { + if (mu_ratio > rateinfo->mu_ratio_th) { + phydm_api_trx_mode(dm, BB_PATH_AB, BB_PATH_A, + BB_PATH_AUTO); + PHYDM_DBG(dm, DBG_TXBF, "[MU IOT] 22C IOT 2T1R\n"); + rateinfo->mu_been_iot = 1; + } else { + phydm_api_trx_mode(dm, BB_PATH_AB, BB_PATH_AB, + BB_PATH_AUTO); + PHYDM_DBG(dm, DBG_TXBF, "[MU IOT] 22C IOT 2T2R\n"); + rateinfo->mu_been_iot = 0; + } + } else if (rateinfo->mu_been_iot == 1) { + if (odm_get_bb_reg(dm, R_0x824, 0xf0000) == 1) { + phydm_api_trx_mode(dm, BB_PATH_AB, BB_PATH_AB, + BB_PATH_AUTO); + PHYDM_DBG(dm, DBG_TXBF, "[MU IOT] 22C IOT Restore\n"); + rateinfo->mu_been_iot = 0; + } + } rateinfo->pre_mu_ratio = mu_ratio; - phydm_mu_rsoml_reset(dm); } -void phydm_txbf_avoid_hang(void *dm_void) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - - /* avoid CCK CCA hang when the BF mode */ - odm_set_bb_reg(dm, R_0x1e6c, 0x100000, 0x1); -} #if (RTL8814B_SUPPORT == 1) void phydm_txbf_80p80_rfmode(void *dm_void, u8 su_bfee_cnt, u8 mu_bfee_cnt) @@ -621,6 +665,21 @@ void phydm_txbf_80p80_rfmode(void *dm_void, u8 su_bfee_cnt, u8 mu_bfee_cnt) #endif #endif /*PHYSTS_3RD_TYPE_IC*/ +void phydm_txbf_avoid_hang(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + /* avoid CCK CCA hang when the BF mode */ +#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT + odm_set_bb_reg(dm, R_0x1e6c, 0x100000, 0x1); +#endif + + /* avoid CCK CCA hang when the BFee mode for 92F */ +#if (RTL8192F_SUPPORT == 1) + odm_set_bb_reg(dm, R_0xa70, 0xffff0000, 0x80ff); +#endif +} + void phydm_bf_debug(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len) { @@ -634,11 +693,12 @@ void phydm_bf_debug(void *dm_void, char input[][16], u32 *_used, char *output, "{BF ver1 :0}, {NO applyV:0; applyV:1; default:2}\n"); PDM_SNPF(*_out_len, *_used, output + *_used, *_out_len - *_used, "{MU RSOML:1}, {MU enable:1/0}, {MU Ratio:40}\n"); + PDM_SNPF(*_out_len, *_used, output + *_used, *_out_len - *_used, + "{MU TRxPath:2}, {TRxPath enable:1/0}\n"); return; } for (i = 0; i < 3; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); } if (var1[0] == 0) { #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) @@ -683,6 +743,16 @@ void phydm_bf_debug(void *dm_void, char input[][16], u32 *_used, char *output, "[MU RSOML] enable= %d, MU ratio TH= %d\n", bfinfo->enable, bfinfo->mu_ratio_th); #endif + } else if (var1[0] == 2) { + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_bf_rate_info_jgr3 *bfinfo = &dm->bf_rate_info_jgr3; + + bfinfo->mu_set_trxpath = (u8)var1[1]; + PDM_SNPF(*_out_len, *_used, output + *_used, *_out_len - *_used, + "[MU TRxPath] mu_set_trxpath = %d\n", + bfinfo->mu_set_trxpath); + #endif } } diff --git a/hal/phydm/txbf/phydm_hal_txbf_api.h b/hal/phydm/txbf/phydm_hal_txbf_api.h index ee1788c..15659cc 100644 --- a/hal/phydm/txbf/phydm_hal_txbf_api.h +++ b/hal/phydm/txbf/phydm_hal_txbf_api.h @@ -44,8 +44,7 @@ u8 beamforming_get_vht_ndp_tx_rate(void *dm_void, u8 bfer_str_num); #endif #if (RTL8822B_SUPPORT == 1 || RTL8822C_SUPPORT == 1 || RTL8192F_SUPPORT == 1 ||\ - RTL8814B_SUPPORT == 1 || RTL8198F_SUPPORT == 1) - + RTL8814B_SUPPORT == 1 || RTL8198F_SUPPORT == 1 || RTL8812F_SUPPORT == 1) u8 phydm_get_beamforming_sounding_info(void *dm_void, u16 *throughput, u8 total_bfee_num, u8 *tx_rate); u8 phydm_get_ndpa_rate(void *dm_void); @@ -66,6 +65,11 @@ struct phydm_bf_rate_info_jgr3 { u32 pre_mu_ratio; u16 num_mu_vht_pkt[VHT_RATE_NUM]; u16 num_qry_vht_pkt[VHT_RATE_NUM]; + boolean mu_set_trxpath; + u8 tx_path_en_ofdm_1sts; + u8 tx_path_en_ofdm_2sts; + u8 rx_path_en_ofdm; + boolean mu_been_iot; }; /*this function is only used for BFer*/ diff --git a/hal/rtl8822b/rtl8822b.h b/hal/rtl8822b/rtl8822b.h index 9a70376..60a41d9 100644 --- a/hal/rtl8822b/rtl8822b.h +++ b/hal/rtl8822b/rtl8822b.h @@ -120,18 +120,14 @@ void rtl8822b_query_rx_desc(union recv_frame *, u8 *pdesc); /* rtl8822b_cmd.c */ s32 rtl8822b_fillh2ccmd(PADAPTER, u8 id, u32 buf_len, u8 *pbuf); -void rtl8822b_set_FwPwrMode_cmd(PADAPTER, u8 psmode); +void _rtl8822b_set_FwPwrMode_cmd(PADAPTER adapter, u8 psmode, u8 rfon_ctrl); +void rtl8822b_set_FwPwrMode_cmd(PADAPTER adapter, u8 psmode); +void rtl8822b_set_FwPwrMode_rfon_ctrl_cmd(PADAPTER adapter, u8 rfon_ctrl); #ifdef CONFIG_USB_CONFIG_OFFLOAD_8822B void rtl8822b_set_usb_config_offload(PADAPTER adapter); #endif -#ifdef CONFIG_TDLS -#ifdef CONFIG_TDLS_CH_SW -void rtl8822b_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); -#endif -#endif - void rtl8822b_set_FwPwrModeInIPS_cmd(PADAPTER adapter, u8 cmd_param); #ifdef CONFIG_WOWLAN void rtl8822b_set_fw_pwrmode_inips_cmd_wowlan(PADAPTER padapter, u8 ps_mode); diff --git a/hal/rtl8822b/rtl8822b_cmd.c b/hal/rtl8822b/rtl8822b_cmd.c index 54ccbf9..3cfa97b 100644 --- a/hal/rtl8822b/rtl8822b_cmd.c +++ b/hal/rtl8822b/rtl8822b_cmd.c @@ -98,7 +98,7 @@ void rtl8822b_req_txrpt_cmd(PADAPTER adapter, u8 macid) #define SET_PWR_MODE_SET_ADOPT_BCN_RECEIVING_TIME(h2c_pkt, value) \ SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 31, 1, value) -void rtl8822b_set_FwPwrMode_cmd(PADAPTER adapter, u8 psmode) +void _rtl8822b_set_FwPwrMode_cmd(PADAPTER adapter, u8 psmode, u8 rfon_ctrl) { int i; u8 smart_ps = 0, mode = 0; @@ -120,12 +120,14 @@ void rtl8822b_set_FwPwrMode_cmd(PADAPTER adapter, u8 psmode) #endif /* CONFIG_P2P */ u8 hw_port = rtw_hal_get_port(adapter); - if (pwrpriv->dtim > 0) - RTW_INFO(FUNC_ADPT_FMT ": dtim=%d, HW port id=%d\n", FUNC_ADPT_ARG(adapter), - pwrpriv->dtim, psmode == PS_MODE_ACTIVE ? pwrpriv->current_lps_hw_port_id : hw_port); - else - RTW_INFO(FUNC_ADPT_FMT ": HW port id=%d\n", FUNC_ADPT_ARG(adapter), - psmode == PS_MODE_ACTIVE ? pwrpriv->current_lps_hw_port_id : hw_port); + if (pwrpriv->pwr_mode != psmode) { + if (pwrpriv->dtim > 0) + RTW_INFO(FUNC_ADPT_FMT ": dtim=%d, HW port id=%d\n", FUNC_ADPT_ARG(adapter), + pwrpriv->dtim, psmode == PS_MODE_ACTIVE ? pwrpriv->current_lps_hw_port_id : hw_port); + else + RTW_INFO(FUNC_ADPT_FMT ": HW port id=%d\n", FUNC_ADPT_ARG(adapter), + psmode == PS_MODE_ACTIVE ? pwrpriv->current_lps_hw_port_id : hw_port); + } if (psmode == PS_MODE_MIN || psmode == PS_MODE_MAX) { #ifdef CONFIG_WMMPS_STA @@ -194,19 +196,28 @@ void rtl8822b_set_FwPwrMode_cmd(PADAPTER adapter, u8 psmode) PowerState = rtw_btcoex_RpwmVal(adapter); else #endif /* CONFIG_BT_COEXIST */ - PowerState = 0x00; /* AllON(0x0C), RFON(0x04), RFOFF(0x00) */ + { + if (rfon_ctrl == rf_on) + PowerState = 0x04; /* AllON(0x0C), RFON(0x04), RFOFF(0x00) */ + else + PowerState = 0x00; /* AllON(0x0C), RFON(0x04), RFOFF(0x00) */ + } } else PowerState = 0x0C; /* AllON(0x0C), RFON(0x04), RFOFF(0x00) */ - if (mode == 0) - fw_psmode_str = "ACTIVE"; - else if (mode == 1) - fw_psmode_str = "LPS"; - else if (mode == 2) - fw_psmode_str = "WMMPS"; + if (pwrpriv->pwr_mode != psmode) { + if (mode == 0) + fw_psmode_str = "ACTIVE"; + else if (mode == 1) + fw_psmode_str = "LPS"; + else if (mode == 2) + fw_psmode_str = "WMMPS"; - RTW_INFO(FUNC_ADPT_FMT": fw ps mode = %s, drv ps mode = %d, rlbm = %d , smart_ps = %d, allQueueUAPSD = %d\n", - FUNC_ADPT_ARG(adapter), fw_psmode_str, psmode, rlbm, smart_ps, allQueueUAPSD); + RTW_INFO(FUNC_ADPT_FMT": fw ps mode = %s, drv ps mode = %d, rlbm = %d ," + "smart_ps = %d, allQueueUAPSD = %d, PowerState = %d\n", + FUNC_ADPT_ARG(adapter), fw_psmode_str, psmode, rlbm, smart_ps, + allQueueUAPSD, PowerState); + } SET_PWR_MODE_SET_CMD_ID(h2c, CMD_ID_SET_PWR_MODE); SET_PWR_MODE_SET_CLASS(h2c, CLASS_SET_PWR_MODE); @@ -245,23 +256,17 @@ void rtl8822b_set_FwPwrMode_cmd(PADAPTER adapter, u8 psmode) rtw_halmac_send_h2c(adapter_to_dvobj(adapter), h2c); } -#ifdef CONFIG_TDLS -#ifdef CONFIG_TDLS_CH_SW -void rtl8822b_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable) +void rtl8822b_set_FwPwrMode_cmd(PADAPTER adapter, u8 psmode) { - u8 u1H2CSetPwrMode[RTW_HALMAC_H2C_MAX_SIZE] = {0}; - - SET_PWR_MODE_SET_CMD_ID(u1H2CSetPwrMode, CMD_ID_SET_PWR_MODE); - SET_PWR_MODE_SET_CLASS(u1H2CSetPwrMode, CLASS_SET_PWR_MODE); - SET_PWR_MODE_SET_MODE(u1H2CSetPwrMode, 1); - SET_PWR_MODE_SET_RLBM(u1H2CSetPwrMode, 1); - SET_PWR_MODE_SET_BCN_EARLY_RPT(u1H2CSetPwrMode, enable); - SET_PWR_MODE_SET_PWR_STATE(u1H2CSetPwrMode, 0x0C); - - rtw_halmac_send_h2c(adapter_to_dvobj(padapter), u1H2CSetPwrMode); + return _rtl8822b_set_FwPwrMode_cmd(adapter, psmode, rf_off); +} + +void rtl8822b_set_FwPwrMode_rfon_ctrl_cmd(PADAPTER adapter, u8 rfon_ctrl) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); + + return _rtl8822b_set_FwPwrMode_cmd(adapter, pwrpriv->power_mgnt, rfon_ctrl); } -#endif -#endif void rtl8822b_set_FwPwrModeInIPS_cmd(PADAPTER adapter, u8 cmd_param) { @@ -287,14 +292,19 @@ void rtl8822b_set_fw_pwrmode_inips_cmd_wowlan(PADAPTER padapter, u8 ps_mode) struct registry_priv *registry_par = &padapter->registrypriv; u8 param[H2C_INACTIVE_PS_LEN] = {0}; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); RTW_INFO("%s, ps_mode: %d\n", __func__, ps_mode); if (ps_mode == PS_MODE_ACTIVE) { SET_H2CCMD_INACTIVE_PS_EN(param, 0); +#ifdef CONFIG_FW_MULTI_PORT_SUPPORT + SET_H2CCMD_INACTIVE_PORT_NUM(param, pwrpriv->current_lps_hw_port_id); + RTW_DBG("pwrpriv->current_lps_hw_port_id = %d\n", pwrpriv->current_lps_hw_port_id); +#endif /* CONFIG_FW_MULTI_PORT_SUPPORT*/ } else { SET_H2CCMD_INACTIVE_PS_EN(param, 1); - if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, _FW_LINKED)) + if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) SET_H2CCMD_INACTIVE_DISBBRF(param, 1); if(registry_par->suspend_type == FW_IPS_WRC) { SET_H2CCMD_INACTIVE_PERIOD_SCAN_EN(param, 1); @@ -302,6 +312,11 @@ void rtl8822b_set_fw_pwrmode_inips_cmd_wowlan(PADAPTER padapter, u8 ps_mode) SET_H2CCMD_INACTIVE_PS_DURATION(param, 1); SET_H2CCMD_INACTIVE_PS_PERIOD_SCAN_TIME(param, 3); } +#ifdef CONFIG_FW_MULTI_PORT_SUPPORT + pwrpriv->current_lps_hw_port_id = get_hw_port(padapter); + SET_H2CCMD_INACTIVE_PORT_NUM(param, pwrpriv->current_lps_hw_port_id); + RTW_DBG("pwrpriv->current_lps_hw_port_id = %d\n", pwrpriv->current_lps_hw_port_id); +#endif /* CONFIG_FW_MULTI_PORT_SUPPORT*/ } rtl8822b_fillh2ccmd(padapter, H2C_INACTIVE_PS_, sizeof(param), param); diff --git a/hal/rtl8822b/rtl8822b_halinit.c b/hal/rtl8822b/rtl8822b_halinit.c index 7032177..dffd563 100644 --- a/hal/rtl8822b/rtl8822b_halinit.c +++ b/hal/rtl8822b/rtl8822b_halinit.c @@ -31,12 +31,14 @@ void rtl8822b_init_hal_spec(PADAPTER adapter) hal_spec->ic_name = "rtl8822b"; hal_spec->macid_num = 128; /* hal_spec->sec_cam_ent_num follow halmac setting */ - hal_spec->sec_cap = SEC_CAP_CHK_BMC; + hal_spec->sec_cap = SEC_CAP_CHK_BMC | SEC_CAP_CHK_EXTRA_SEC; + hal_spec->wow_cap = WOW_CAP_TKIP_OL; hal_spec->macid_cap = MACID_DROP; hal_spec->rfpath_num_2g = 2; hal_spec->rfpath_num_5g = 2; - hal_spec->rf_reg_path_num = 2; + hal_spec->rf_reg_path_num = hal_spec->rf_reg_path_avail_num = 2; + hal_spec->rf_reg_trx_path_bmp = 0x33; hal_spec->max_tx_cnt = 2; hal_spec->tx_nss_num = 2; @@ -55,9 +57,7 @@ void rtl8822b_init_hal_spec(PADAPTER adapter) | WL_FUNC_TDLS ; -#if CONFIG_TX_AC_LIFETIME hal_spec->tx_aclt_unit_factor = 8; -#endif hal_spec->rx_tsf_filter = 1; @@ -71,6 +71,7 @@ void rtl8822b_init_hal_spec(PADAPTER adapter) , REG_MACID_SLEEP1_8822B , REG_MACID_SLEEP2_8822B , REG_MACID_SLEEP3_8822B); + rtw_macid_ctl_init_drop_reg(adapter_to_macidctl(adapter) , REG_MACID_DROP0_8822B , REG_MACID_DROP1_8822B diff --git a/hal/rtl8822b/rtl8822b_ops.c b/hal/rtl8822b/rtl8822b_ops.c index aed7132..3111e00 100644 --- a/hal/rtl8822b/rtl8822b_ops.c +++ b/hal/rtl8822b/rtl8822b_ops.c @@ -869,14 +869,11 @@ static void xmit_status_check(PADAPTER p) else { diff_time = rtw_get_passing_time_ms(psrtpriv->last_tx_complete_time); if (diff_time > 4000) { - u32 ability = 0; - - ability = rtw_phydm_ability_get(p); RTW_INFO("%s tx hang %s\n", __FUNCTION__, - (ability & ODM_BB_ADAPTIVITY) ? "ODM_BB_ADAPTIVITY" : ""); + (rtw_odm_adaptivity_needed(p)) ? "ODM_BB_ADAPTIVITY" : ""); - if (!(ability & ODM_BB_ADAPTIVITY)) { + if (!rtw_odm_adaptivity_needed(p)) { psrtpriv->self_dect_tx_cnt++; psrtpriv->self_dect_case = 1; rtw_hal_sreset_reset(p); @@ -965,29 +962,47 @@ static void linked_status_check(PADAPTER p) static void set_opmode_monitor(PADAPTER adapter) { - u32 rcr_bits; - u16 value_rxfltmap2; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; +#ifdef CONFIG_WIFI_MONITOR + u8 tmp_8bit; + u32 tmp_32bit; + struct net_device *ndev = adapter->pnetdev; + struct mon_reg_backup *mon = &GET_HAL_DATA(adapter)->mon_backup; + mon->known_rcr = 1; + rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)& mon->rcr); /* Receive all type */ - rcr_bits = BIT_AAP_8822B | BIT_APM_8822B | BIT_AM_8822B - | BIT_AB_8822B | BIT_APWRMGT_8822B - | BIT_APP_PHYSTS_8822B; + tmp_32bit = BIT_AAP_8822B | BIT_APP_PHYSTS_8822B; -#ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL - /* Append FCS */ - rcr_bits |= BIT_APP_FCS_8822B; -#endif + if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) { + /* Append FCS */ + tmp_32bit |= BIT_APP_FCS_8822B; + } - rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&GET_HAL_DATA(adapter)->rcr_backup); - rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_bits); + rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)& tmp_32bit); + + if (1) + rtw_halmac_config_rx_info(adapter_to_dvobj(adapter), + HALMAC_DRV_INFO_PHY_SNIFFER); + else + rtw_halmac_config_rx_info(adapter_to_dvobj(adapter), + HALMAC_DRV_INFO_PHY_PLCP); + + tmp_8bit = rtw_read8(adapter, REG_RX_DRVINFO_SZ_8822B); + rtw_write8(adapter, REG_RX_DRVINFO_SZ_8822B, (tmp_8bit | 0x80)); /* Receive all data frames */ - value_rxfltmap2 = 0xFFFF; - rtw_write16(adapter, REG_RXFLTMAP2_8822B, value_rxfltmap2); + mon->known_rxfilter = 1; + mon->rxfilter0 = rtw_read16(adapter, REG_RXFLTMAP0_8822B); + mon->rxfilter1 = rtw_read16(adapter, REG_RXFLTMAP1_8822B); + mon->rxfilter2 = rtw_read16(adapter, REG_RXFLTMAP2_8822B); + rtw_write16(adapter, REG_RXFLTMAP0_8822B, 0xFFFF); + rtw_write16(adapter, REG_RXFLTMAP1_8822B, 0xFFFF); + rtw_write16(adapter, REG_RXFLTMAP2_8822B, 0xFFFF); +#endif /* CONFIG_WIFI_MONITOR */ } +#ifndef CONFIG_MI_WITH_MBSSID_CAM static void set_opmode_port0(PADAPTER adapter, u8 mode) { u8 is_tx_bcn; @@ -1069,7 +1084,7 @@ static void set_opmode_port0(PADAPTER adapter, u8 mode) /* Enable HW seq for BCN 0x4FC[0]: EN_HWSEQ -= 0x4FC[1]: EN_HWSEQEXT + 0x4FC[1]: EN_HWSEQEXT According TX desc */ rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01); @@ -1103,7 +1118,6 @@ static void set_opmode_port0(PADAPTER adapter, u8 mode) break; } } - static void set_opmode_port1(PADAPTER adapter, u8 mode) { #ifdef CONFIG_CONCURRENT_MODE @@ -1151,6 +1165,7 @@ static void set_opmode_port1(PADAPTER adapter, u8 mode) } #endif /* CONFIG_CONCURRENT_MODE */ } +#endif /* !CONFIG_MI_WITH_MBSSID_CAM */ void hw_tsf_reset(_adapter *adapter) { u8 hw_port = rtw_hal_get_port(adapter); @@ -1252,14 +1267,32 @@ void rtw_hw_client_port_clr(_adapter *adapter) static void hw_var_set_opmode(PADAPTER adapter, u8 mode) { - u8 val8; static u8 isMonitor = _FALSE; - if (isMonitor == _TRUE) { - /* reset RCR from backup */ - rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&GET_HAL_DATA(adapter)->rcr_backup); - rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE); +#ifdef CONFIG_WIFI_MONITOR + struct mon_reg_backup *backup = &GET_HAL_DATA(adapter)->mon_backup; + + if (backup->known_rcr) { + backup->known_rcr = 0; + rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&backup->rcr); + + if (!!(backup->rcr &= BIT_APP_PHYSTS_8822B)) + rtw_halmac_config_rx_info(adapter_to_dvobj(adapter), + HALMAC_DRV_INFO_PHY_STATUS); + else + rtw_halmac_config_rx_info(adapter_to_dvobj(adapter), + HALMAC_DRV_INFO_NONE); + + rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE); + } + if (backup->known_rxfilter) { + backup->known_rxfilter = 0; + rtw_write16(adapter, REG_RXFLTMAP0_8822B, backup->rxfilter0); + rtw_write16(adapter, REG_RXFLTMAP1_8822B, backup->rxfilter1); + rtw_write16(adapter, REG_RXFLTMAP2_8822B, backup->rxfilter2); + } +#endif /* CONFIG_WIFI_MONITOR */ isMonitor = _FALSE; } @@ -1472,16 +1505,18 @@ static void hw_var_set_mlme_sitesurvey(PADAPTER adapter, u8 enable) * 2. config RCR not to receive different BSSID BCN or probe rsp */ - if (rtw_mi_check_fwstate(adapter, _FW_LINKED | WIFI_AP_STATE | WIFI_MESH_STATE)) + if (rtw_mi_check_fwstate(adapter, WIFI_ASOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE)) /* enable to rx data frame */ rtw_write16(adapter, REG_RXFLTMAP2_8822B, 0xFFFF); rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE); + #ifdef CONFIG_AP_MODE if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) { ResumeTxBeacon(adapter); rtw_mi_tx_beacon_hdl(adapter); } + #endif } } @@ -1628,6 +1663,23 @@ static void hw_var_set_acm_ctrl(PADAPTER adapter, u8 ctrl) rtw_write8(adapter, REG_ACMHWCTRL_8822B, hwctrl); } +void hw_var_lps_rfon_chk(_adapter *adapter, u8 rfon_ctrl) +{ +#ifdef CONFIG_LPS_ACK + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); + + if (rfon_ctrl == rf_on) { + if (rtw_sctx_wait(&pwrpriv->lps_ack_sctx, __func__)) { + if (pwrpriv->lps_ack_status > 0) + RTW_INFO(FUNC_ADPT_FMT" RF_ON function is not ready !!!\n", FUNC_ADPT_ARG(adapter)); + } else { + RTW_WARN("LPS RFON sctx query timeout, operation abort!!\n"); + } + pwrpriv->lps_ack_status = -1; + } +#endif +} + static void hw_var_set_sec_dk_cfg(PADAPTER adapter, u8 enable) { struct security_priv *sec = &adapter->securitypriv; @@ -1791,6 +1843,53 @@ static void hw_var_set_h2c_fw_joinbssrpt(PADAPTER adapter, u8 mstatus) hw_var_set_dl_rsvd_page(adapter, RT_MEDIA_CONNECT); } +#ifdef CONFIG_WOWLAN +static void hw_var_vendor_wow_mode(_adapter *adapter, u8 en) +{ +#ifdef CONFIG_CONCURRENT_MODE + _adapter *iface = NULL; + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + u8 igi = 0, mac_addr[ETH_ALEN]; + + RTW_INFO("%s: en(%d)--->\n", __func__, en); + if (en) { + rtw_hal_get_hwreg(adapter, HW_VAR_MAC_ADDR, mac_addr); + /* RTW_INFO("suspend mac addr: "MAC_FMT"\n", MAC_ARG(mac_addr)); */ + rtw_halmac_set_bssid(dvobj, HW_PORT4, mac_addr); + dvobj->rxfltmap2_bf_suspend = rtw_read16(adapter, REG_RXFLTMAP2); + dvobj->bcn_ctrl_clint3_bf_suspend = rtw_read8(adapter, REG_BCN_CTRL_CLINT3); + dvobj->rcr_bf_suspend = rtw_read32(adapter, REG_RCR); + dvobj->cr_ext_bf_suspend = rtw_read32(adapter, REG_CR_EXT); + /*RTW_INFO("RCR: 0x%02x, REG_CR_EXT: 0x%02x , REG_BCN_CTRL_CLINT3: 0x%02x, REG_RXFLTMAP2:0x%02x, REG_MACID_DROP0_8822B:0x%02x\n" + , rtw_read32(adapter, REG_RCR), rtw_read8(adapter, REG_CR_EXT), rtw_read8(adapter, REG_BCN_CTRL_CLINT3) + , rtw_read32(adapter, REG_RXFLTMAP2), rtw_read8(adapter, REG_MACID_DROP0_8822B)); */ + rtw_write32(adapter, REG_RCR, (rtw_read32(adapter, REG_RCR) & (~(RCR_AM))) | RCR_CBSSID_DATA | RCR_CBSSID_BCN); + /* set PORT4 to ad hoc mode to filter not necessary Beacons */ + rtw_write8(adapter, REG_CR_EXT, (rtw_read8(adapter, REG_CR_EXT)& (~BIT5)) | BIT4); + rtw_write8(adapter, REG_BCN_CTRL_CLINT3, rtw_read8(adapter, REG_BCN_CTRL_CLINT3) | BIT3); + rtw_write16(adapter, REG_RXFLTMAP2, 0xffff); + /* RTW_INFO("RCR: 0x%02x, REG_CR_EXT: 0x%02x , REG_BCN_CTRL_CLINT3: 0x%02x, REG_RXFLTMAP2:0x%02x, REG_MACID_DROP0_8822B:0x%02x\n" + , rtw_read32(adapter, REG_RCR), rtw_read8(adapter, REG_CR_EXT), rtw_read8(adapter, REG_BCN_CTRL_CLINT3) + , rtw_read32(adapter, REG_RXFLTMAP2), rtw_read8(adapter, REG_MACID_DROP0_8822B)); */ + + /* The WRC's RSSI is weak. Set the IGI to lower */ + odm_write_dig(adapter_to_phydm(adapter), 0x24); + } else { + /* restore the rcr, port ctrol setting */ + rtw_write32(adapter, REG_CR_EXT, dvobj->cr_ext_bf_suspend); + rtw_write32(adapter, REG_RCR, dvobj->rcr_bf_suspend); + rtw_write8(adapter, REG_BCN_CTRL_CLINT3, dvobj->bcn_ctrl_clint3_bf_suspend); + rtw_write16(adapter, REG_RXFLTMAP2, dvobj->rxfltmap2_bf_suspend); + + /* RTW_INFO("RCR: 0x%02x, REG_CR_EXT: 0x%02x , REG_BCN_CTRL_CLINT3: 0x%02x, REG_RXFLTMAP2:0x%02x, REG_MACID_DROP0_8822B:0x%02x\n" + , rtw_read32(adapter, REG_RCR), rtw_read8(adapter, REG_CR_EXT), rtw_read8(adapter, REG_BCN_CTRL_CLINT3) + , rtw_read32(adapter, REG_RXFLTMAP2), rtw_read8(adapter, REG_MACID_DROP0_8822B)); */ + } +#endif /* CONFIG_CONCURRENT_MODE */ +} +#endif /* CONFIG_WOWLAN */ + /* * Parameters: * adapter @@ -2070,6 +2169,14 @@ u8 rtl8822b_sethwreg(PADAPTER adapter, u8 variable, u8 *val) case HW_VAR_H2C_FW_PWRMODE: rtl8822b_set_FwPwrMode_cmd(adapter, *val); break; + + case HW_VAR_H2C_FW_PWRMODE_RFON_CTRL: + rtl8822b_set_FwPwrMode_rfon_ctrl_cmd(adapter, *val); + break; + + case HW_VAR_LPS_RFON_CHK : + hw_var_lps_rfon_chk(adapter, *val); + break; /* case HW_VAR_H2C_PS_TUNE_PARAM: break; @@ -2082,6 +2189,11 @@ u8 rtl8822b_sethwreg(PADAPTER adapter, u8 variable, u8 *val) case HW_VAR_H2C_FW_JOINBSSRPT: hw_var_set_h2c_fw_joinbssrpt(adapter, *val); break; +#ifdef CONFIG_WOWLAN + case HW_VAR_VENDOR_WOW_MODE: + hw_var_vendor_wow_mode(adapter, *(u8 *)val); + break; +#endif /* CONFIG_WOWLAN */ case HW_VAR_DL_RSVD_PAGE: #ifdef CONFIG_BT_COEXIST if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) @@ -2218,11 +2330,12 @@ u8 rtl8822b_sethwreg(PADAPTER adapter, u8 variable, u8 *val) */ #ifdef CONFIG_GPIO_WAKEUP case HW_SET_GPIO_WL_CTRL: { + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); u8 enable = *val; u8 value = 0; u8 addr = REG_PAD_CTRL1_8822B + 3; - if (WAKEUP_GPIO_IDX == 6) { + if (pwrpriv->wowlan_gpio_index == 6) { value = rtw_read8(adapter, addr); if (enable == _TRUE && (value & BIT(1))) @@ -2322,13 +2435,6 @@ u8 rtl8822b_sethwreg(PADAPTER adapter, u8 variable, u8 *val) case HW_VAR_CH_SW_IQK_INFO_RESTORE: break; */ -#ifdef CONFIG_TDLS -#ifdef CONFIG_TDLS_CH_SW - case HW_VAR_TDLS_BCN_EARLY_C2H_RPT: - rtl8822b_set_BcnEarly_C2H_Rpt_cmd(adapter, *val); - break; -#endif -#endif case HW_VAR_FREECNT: @@ -2377,6 +2483,7 @@ u8 rtl8822b_sethwreg(PADAPTER adapter, u8 variable, u8 *val) return ret; } +#ifdef CONFIG_PROC_DEBUG struct qinfo { u32 head:11; u32 tail:11; @@ -2478,6 +2585,7 @@ static void dump_mac_txfifo(void *sel, _adapter *adapter) RTW_PRINT_SEL(sel, "HPQ: %d, LPQ: %d, NPQ: %d, EPQ: %d, PUBQ: %d\n" , hpq, lpq, npq, epq, pubq); } +#endif static u8 hw_var_get_bcn_valid(PADAPTER adapter) { @@ -2569,8 +2677,11 @@ void rtl8822b_gethwreg(PADAPTER adapter, u8 variable, u8 *val) case HW_VAR_BCN_VALID: *val = hw_var_get_bcn_valid(adapter); break; -/* case HW_VAR_FREECNT: + /* free run counter 0x577[3]=1 means running */ + *val = rtw_read8(adapter, REG_MISC_CTRL)&BIT_EN_FREECNT; + break; +/* case HW_VAR_CAM_INVALID_ALL: */ case HW_VAR_AC_PARAM_VO: @@ -2723,6 +2834,7 @@ void rtl8822b_gethwreg(PADAPTER adapter, u8 variable, u8 *val) *((u16 *)val) = rtw_read8(adapter, REG_SYS_CFG5); break; +#ifdef CONFIG_PROC_DEBUG case HW_VAR_DUMP_MAC_QUEUE_INFO: dump_mac_qinfo(val, adapter); break; @@ -2730,6 +2842,7 @@ void rtl8822b_gethwreg(PADAPTER adapter, u8 variable, u8 *val) case HW_VAR_DUMP_MAC_TXFIFO: dump_mac_txfifo(val, adapter); break; +#endif /* case HW_VAR_ASIX_IOT: case HW_VAR_EN_HW_UPDATE_TSF: @@ -2738,7 +2851,7 @@ void rtl8822b_gethwreg(PADAPTER adapter, u8 variable, u8 *val) case HW_VAR_CH_SW_IQK_INFO_RESTORE: #ifdef CONFIG_TDLS #ifdef CONFIG_TDLS_CH_SW - case HW_VAR_TDLS_BCN_EARLY_C2H_RPT: + case HW_VAR_BCN_EARLY_C2H_RPT: #endif #endif break; @@ -2968,6 +3081,11 @@ void rtl8822b_fill_txdesc_sectype(struct pkt_attrib *pattrib, u8 *ptxdesc) case _AES_: SET_TX_DESC_SEC_TYPE_8822B(ptxdesc, 0x3); break; + case _CCMP_256_: + case _GCMP_: + case _GCMP_256_: + SET_TX_DESC_SEC_TYPE_8822B(ptxdesc, 0x2); + break; case _NO_PRIVACY_: default: SET_TX_DESC_SEC_TYPE_8822B(ptxdesc, 0x0); @@ -3134,7 +3252,6 @@ static void rtl8822b_fill_txdesc_tx_rate(struct _ADAPTER *adapter, } } -#ifdef CONFIG_CONCURRENT_MODE void rtl8822b_fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc) { if ((pattrib->encrypt > 0) && (!pattrib->bswenc) @@ -3143,7 +3260,6 @@ void rtl8822b_fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdes SET_TX_DESC_MACID_8822B(ptxdesc, pattrib->bmc_camid); } } -#endif void rtl8822b_fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc) { @@ -3162,14 +3278,17 @@ void rtl8822b_fill_txdesc_bf(struct xmit_frame *frame, u8 *desc) return; #else /* CONFIG_BEAMFORMING */ struct pkt_attrib *attrib; - + struct _ADAPTER *padapter = frame->padapter; + struct hal_com_data *pHalData = GET_HAL_DATA(padapter); + u8 init_rate; attrib = &frame->attrib; + init_rate = pHalData->INIDATA_RATE[attrib->mac_id] & 0x7F; SET_TX_DESC_G_ID_8822B(desc, attrib->txbf_g_id); SET_TX_DESC_P_AID_8822B(desc, attrib->txbf_p_aid); - SET_TX_DESC_MU_DATARATE_8822B(desc, MRateToHwRate(attrib->rate)); + SET_TX_DESC_MU_DATARATE_8822B(desc, init_rate); /*SET_TX_DESC_MU_RC_8822B(desc, 0);*/ /* Force to disable STBC when txbf is enabled */ @@ -3348,10 +3467,8 @@ static void fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf) rtl8822b_fill_txdesc_sectype(pattrib, pbuf); rtl8822b_fill_txdesc_vcs(adapter, pattrib, pbuf); -#ifdef CONFIG_CONCURRENT_MODE if (bmcst) rtl8822b_fill_txdesc_force_bmc_camid(pattrib, pbuf); -#endif #ifdef CONFIG_P2P if (!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) { @@ -3671,6 +3788,11 @@ static void fill_fake_txdesc(PADAPTER adapter, u8 *pDesc, u32 BufferLen, case _AES_: SET_TX_DESC_SEC_TYPE_8822B(pDesc, 0x3); break; + case _CCMP_256_: + case _GCMP_: + case _GCMP_256_: + SET_TX_DESC_SEC_TYPE_8822B(pDesc, 0x2); + break; default: SET_TX_DESC_SEC_TYPE_8822B(pDesc, 0x0); break; @@ -3763,6 +3885,8 @@ void rtl8822b_rxdesc2attribute(struct rx_pkt_attrib *a, u8 *desc) a->frag_num = (u8)GET_RX_DESC_FRAG_8822B(desc); a->data_rate = (u8)GET_RX_DESC_RX_RATE_8822B(desc); + a->ampdu = (u8)GET_RX_DESC_PAGGR_8822B(desc); + a->ampdu_eof = (u8)GET_RX_DESC_RX_EOF_8822B(desc); a->ppdu_cnt = (u8)GET_RX_DESC_PPDU_CNT_8822B(desc); a->free_cnt = (u32)GET_RX_DESC_TSFL_8822B(desc); diff --git a/hal/rtl8822b/rtl8822b_phy.c b/hal/rtl8822b/rtl8822b_phy.c index 1ec7541..8227fe3 100644 --- a/hal/rtl8822b/rtl8822b_phy.c +++ b/hal/rtl8822b/rtl8822b_phy.c @@ -187,6 +187,7 @@ static u8 _init_rf_reg(PADAPTER adapter) u8 path; enum rf_path phydm_path; PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE u8 *regfile; #endif @@ -198,7 +199,7 @@ static u8 _init_rf_reg(PADAPTER adapter) /* * Initialize RF */ - for (path = 0; path < hal->NumTotalRFPath; path++) { + for (path = 0; path < hal_spec->rf_reg_path_num; path++) { /* Initialize RF from configuration file */ switch (path) { case 0: @@ -387,7 +388,7 @@ void dm_InterruptMigration(PADAPTER adapter) * when interrupt migration is set before. 2010.03.05. */ if (!adapter->registrypriv.wifi_spec - && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) && pmlmepriv->LinkDetectInfo.bHigherBusyTraffic) { IntMtToSet = _TRUE; @@ -426,8 +427,6 @@ static void init_phydm_cominfo(PADAPTER adapter) PHAL_DATA_TYPE hal; struct dm_struct *p_dm_odm; u32 support_ability = 0; - u8 cut_ver = ODM_CUT_A, fab_ver = ODM_TSMC; - hal = GET_HAL_DATA(adapter); p_dm_odm = &hal->odmpriv; @@ -437,41 +436,9 @@ static void init_phydm_cominfo(PADAPTER adapter) odm_cmn_info_init(p_dm_odm, ODM_CMNINFO_PACKAGE_TYPE, hal->PackageType); odm_cmn_info_init(p_dm_odm, ODM_CMNINFO_IC_TYPE, ODM_RTL8822B); - if (IS_CHIP_VENDOR_TSMC(hal->version_id)) - fab_ver = ODM_TSMC; - else if (IS_CHIP_VENDOR_UMC(hal->version_id)) - fab_ver = ODM_UMC; - else if (IS_CHIP_VENDOR_SMIC(hal->version_id)) - fab_ver = ODM_UMC + 1; - else - RTW_INFO("%s: unknown Fv=%d !!\n", - __FUNCTION__, GET_CVID_MANUFACTUER(hal->version_id)); - - if (IS_A_CUT(hal->version_id)) - cut_ver = ODM_CUT_A; - else if (IS_B_CUT(hal->version_id)) - cut_ver = ODM_CUT_B; - else if (IS_C_CUT(hal->version_id)) - cut_ver = ODM_CUT_C; - else if (IS_D_CUT(hal->version_id)) - cut_ver = ODM_CUT_D; - else if (IS_E_CUT(hal->version_id)) - cut_ver = ODM_CUT_E; - else if (IS_F_CUT(hal->version_id)) - cut_ver = ODM_CUT_F; - else if (IS_I_CUT(hal->version_id)) - cut_ver = ODM_CUT_I; - else if (IS_J_CUT(hal->version_id)) - cut_ver = ODM_CUT_J; - else if (IS_K_CUT(hal->version_id)) - cut_ver = ODM_CUT_K; - else - RTW_INFO("%s: unknown Cv=%d !!\n", - __FUNCTION__, GET_CVID_CUT_VERSION(hal->version_id)); - - RTW_INFO("%s: Fv=%d Cv=%d\n", __FUNCTION__, fab_ver, cut_ver); - odm_cmn_info_init(p_dm_odm, ODM_CMNINFO_FAB_VER, fab_ver); - odm_cmn_info_init(p_dm_odm, ODM_CMNINFO_CUT_VER, cut_ver); + RTW_INFO("%s: Fv=%d Cv=%d\n", __FUNCTION__, hal->version_id.VendorType, hal->version_id.CUTVersion); + odm_cmn_info_init(p_dm_odm, ODM_CMNINFO_FAB_VER, hal->version_id.VendorType); + odm_cmn_info_init(p_dm_odm, ODM_CMNINFO_CUT_VER, hal->version_id.CUTVersion); } @@ -520,7 +487,6 @@ void rtl8822b_phy_haldm_watchdog(PADAPTER adapter) BOOLEAN bFwCurrentInPSMode = _FALSE; u8 bFwPSAwake = _TRUE; struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); - u8 lps_changed = _FALSE; u8 in_lps = _FALSE; PADAPTER current_lps_iface = NULL, iface = NULL; struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); @@ -560,28 +526,29 @@ void rtl8822b_phy_haldm_watchdog(PADAPTER adapter) } #ifdef CONFIG_LPS - if (pwrpriv->bLeisurePs && bFwCurrentInPSMode && pwrpriv->pwr_mode != PS_MODE_ACTIVE -#ifdef CONFIG_WMMPS_STA - && !rtw_is_wmmps_mode(adapter) -#endif /* CONFIG_WMMPS_STA */ - ) { + if (pwrpriv->bLeisurePs && bFwCurrentInPSMode && pwrpriv->pwr_mode != PS_MODE_ACTIVE) { + in_lps = _TRUE; for (i = 0; i < dvobj->iface_nums; i++) { iface = dvobj->padapters[i]; - if (pwrpriv->current_lps_hw_port_id == rtw_hal_get_port(iface)) + if (pwrpriv->current_lps_hw_port_id == rtw_hal_get_port(iface)) { current_lps_iface = iface; + rtw_lps_rfon_ctrl(current_lps_iface, rf_on); + break; + } } - lps_changed = _TRUE; - in_lps = _TRUE; - LPS_Leave(current_lps_iface, LPS_CTRL_PHYDM); + if (!current_lps_iface) { + RTW_WARN("Can't find a adapter with LPS to enable RFON function !\n"); + goto skip_dm; + } } #endif #ifdef CONFIG_BEAMFORMING #ifdef RTW_BEAMFORMING_VERSION_2 if (check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) && - check_fwstate(&adapter->mlmepriv, _FW_LINKED)) + check_fwstate(&adapter->mlmepriv, WIFI_ASOC_STATE)) rtw_hal_beamforming_config_csirate(adapter); #endif #endif @@ -596,8 +563,8 @@ void rtl8822b_phy_haldm_watchdog(PADAPTER adapter) skip_dm: #ifdef CONFIG_LPS - if (lps_changed) - LPS_Enter(current_lps_iface, LPS_CTRL_PHYDM); + if (current_lps_iface) + rtw_lps_rfon_ctrl(current_lps_iface, rf_off); #endif /* @@ -703,31 +670,12 @@ static void set_tx_power_level_by_path(PADAPTER adapter, u8 channel, u8 path) void rtl8822b_set_tx_power_level(PADAPTER adapter, u8 channel) { - PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter); - struct dm_struct *phydm; - #ifdef CONFIG_ANTENNA_DIVERSITY - struct phydm_fat_struct *p_dm_fat_table; - #endif + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); u8 path = RF_PATH_A; - - hal = GET_HAL_DATA(adapter); - phydm = &hal->odmpriv; - - #ifdef CONFIG_ANTENNA_DIVERSITY - p_dm_fat_table = &phydm->dm_fat_table; - - if (hal->AntDivCfg) { - /* antenna diversity Enable */ - path = (p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? RF_PATH_A : RF_PATH_B; - set_tx_power_level_by_path(adapter, channel, path); - } else - #endif - { - /* antenna diversity disable */ - for (path = RF_PATH_A; path < hal->NumTotalRFPath; ++path) + for (path = RF_PATH_A; path < hal_spec->rf_reg_path_num; ++path) + if (GET_HAL_TX_PATH_BMP(adapter) & BIT(path)) set_tx_power_level_by_path(adapter, channel, path); - } } /* diff --git a/hal/rtl8822b/usb/rtl8822bu.h b/hal/rtl8822b/usb/rtl8822bu.h index 075e275..a8e0282 100644 --- a/hal/rtl8822b/usb/rtl8822bu.h +++ b/hal/rtl8822b/usb/rtl8822bu.h @@ -49,6 +49,9 @@ s32 rtl8822bu_init_xmit_priv(PADAPTER); void rtl8822bu_free_xmit_priv(PADAPTER); s32 rtl8822bu_mgnt_xmit(PADAPTER, struct xmit_frame *); s32 rtl8822bu_hal_xmit(PADAPTER, struct xmit_frame *); +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtl8822bu_hal_mgmt_xmitframe_enqueue(PADAPTER, struct xmit_frame *); +#endif s32 rtl8822bu_hal_xmitframe_enqueue(PADAPTER, struct xmit_frame *); s32 rtl8822bu_hostap_mgnt_xmit_entry(PADAPTER, _pkt *); #ifdef CONFIG_XMIT_THREAD_MODE diff --git a/hal/rtl8822b/usb/rtl8822bu_halinit.c b/hal/rtl8822b/usb/rtl8822bu_halinit.c index 4b7f96c..c58ddda 100644 --- a/hal/rtl8822b/usb/rtl8822bu_halinit.c +++ b/hal/rtl8822b/usb/rtl8822bu_halinit.c @@ -255,6 +255,7 @@ exit: u32 rtl8822bu_inirp_init(PADAPTER padapter) { + struct registry_priv *regsty = adapter_to_regsty(padapter); u8 i, status; struct recv_buf *precvbuf; struct dvobj_priv *pdev = adapter_to_dvobj(padapter); @@ -285,7 +286,7 @@ u32 rtl8822bu_inirp_init(PADAPTER padapter) /* issue Rx irp to receive data */ precvbuf = (struct recv_buf *)precvpriv->precv_buf; - for (i = 0; i < NR_RECVBUFF; i++) { + for (i = 0; i < regsty->recvbuf_nr; i++) { if (_read_port(pintfhdl, precvpriv->ff_hwaddr, 0, (u8 *)precvbuf) == _FALSE) { status = _FAIL; goto exit; diff --git a/hal/rtl8822b/usb/rtl8822bu_ops.c b/hal/rtl8822b/usb/rtl8822bu_ops.c index 6c4862a..b9f2c76 100644 --- a/hal/rtl8822b/usb/rtl8822bu_ops.c +++ b/hal/rtl8822b/usb/rtl8822bu_ops.c @@ -198,11 +198,6 @@ static u8 rtl8822bu_ps_func(PADAPTER padapter, HAL_INTF_PS_FUNC efunc_id, u8 *va switch (efunc_id) { -#if defined(CONFIG_AUTOSUSPEND) && defined(SUPPORT_HW_RFOFF_DETECTED) - case HAL_USB_SELECT_SUSPEND: - break; -#endif /* CONFIG_AUTOSUSPEND && SUPPORT_HW_RFOFF_DETECTED */ - default: break; } @@ -321,6 +316,9 @@ void rtl8822bu_set_hal_ops(PADAPTER padapter) ops->hal_xmit = rtl8822bu_hal_xmit; ops->mgnt_xmit = rtl8822bu_mgnt_xmit; +#ifdef CONFIG_RTW_MGMT_QUEUE + ops->hal_mgmt_xmitframe_enqueue = rtl8822bu_hal_mgmt_xmitframe_enqueue; +#endif ops->hal_xmitframe_enqueue = rtl8822bu_hal_xmitframe_enqueue; #ifdef CONFIG_HOSTAPD_MLME diff --git a/hal/rtl8822b/usb/rtl8822bu_xmit.c b/hal/rtl8822b/usb/rtl8822bu_xmit.c index 74d4086..7e66c91 100644 --- a/hal/rtl8822b/usb/rtl8822bu_xmit.c +++ b/hal/rtl8822b/usb/rtl8822bu_xmit.c @@ -132,10 +132,8 @@ static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bag rtl8822b_fill_txdesc_vcs(padapter, pattrib, ptxdesc); -#ifdef CONFIG_CONCURRENT_MODE if (bmcst) rtl8822b_fill_txdesc_force_bmc_camid(pattrib, ptxdesc); -#endif #ifdef CONFIG_SUPPORT_DYNAMIC_TXPWR rtw_phydm_set_dyntxpwr(padapter, ptxdesc, pattrib->mac_id); #endif @@ -392,7 +390,7 @@ static s32 rtw_dump_xframe(PADAPTER padapter, struct xmit_frame *pxmitframe) (pxmitframe->attrib.ether_type != 0x888e) && (pxmitframe->attrib.ether_type != 0x88b4) && (pxmitframe->attrib.dhcp_pkt != 1)) - rtw_issue_addbareq_cmd(padapter, pxmitframe); + rtw_issue_addbareq_cmd(padapter, pxmitframe, _FALSE); #endif /* CONFIG_80211N_HT */ mem_addr = pxmitframe->buf_addr; @@ -499,7 +497,14 @@ static s32 rtl8822bu_xmitframe_complete(PADAPTER padapter, struct xmit_priv *pxm int res = _SUCCESS; #endif - +#ifdef CONFIG_RTW_MGMT_QUEUE + /* dump management frame directly */ + pxmitframe = rtw_dequeue_mgmt_xframe(pxmitpriv); + if (pxmitframe) { + rtw_dump_xframe(padapter, pxmitframe); + return _TRUE; + } +#endif /* check xmitbuffer is ok */ if (pxmitbuf == NULL) { @@ -711,7 +716,7 @@ agg_end: (pfirstframe->attrib.ether_type != 0x888e) && (pfirstframe->attrib.ether_type != 0x88b4) && (pfirstframe->attrib.dhcp_pkt != 1)) - rtw_issue_addbareq_cmd(padapter, pfirstframe); + rtw_issue_addbareq_cmd(padapter, pfirstframe, _FALSE); #endif /* CONFIG_80211N_HT */ #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX /* 3. update first frame txdesc */ @@ -782,6 +787,14 @@ static s32 rtl8822bu_xmitframe_complete(PADAPTER padapter, struct xmit_priv *pxm phwxmits = pxmitpriv->hwxmits; hwentry = pxmitpriv->hwxmit_entry; +#ifdef CONFIG_RTW_MGMT_QUEUE + /* dump management frame directly */ + pxmitframe = rtw_dequeue_mgmt_xframe(pxmitpriv); + if (pxmitframe) { + rtw_dump_xframe(padapter, pxmitframe); + return _TRUE; + } +#endif if (pxmitbuf == NULL) { pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); @@ -963,6 +976,25 @@ s32 rtl8822bu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe) return pre_xmitframe(padapter, pxmitframe); } +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtl8822bu_hal_mgmt_xmitframe_enqueue(PADAPTER padapter, struct xmit_frame *pxmitframe) +{ + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + s32 err; + + err = rtw_mgmt_xmitframe_enqueue(padapter, pxmitframe); + if (err != _SUCCESS) { + rtw_free_xmitframe(pxmitpriv, pxmitframe); + pxmitpriv->tx_drop++; + } else { +#ifdef PLATFORM_LINUX + tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); +#endif + } + return err; +} +#endif + s32 rtl8822bu_hal_xmitframe_enqueue(PADAPTER padapter, struct xmit_frame *pxmitframe) { struct xmit_priv *pxmitpriv = &padapter->xmitpriv; diff --git a/halmac.mk b/halmac.mk index 22b5203..61f7814 100644 --- a/halmac.mk +++ b/halmac.mk @@ -5,8 +5,6 @@ # Base directory path_hm := hal/halmac -# Level 1 directory -path_hm_d1 := $(path_hm)/halmac_88xx ifeq ($(CONFIG_PCI_HCI), y) pci := y @@ -19,23 +17,30 @@ usb := y endif ifeq ($(CONFIG_RTL8822B), y) +series := 88xx ic := 8822b endif ifeq ($(CONFIG_RTL8822C), y) +series := 88xx ic := 8822c endif ifeq ($(CONFIG_RTL8821C), y) +series := 88xx ic := 8821c endif ifeq ($(CONFIG_RTL8814B), y) -v1 := _v1 +series := 88xx_v1 ic := 8814b endif -ifeq ($(v1), _v1) +ifeq ($(CONFIG_RTL8723F), y) +series := 87xx +ic := 8723f +endif +ifeq ($(series), 88xx_v1) d2all := else d2all := y @@ -44,27 +49,27 @@ endif halmac-y += $(path_hm)/halmac_api.o halmac-y += $(path_hm)/halmac_dbg.o -# Modify level 1 directory if needed -path_hm_d1 := $(path_hm_d1)$(v1) -halmac-y += $(path_hm_d1)/halmac_bb_rf_88xx$(v1).o \ - $(path_hm_d1)/halmac_cfg_wmac_88xx$(v1).o \ - $(path_hm_d1)/halmac_common_88xx$(v1).o \ - $(path_hm_d1)/halmac_efuse_88xx$(v1).o \ - $(path_hm_d1)/halmac_flash_88xx$(v1).o \ - $(path_hm_d1)/halmac_fw_88xx$(v1).o \ - $(path_hm_d1)/halmac_gpio_88xx$(v1).o \ - $(path_hm_d1)/halmac_init_88xx$(v1).o \ - $(path_hm_d1)/halmac_mimo_88xx$(v1).o -halmac-$(pci) += $(path_hm_d1)/halmac_pcie_88xx$(v1).o -halmac-$(sdio) += $(path_hm_d1)/halmac_sdio_88xx$(v1).o -halmac-$(usb) += $(path_hm_d1)/halmac_usb_88xx$(v1).o +# Level 1 directory +path_hm_d1 := $(path_hm)/halmac_$(series) +halmac-y += $(path_hm_d1)/halmac_bb_rf_$(series).o \ + $(path_hm_d1)/halmac_cfg_wmac_$(series).o \ + $(path_hm_d1)/halmac_common_$(series).o \ + $(path_hm_d1)/halmac_efuse_$(series).o \ + $(path_hm_d1)/halmac_flash_$(series).o \ + $(path_hm_d1)/halmac_fw_$(series).o \ + $(path_hm_d1)/halmac_gpio_$(series).o \ + $(path_hm_d1)/halmac_init_$(series).o \ + $(path_hm_d1)/halmac_mimo_$(series).o +halmac-$(pci) += $(path_hm_d1)/halmac_pcie_$(series).o +halmac-$(sdio) += $(path_hm_d1)/halmac_sdio_$(series).o +halmac-$(usb) += $(path_hm_d1)/halmac_usb_$(series).o # Level 2 directory path_hm_d2 := $(path_hm_d1)/halmac_$(ic) halmac-$(d2all) += $(path_hm_d2)/halmac_cfg_wmac_$(ic).o \ $(path_hm_d2)/halmac_common_$(ic).o -halmac-y += $(path_hm_d2)/halmac_gpio_$(ic).o \ +halmac-y += $(path_hm_d2)/halmac_gpio_$(ic).o \ $(path_hm_d2)/halmac_init_$(ic).o \ $(path_hm_d2)/halmac_phy_$(ic).o \ $(path_hm_d2)/halmac_pwr_seq_$(ic).o diff --git a/include/Hal8188FPhyCfg.h b/include/Hal8188FPhyCfg.h index 3719dd2..1bc60dc 100644 --- a/include/Hal8188FPhyCfg.h +++ b/include/Hal8188FPhyCfg.h @@ -97,6 +97,8 @@ PHY_SetTxPowerLevel8188F( u8 channel ); +void rtl8188f_set_txpwr_done(_adapter *adapter); + void PHY_SetSwChnlBWMode8188F( PADAPTER Adapter, diff --git a/include/HalVerDef.h b/include/HalVerDef.h index 4067119..d4e4067 100644 --- a/include/HalVerDef.h +++ b/include/HalVerDef.h @@ -41,6 +41,7 @@ typedef enum tag_HAL_IC_Type_Definition { CHIP_8188GTV = 18, CHIP_8822C = 19, CHIP_8814B = 20, + CHIP_8723F = 21, } HAL_IC_TYPE_E; /* HAL_CHIP_TYPE_E */ @@ -130,6 +131,7 @@ typedef struct tag_HAL_VERSION { #define IS_8710B_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8710B) ? TRUE : FALSE) #define IS_8822C_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8822C) ? TRUE : FALSE) #define IS_8814B_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8814B) ? TRUE : FALSE) +#define IS_8723F_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8723F) ? TRUE : FALSE) #define IS_8192F_SERIES(version)\ ((GET_CVID_IC_TYPE(version) == CHIP_8192F) ? TRUE : FALSE) diff --git a/include/autoconf.h b/include/autoconf.h index 8f69647..584491b 100644 --- a/include/autoconf.h +++ b/include/autoconf.h @@ -127,7 +127,6 @@ /*#endif*/ /* CONFIG_MP_INCLUDED */ -#define CONFIG_AP_MODE 1 #ifdef CONFIG_AP_MODE /* #define CONFIG_INTERRUPT_BASED_TXBCN */ /* Tx Beacon when driver BCN_OK ,BCN_ERR interrupt occurs */ #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_INTERRUPT_BASED_TXBCN) @@ -145,7 +144,6 @@ #define CONFIG_FIND_BEST_CHANNEL 1 #endif -#define CONFIG_P2P 1 #ifdef CONFIG_P2P /* The CONFIG_WFD is for supporting the Wi-Fi display */ #define CONFIG_WFD @@ -190,8 +188,6 @@ /*#define CONFIG_RTW_80211K*/ -#define CONFIG_LAYER2_ROAMING -#define CONFIG_LAYER2_ROAMING_RESUME /*#define CONFIG_ADAPTOR_INFO_CACHING_FILE */ /* now just applied on 8192cu only, should make it general... */ /*#define CONFIG_RESUME_IN_WORKQUEUE */ /*#define CONFIG_SET_SCAN_DENY_TIMER */ @@ -202,7 +198,7 @@ /* #define CONFIG_BACKGROUND_NOISE_MONITOR */ #endif #define RTW_NOTCH_FILTER 0 /* 0:Disable, 1:Enable, */ - +#define RTW_FORCE_CTS_TO_SELF_UNDER_LOW_RSSI /* * Interface Related Config diff --git a/include/cmn_info/rtw_sta_info.h b/include/cmn_info/rtw_sta_info.h index eddb8ef..d4de0e5 100644 --- a/include/cmn_info/rtw_sta_info.h +++ b/include/cmn_info/rtw_sta_info.h @@ -85,6 +85,14 @@ enum rf_type { RF_3T3R = 5, RF_3T4R = 6, RF_4T4R = 7, + RF_4T3R = 8, + RF_4T2R = 9, + RF_4T1R = 10, + RF_3T2R = 11, + RF_3T1R = 12, + RF_2T1R = 13, + RF_1T4R = 14, + RF_1T3R = 15, RF_TYPE_MAX, }; @@ -191,6 +199,7 @@ struct ra_sta_info { struct dtp_info { u8 dyn_tx_power; /*Dynamic Tx power offset*/ u8 last_tx_power; + boolean sta_is_alive; u8 sta_tx_high_power_lvl:4; u8 sta_last_dtp_lvl:4; }; @@ -248,6 +257,7 @@ struct phydm_phyinfo_struct { u8 cnt_pw2cca; u8 cnt_cca2agc_rdy; /*ODM_PHY_STATUS_NEW_TYPE_SUPPORT*/ + u8 rx_cck_evm; }; struct phydm_perpkt_info_struct { diff --git a/include/drv_conf.h b/include/drv_conf.h old mode 100755 new mode 100644 index e2d0474..d7cbeaf --- a/include/drv_conf.h +++ b/include/drv_conf.h @@ -18,6 +18,15 @@ #include "hal_ic_cfg.h" #define CONFIG_RSSI_PRIORITY + +/* + * RTW_BUSY_DENY_SCAN control if scan would be denied by busy traffic. + * When this defined, BUSY_TRAFFIC_SCAN_DENY_PERIOD would be used to judge if + * scan request coming from scan UI. Scan request from scan UI would be + * exception and never be denied by busy traffic. + */ +#define RTW_BUSY_DENY_SCAN + #ifdef CONFIG_RTW_REPEATER_SON #ifndef CONFIG_AP #define CONFIG_AP @@ -32,9 +41,10 @@ #define CONFIG_RTW_REPEATER_SON_ID 0x02040608 #endif //#define CONFIG_RTW_REPEATER_SON_ROOT - #ifndef CONFIG_RTW_REPEATER_SON_ROOT - #define CONFIG_LAYER2_ROAMING_ACTIVE - #endif + #ifndef CONFIG_RTW_REPEATER_SON_ROOT + #undef CONFIG_ROAMING_FLAG + #define CONFIG_ROAMING_FLAG 0x7 + #endif #undef CONFIG_POWER_SAVING #endif @@ -62,15 +72,87 @@ #endif -/* Older Android kernel doesn't has CONFIG_ANDROID defined, - * add this to force CONFIG_ANDROID defined */ -#ifdef CONFIG_PLATFORM_ANDROID - #ifndef CONFIG_ANDROID - #define CONFIG_ANDROID - #endif +#ifdef CONFIG_LAYER2_ROAMING +/*#define CONFIG_RTW_ROAM_QUICKSCAN */ /* active_roaming is required. i.e CONFIG_ROAMING_FLAG[bit2] MUST be enabled */ +/*#define CONFIG_RTW_ROAM_QUICKSCAN_TH 60*/ #endif -#ifdef CONFIG_ANDROID +/* Default enable single wiphy if driver ver >= 5.9 */ +#define RTW_SINGLE_WIPHY + +#ifdef CONFIG_RTW_ANDROID + + #include + + #ifndef CONFIG_IOCTL_CFG80211 + #define CONFIG_IOCTL_CFG80211 + #endif + + #ifndef RTW_USE_CFG80211_STA_EVENT + #define RTW_USE_CFG80211_STA_EVENT + #endif + + #if (CONFIG_RTW_ANDROID > 4) + #ifndef CONFIG_RADIO_WORK + #define CONFIG_RADIO_WORK + #endif + #endif + + #if (CONFIG_RTW_ANDROID <= 7) + #ifdef RTW_SINGLE_WIPHY + #undef RTW_SINGLE_WIPHY + #endif + #endif + + #if (CONFIG_RTW_ANDROID >= 8) + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + #ifndef CONFIG_RTW_WIFI_HAL + #define CONFIG_RTW_WIFI_HAL + #endif + #else + #error "Linux kernel version is too old\n" + #endif + #endif + + #ifdef CONFIG_RTW_WIFI_HAL + #ifndef CONFIG_RTW_WIFI_HAL_DEBUG + //#define CONFIG_RTW_WIFI_HAL_DEBUG + #endif + #ifndef CONFIG_RTW_CFGVENDOR_LLSTATS + #define CONFIG_RTW_CFGVENDOR_LLSTATS + #endif + #if (CONFIG_RTW_ANDROID < 11) + #ifndef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI + #define CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI + #endif + #else + #ifndef CONFIG_RTW_SCAN_RAND + #define CONFIG_RTW_SCAN_RAND + #endif + #endif + #ifndef CONFIG_RTW_CFGVENDOR_RSSIMONITOR + #define CONFIG_RTW_CFGVENDOR_RSSIMONITOR + #endif + #ifndef CONFIG_RTW_CFGVENDOR_WIFI_LOGGER + #define CONFIG_RTW_CFGVENDOR_WIFI_LOGGER + #endif + #if (CONFIG_RTW_ANDROID >= 10) + #ifndef CONFIG_RTW_CFGVENDOR_WIFI_OFFLOAD + //#define CONFIG_RTW_CFGVENDOR_WIFI_OFFLOAD + #endif + #ifndef CONFIG_RTW_HOSTAPD_ACS + #define CONFIG_RTW_HOSTAPD_ACS + #endif + #ifndef CONFIG_KERNEL_PATCH_EXTERNAL_AUTH + #define CONFIG_KERNEL_PATCH_EXTERNAL_AUTH + #endif + #ifndef CONFIG_RTW_ABORT_SCAN + #define CONFIG_RTW_ABORT_SCAN + #endif + #endif + #endif // CONFIG_RTW_WIFI_HAL + + /* Some Android build will restart the UI while non-printable ascii is passed * between java and c/c++ layer (JNI). We force CONFIG_VALIDATE_SSID * for Android here. If you are sure there is no risk on your system about this, @@ -79,7 +161,7 @@ /* Android expect dbm as the rx signal strength unit */ #define CONFIG_SIGNAL_DISPLAY_DBM -#endif +#endif // CONFIG_RTW_ANDROID /* #if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CONFIG_RESUME_IN_WORKQUEUE) @@ -111,7 +193,7 @@ #endif #ifdef CONFIG_WIFI_MONITOR - #define CONFIG_MONITOR_MODE_XMIT + /* #define CONFIG_MONITOR_MODE_XMIT */ #endif #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL @@ -132,9 +214,47 @@ #endif #endif +#ifndef CONFIG_RTW_DATA_BMC_TO_UC +#define CONFIG_RTW_DATA_BMC_TO_UC 0 +#endif + #ifdef CONFIG_AP_MODE #define CONFIG_LIMITED_AP_NUM 1 - #define CONFIG_TX_MCAST2UNI /* AP mode support IP multicast->unicast */ + + #ifndef CONFIG_RTW_AP_DATA_BMC_TO_UC + #define CONFIG_RTW_AP_DATA_BMC_TO_UC 1 + #endif + #if CONFIG_RTW_AP_DATA_BMC_TO_UC + #undef CONFIG_RTW_DATA_BMC_TO_UC + #define CONFIG_RTW_DATA_BMC_TO_UC 1 + #endif + #ifndef CONFIG_RTW_AP_SRC_B2U_FLAGS + #define CONFIG_RTW_AP_SRC_B2U_FLAGS 0x8 /* see RTW_AP_B2U_XXX */ + #endif + #ifndef CONFIG_RTW_AP_FWD_B2U_FLAGS + #define CONFIG_RTW_AP_FWD_B2U_FLAGS 0x8 /* see RTW_AP_B2U_XXX */ + #endif +#endif + +#ifdef CONFIG_RTW_MULTI_AP + #ifndef CONFIG_AP_MODE + #error "enable CONFIG_RTW_MULTI_AP without CONFIG_AP_MODE" + #endif + #ifndef CONFIG_RTW_WDS + #define CONFIG_RTW_WDS + #endif + #ifndef CONFIG_RTW_UNASOC_STA_MODE_OF_STYPE + #define CONFIG_RTW_UNASOC_STA_MODE_OF_STYPE {2, 1} /* BMC:2 for all, NMY_UC:1 for interested target */ + #endif + #ifndef CONFIG_RTW_NLRTW + #define CONFIG_RTW_NLRTW + #endif + #ifndef CONFIG_RTW_WNM + #define CONFIG_RTW_WNM + #endif + #ifndef CONFIG_RTW_80211K + #define CONFIG_RTW_80211K + #endif #endif #ifdef CONFIG_RTW_MESH @@ -169,6 +289,16 @@ #ifndef CONFIG_RTW_MESH_DATA_BMC_TO_UC #define CONFIG_RTW_MESH_DATA_BMC_TO_UC 1 #endif + #if CONFIG_RTW_MESH_DATA_BMC_TO_UC + #undef CONFIG_RTW_DATA_BMC_TO_UC + #define CONFIG_RTW_DATA_BMC_TO_UC 1 + #endif + #ifndef CONFIG_RTW_MSRC_B2U_FLAGS + #define CONFIG_RTW_MSRC_B2U_FLAGS 0x0 /* see RTW_MESH_B2U_XXX */ + #endif + #ifndef CONFIG_RTW_MFWD_B2U_FLAGS + #define CONFIG_RTW_MFWD_B2U_FLAGS 0x2 /* see RTW_MESH_B2U_XXX */ + #endif #endif #if !defined(CONFIG_SCAN_BACKOP) && defined(CONFIG_AP_MODE) @@ -177,7 +307,6 @@ #define RTW_SCAN_SPARSE_MIRACAST 1 #define RTW_SCAN_SPARSE_BG 0 -#define RTW_SCAN_SPARSE_ROAMING_ACTIVE 1 #ifndef CONFIG_TX_AC_LIFETIME #define CONFIG_TX_AC_LIFETIME 1 @@ -222,7 +351,7 @@ #ifndef CONFIG_IEEE80211_BAND_5GHZ #if defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8821C) \ || defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8822C) \ - || defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8814B) + || defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8814B) || defined(CONFIG_RTL8723F) #define CONFIG_IEEE80211_BAND_5GHZ 1 #else #define CONFIG_IEEE80211_BAND_5GHZ 0 @@ -280,6 +409,9 @@ #endif #if RTW_DEF_MODULE_REGULATORY_CERT + #ifdef CONFIG_REGD_SRC_FROM_OS + #error "CONFIG_REGD_SRC_FROM_OS is not supported when enable RTW_DEF_MODULE_REGULATORY_CERT" + #endif /* force enable TX power by rate and TX power limit */ #undef CONFIG_TXPWR_BY_RATE_EN #undef CONFIG_TXPWR_LIMIT_EN @@ -292,16 +424,35 @@ #define CONFIG_TXPWR_LIMIT 1 #endif +#ifndef CONFIG_RTW_REGD_SRC +#define CONFIG_RTW_REGD_SRC 1 /* 0:RTK_PRIV, 1:OS */ +#endif + +#define CONFIG_IOCTL_WEXT + #ifdef CONFIG_RTW_IPCAM_APPLICATION #undef CONFIG_TXPWR_BY_RATE_EN #define CONFIG_TXPWR_BY_RATE_EN 1 #define CONFIG_RTW_CUSTOMIZE_BEEDCA 0x0000431C #define CONFIG_RTW_CUSTOMIZE_BWMODE 0x00 #define CONFIG_RTW_CUSTOMIZE_RLSTA 0x30 + #define CONFIG_CHECK_SPECIFIC_IE_CONTENT + #ifdef CONFIG_CUSTOMER_EZVIZ_CHIME2 + #undef CONFIG_ACTIVE_KEEP_ALIVE_CHECK + #endif #if defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8822B) #define CONFIG_RTW_TX_NPATH_EN /* mutually incompatible with STBC_TX & Beamformer */ #endif #endif +/* #define CONFIG_RTW_TOKEN_BASED_XMIT */ +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + #define NR_TBTX_SLOT 4 + #define NR_MAXSTA_INSLOT 5 + #define TBTX_TX_DURATION 30 + + #define MAX_TXPAUSE_DURATION (TBTX_TX_DURATION*NR_TBTX_SLOT) +#endif + /*#define CONFIG_EXTEND_LOWRATE_TXOP */ #ifndef CONFIG_RTW_RX_AMPDU_SZ_LIMIT_1SS @@ -349,6 +500,10 @@ #define CONFIG_RTW_TARGET_TX_PWR_5G_D {-1, -1, -1, -1, -1, -1, -1, -1, -1} #endif +#ifndef CONFIG_RTW_ANTENNA_GAIN +#define CONFIG_RTW_ANTENNA_GAIN 0x7FFF /* == UNSPECIFIED_MBM */ +#endif + #ifndef CONFIG_RTW_AMPLIFIER_TYPE_2G #define CONFIG_RTW_AMPLIFIER_TYPE_2G 0 #endif @@ -392,7 +547,8 @@ defined(CONFIG_RTL8188GTV) || defined(CONFIG_RTL8192F) || \ defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8710B) || \ defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) #define CONFIG_HWMPCAP_GEN1 -#elif defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) /*|| defined(CONFIG_RTL8814A)*/ +#elif defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || \ +defined(CONFIG_RTL8723F) /*|| defined(CONFIG_RTL8814A)*/ #define CONFIG_HWMPCAP_GEN2 #elif defined(CONFIG_RTL8814B) /*Address CAM - 128*/ #define CONFIG_HWMPCAP_GEN3 @@ -422,7 +578,9 @@ defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) #endif #if (CONFIG_IFACE_NUMBER > 2) - #define CONFIG_MI_WITH_MBSSID_CAM + #ifndef CONFIG_HWMPCAP_GEN3 + #define CONFIG_MI_WITH_MBSSID_CAM + #endif #ifdef CONFIG_MI_WITH_MBSSID_CAM #define CONFIG_MBSSID_CAM @@ -451,6 +609,17 @@ defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) #endif #endif /*CONFIG_HWMPCAP_GEN2*/ + + #ifdef CONFIG_HWMPCAP_GEN3 + #define CONFIG_PORT_BASED_TXBCN + #undef CONFIG_SUPPORT_MULTI_BCN + #undef CONFIG_SWTIMER_BASED_TXBCN + #undef CONFIG_LIMITED_AP_NUM + #define CONFIG_LIMITED_AP_NUM 4 + #ifdef CONFIG_PCI_HCI + #define CONFIG_PORT_BASED_HIQ /* 8814BU doesn't support */ + #endif + #endif #endif /*CONFIG_AP_MODE*/ #ifdef CONFIG_HWMPCAP_GEN2 /*CONFIG_RTL8822B/CONFIG_RTL8821C/CONFIG_RTL8822C*/ @@ -459,9 +628,24 @@ defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) #endif/*CONFIG_HWMPCAP_GEN2*/ #endif/*(CONFIG_IFACE_NUMBER > 2)*/ +#if defined(CONFIG_MI_UNIQUE_MACADDR_BIT) + #if !defined(CONFIG_MI_WITH_MBSSID_CAM) + #error "CONFIG_MI_UNIQUE_MACADDR_BIT should not be used without multiple interface !!" + #endif + #if (CONFIG_MI_UNIQUE_MACADDR_BIT < 24) || ( 47 < CONFIG_MI_UNIQUE_MACADDR_BIT) + #error "CONFIG_MI_UNIQUE_MACADDR_BIT should be the bit in NIC specific mac address(BIT[24:47] !!" + #endif +#endif + #define MACID_NUM_SW_LIMIT 32 #define SEC_CAM_ENT_NUM_SW_LIMIT 32 +#ifdef SEC_DEFAULT_KEY_SEARCH + #if (CONFIG_IFACE_NUMBER >= 2) + #error "Default Key Search only work with only one interface case!" + #endif +#endif + #if defined(CONFIG_WOWLAN) && (defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)) #define CONFIG_WOW_PATTERN_HW_CAM #endif @@ -500,20 +684,8 @@ defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) #endif /* CONFIG_SDIO_HCI || CONFIG_USB_RX_AGGREGATION */ #ifdef CONFIG_RTW_HOSTAPD_ACS - #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A) - #ifndef CONFIG_FIND_BEST_CHANNEL - #define CONFIG_FIND_BEST_CHANNEL - #endif - #else - #ifdef CONFIG_FIND_BEST_CHANNEL - #undef CONFIG_FIND_BEST_CHANNEL - #endif - #ifndef CONFIG_RTW_ACS - #define CONFIG_RTW_ACS - #endif - #ifndef CONFIG_BACKGROUND_NOISE_MONITOR - #define CONFIG_BACKGROUND_NOISE_MONITOR - #endif + #ifndef CONFIG_RTW_ACS + #define CONFIG_RTW_ACS #endif #endif @@ -593,12 +765,31 @@ defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) #endif #endif +#ifdef CONFIG_WAR_OFFLOAD +#ifndef CONFIG_WOWLAN + #error "WAR OFFLOAD is part of WOWLAN" +#endif +#endif + +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) +#ifndef CONFIG_WOWLAN + #error "mDNS OFFLOAD is part of WOWLAN" +#endif +#ifndef CONFIG_WAR_OFFLOAD + #define CONFIG_WAR_OFFLOAD +#endif +#endif + #define CONFIG_RTW_TPT_MODE #ifdef CONFIG_PCI_BCN_POLLING #define CONFIG_BCN_ICF #endif +#ifndef CONFIG_RTW_MGMT_QUEUE + #define CONFIG_RTW_MGMT_QUEUE +#endif + #ifndef CONFIG_PCI_MSI #define CONFIG_RTW_PCI_MSI_DISABLE #endif diff --git a/include/drv_types.h b/include/drv_types.h index 45a4c16..3165914 100644 --- a/include/drv_types.h +++ b/include/drv_types.h @@ -92,6 +92,15 @@ typedef struct _ADAPTER _adapter, ADAPTER, *PADAPTER; #include "../hal/hal_dm.h" #include #include +#ifdef CONFIG_RTW_80211R +#include +#endif +#if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) +#include +#endif +#ifdef CONFIG_RTW_MBO +#include +#endif #include #include #include @@ -105,9 +114,15 @@ typedef struct _ADAPTER _adapter, ADAPTER, *PADAPTER; #include #include #include +#ifdef CONFIG_RTW_WDS +#include "../core/wds/rtw_wds.h" +#endif #ifdef CONFIG_RTW_MESH #include "../core/mesh/rtw_mesh.h" #endif +#ifdef CONFIG_WIFI_MONITOR +#include "../core/monitor/rtw_radiotap.h" +#endif #include #include #include @@ -156,6 +171,8 @@ typedef struct _ADAPTER _adapter, ADAPTER, *PADAPTER; #include #endif /*CONFIG_RTW_REPEATER_SON */ +#include + #define SPEC_DEV_ID_NONE BIT(0) #define SPEC_DEV_ID_DISABLE_HT BIT(1) #define SPEC_DEV_ID_ENABLE_PS BIT(2) @@ -248,7 +265,19 @@ struct registry_priv { u8 tx_bw_mode; #ifdef CONFIG_AP_MODE u8 bmc_tx_rate; + #if CONFIG_RTW_AP_DATA_BMC_TO_UC + u8 ap_src_b2u_flags; + u8 ap_fwd_b2u_flags; + #endif #endif + +#ifdef CONFIG_RTW_MESH + #if CONFIG_RTW_MESH_DATA_BMC_TO_UC + u8 msrc_b2u_flags; + u8 mfwd_b2u_flags; + #endif +#endif + #ifdef CONFIG_80211N_HT u8 ht_enable; /* 0: 20 MHz, 1: 40 MHz, 2: 80 MHz, 3: 160MHz */ @@ -259,6 +288,7 @@ struct registry_priv { u8 rx_stbc; u8 rx_ampdu_amsdu;/* Rx A-MPDU Supports A-MSDU is permitted */ u8 tx_ampdu_amsdu;/* Tx A-MPDU Supports A-MSDU is permitted */ + u8 tx_quick_addba_req; u8 rx_ampdu_sz_limit_by_nss_bw[4][4]; /* 1~4SS, BW20~BW160 */ /* Short GI support Bit Map */ /* BIT0 - 20MHz, 1: support, 0: non-support */ @@ -291,20 +321,24 @@ struct registry_priv { #ifdef CONFIG_80211AC_VHT u8 vht_enable; /* 0:disable, 1:enable, 2:auto */ + u8 vht_24g_enable; /* 0:disable, 1:enable */ u8 ampdu_factor; u8 vht_rx_mcs_map[2]; #endif /* CONFIG_80211AC_VHT */ - u8 lowrate_two_xmit; - u8 low_power ; u8 wifi_spec;/* !turbo_mode */ - u8 rf_path; /*rf_config*/ + u8 trx_path_bmp; /* [7:4]TX path bmp, [0:3]RX path bmp, 0: not specified */ + u8 tx_path_lmt; /* limit of TX path number, 0: not specified */ + u8 rx_path_lmt; /* limit of TX path number, 0: not specified */ u8 tx_nss; u8 rx_nss; +#ifdef CONFIG_REGD_SRC_FROM_OS + enum regd_src_t regd_src; +#endif char alpha2[2]; u8 channel_plan; u8 excl_chs[MAX_CHANNEL_NUM]; @@ -367,6 +401,7 @@ struct registry_priv { #if CONFIG_IEEE80211_BAND_5GHZ s8 target_tx_pwr_5g[RF_PATH_MAX][RATE_SECTION_NUM - 1]; #endif + s16 antenna_gain; u8 tsf_update_pause_factor; u8 tsf_update_restore_factor; @@ -419,7 +454,7 @@ struct registry_priv { #ifdef CONFIG_DFS_MASTER u8 dfs_region_domain; #endif - + u8 amsdu_mode; #ifdef CONFIG_MCC_MODE u8 en_mcc; u32 rtw_mcc_single_tx_cri; @@ -446,10 +481,13 @@ struct registry_priv { #endif /* CONFIG_RTW_NAPI */ #ifdef CONFIG_WOWLAN + u8 wowlan_enable; u8 wakeup_event; u8 suspend_type; #endif + u8 recvbuf_nr; + #ifdef CONFIG_SUPPORT_TRX_SHARED u8 trx_share_mode; #endif @@ -496,16 +534,31 @@ struct registry_priv { u8 tdmadig_mode; u8 tdmadig_dynamic; #endif/*CONFIG_TDMADIG*/ + u8 en_dyn_rrsr; + u32 set_rrsr_value; #ifdef CONFIG_RTW_MESH u8 peer_alive_based_preq; #endif +#ifdef RTW_BUSY_DENY_SCAN /* - * vht_2g4: use VHT rate on 2.4G or not - * 0: deny - * 1: allow + * scan_interval_thr means scan interval threshold which is used to + * judge if user is in scan page or not. + * If scan interval < scan_interval_thr we guess user is in scan page, + * and driver won't deny any scan request at that time. + * Its default value comes from compiler flag + * BUSY_TRAFFIC_SCAN_DENY_PERIOD, and unit is ms. */ - u8 vht_2g4; + u32 scan_interval_thr; +#endif + +#ifdef CONFIG_RTL8822C_XCAP_NEW_POLICY + u8 rtw_8822c_xcap_overwrite; +#endif +#ifdef CONFIG_RTW_MULTI_AP + u8 unassoc_sta_mode_of_stype[UNASOC_STA_SRC_NUM]; + u16 max_unassoc_sta_cnt; +#endif }; /* For registry parameters */ @@ -539,12 +592,21 @@ struct registry_priv { #define REGSTY_IS_BW_2G_SUPPORT(regsty, bw) (REGSTY_BW_2G((regsty)) >= (bw)) #define REGSTY_IS_BW_5G_SUPPORT(regsty, bw) (REGSTY_BW_5G((regsty)) >= (bw)) +#ifdef CONFIG_80211AC_VHT #define REGSTY_IS_11AC_ENABLE(regsty) ((regsty)->vht_enable != 0) #define REGSTY_IS_11AC_AUTO(regsty) ((regsty)->vht_enable == 2) +#define REGSTY_IS_11AC_24G_ENABLE(regsty) ((regsty)->vht_24g_enable != 0) +#else +#define REGSTY_IS_11AC_ENABLE(regsty) 0 +#define REGSTY_IS_11AC_AUTO(regsty) 0 +#define REGSTY_IS_11AC_24G_ENABLE(regsty) 0 +#endif -#define rtw_is_vht_2g4(adapter) ((adapter)->registrypriv.vht_2g4 != 0) -#define rtw_set_vht_2g4(adapter, enable) \ - ((adapter)->registrypriv.vht_2g4 = (enable ? 1 : 0)) +#ifdef CONFIG_REGD_SRC_FROM_OS +#define REGSTY_REGD_SRC_FROM_OS(regsty) ((regsty)->regd_src == REGD_SRC_OS) +#else +#define REGSTY_REGD_SRC_FROM_OS(regsty) 0 +#endif typedef struct rtw_if_operations { int __must_check (*read)(struct dvobj_priv *d, unsigned int addr, void *buf, @@ -623,6 +685,7 @@ struct rx_logs { u32 core_rx_post_decrypt_tkip; u32 core_rx_post_decrypt_aes; u32 core_rx_post_decrypt_wapi; + u32 core_rx_post_decrypt_gcmp; u32 core_rx_post_decrypt_hw; u32 core_rx_post_decrypt_unknown; u32 core_rx_post_decrypt_err; @@ -773,10 +836,12 @@ struct rtw_traffic_statistics { }; #define SEC_CAP_CHK_BMC BIT0 +#define SEC_CAP_CHK_EXTRA_SEC BIT1 /* 256 bit */ +#define SEC_CAP_CHK_WRITE_CAM_NEW_RULE BIT2 + #define MACID_DROP BIT0 #define MACID_DROP_INDIRECT BIT1 - #define SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH BIT0 struct sec_cam_bmp { @@ -857,7 +922,6 @@ struct macid_ctl_t { u8 op_num[H2C_MSR_ROLE_MAX]; /* number of macid having h2c_msr's OPMODE = 1 for specific ROLE */ struct sta_info *sta[MACID_NUM_SW_LIMIT]; /* corresponding stainfo when macid is not shared */ - u8 macid_cap; /* macid sleep registers */ #ifdef CONFIG_PROTSEL_MACSLEEP @@ -938,12 +1002,34 @@ struct macid_ctl_t { #define OFFCHS_LEAVE_OP 2 #define OFFCHS_BACKING_OP 3 +#define TPC_MODE_DISABLE 0 +#define TPC_MODE_MANUAL 1 +#define TPC_MODE_INVALID 2 /* keep last */ + +#define TPC_MANUAL_CONSTRAINT_MAX 600 /* mB */ + struct rf_ctl_t { + enum regd_src_t regd_src; const struct country_chplan *country_ent; u8 ChannelPlan; u8 max_chan_nums; RT_CHANNEL_INFO channel_set[MAX_CHANNEL_NUM]; + struct op_class_pref_t **spt_op_class_ch; + u8 cap_spt_op_class_num; + u8 reg_spt_op_class_num; + u8 cur_spt_op_class_num; struct p2p_channels channel_list; +#ifdef CONFIG_RTW_MBO + struct npref_ch_rtp ch_rtp; +#endif + + s16 antenna_gain; /* mBi */ + + u8 op_class; + u8 op_ch; + s16 op_txpwr_max; /* EIRP in mBm */ + u8 if_op_class[CONFIG_IFACE_NUMBER]; + u8 if_op_ch[CONFIG_IFACE_NUMBER]; _mutex offch_mutex; u8 offch_state; @@ -970,11 +1056,18 @@ struct rf_ctl_t { u8 txpwr_lmt_5g_20_40_ref; #endif #endif + u8 tpc_mode; + u16 tpc_manual_constraint; /* mB */ bool ch_sel_within_same_band; #if CONFIG_DFS u8 csa_ch; + u8 csa_switch_cnt; + u8 csa_ch_offset; + u8 csa_ch_width; + u8 csa_ch_freq_seg0; /* Channel Center Frequency Segment 0 */ + u8 csa_ch_freq_seg1; /* Channel Center Frequency Segment 1 */ #ifdef CONFIG_DFS_MASTER u8 dfs_region_domain; @@ -994,6 +1087,7 @@ struct rf_ctl_t { #if CONFIG_DFS_SLAVE_WITH_RADAR_DETECT u8 dfs_slave_with_rd; #endif + u8 dfs_ch_sel_e_flags; u8 dfs_ch_sel_d_flags; u8 dbg_dfs_fake_radar_detect_cnt; @@ -1003,6 +1097,13 @@ struct rf_ctl_t { #endif /* CONFIG_DFS */ }; +struct wow_ctl_t { + u8 wow_cap; +}; + +#define WOW_CAP_TKIP_OL BIT0 +#define WOW_CAP_HALMAC_ACCESS_PATTERN_IN_TXFIFO BIT1 + #define RTW_CAC_STOPPED 0 #ifdef CONFIG_DFS_MASTER #define IS_CAC_STOPPED(rfctl) ((rfctl)->cac_end_time == RTW_CAC_STOPPED) @@ -1048,6 +1149,13 @@ struct halmac_indicator { struct halmacpriv { /* flags */ +#ifdef CONFIG_SDIO_HCI + /* + * Indirect Access for SDIO, + * 0:default, 1:enable, 2:disable + */ + u8 sdio_io_indir; +#endif /* CONFIG_SDIO_HCI */ /* For asynchronous functions */ struct halmac_indicator *indicator; @@ -1133,6 +1241,14 @@ struct dvobj_priv { unsigned char oper_ch_offset;/* PRIME_CHNL_OFFSET */ systime on_oper_ch_time; + u8 union_ch; + u8 union_bw; + u8 union_offset; + /* backup values when union_ch is set to 0 */ + u8 union_ch_bak; + u8 union_bw_bak; + u8 union_offset_bak; + _adapter *padapters[CONFIG_IFACE_NUMBER];/*IFACE_ID_MAX*/ u8 iface_nums; /* total number of ifaces used runtime */ struct mi_state iface_state; @@ -1164,6 +1280,8 @@ struct dvobj_priv { struct cam_ctl_t cam_ctl; struct sec_cam_ent cam_cache[SEC_CAM_ENT_NUM_SW_LIMIT]; + + struct wow_ctl_t wow_ctl; #ifdef CONFIG_MBSSID_CAM struct mbid_cam_ctl_t mbid_cam_ctl; @@ -1235,6 +1353,11 @@ struct dvobj_priv { INTF_OPS intf_ops; #endif +#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT + u8 tx_aval_int_thr_mode;/* if 0=>threhold set by reques(default) ;if 1=>fixed by proc; if 2: fixed by sdio_tx_max_len */ + u8 tx_aval_int_thr_value; +#endif/*CONFIG_SDIO_TX_ENABLE_AVAL_INT*/ + /*-------- below is for USB INTERFACE --------*/ #ifdef CONFIG_USB_HCI @@ -1284,7 +1407,7 @@ struct dvobj_priv { /* PCI IO map */ unsigned long pci_base_addr; /* device I/O address */ -#ifdef RTK_129X_PLATFORM +#ifdef CONFIG_PLATFORM_RTK129X unsigned long ctrl_start; /* PCI MASK addr */ unsigned long mask_addr; @@ -1331,6 +1454,17 @@ struct dvobj_priv { #ifdef CONFIG_PROTSEL_MACSLEEP struct protsel protsel_macsleep; #endif +#ifdef CONFIG_WOWLAN + u8 bcn_ctrl_clint3_bf_suspend; + u16 rxfltmap2_bf_suspend; + u8 lifetime_en; + u32 pkt_lifetime; + u32 rcr_bf_suspend; + u32 cr_ext_bf_suspend; +#endif /* CONFIG_WOWLAN */ +#if defined (CONFIG_CONCURRENT_MODE) && defined (CONFIG_TSF_SYNC) + u16 sync_tsfr_counter; +#endif }; #define DEV_STA_NUM(_dvobj) MSTATE_STA_NUM(&((_dvobj)->iface_state)) @@ -1351,9 +1485,10 @@ struct dvobj_priv { #define DEV_WPS_NUM(_dvobj) MSTATE_WPS_NUM(&((_dvobj)->iface_state)) #define DEV_ROCH_NUM(_dvobj) MSTATE_ROCH_NUM(&((_dvobj)->iface_state)) #define DEV_MGMT_TX_NUM(_dvobj) MSTATE_MGMT_TX_NUM(&((_dvobj)->iface_state)) -#define DEV_U_CH(_dvobj) MSTATE_U_CH(&((_dvobj)->iface_state)) -#define DEV_U_BW(_dvobj) MSTATE_U_BW(&((_dvobj)->iface_state)) -#define DEV_U_OFFSET(_dvobj) MSTATE_U_OFFSET(&((_dvobj)->iface_state)) + +#define DEV_U_CH(_dvobj) ((_dvobj)->union_ch) +#define DEV_U_BW(_dvobj) ((_dvobj)->union_bw) +#define DEV_U_OFFSET(_dvobj) ((_dvobj)->union_offset) #define dvobj_to_pwrctl(dvobj) (&(dvobj->pwrctl_priv)) #define pwrctl_to_dvobj(pwrctl) container_of(pwrctl, struct dvobj_priv, pwrctl_priv) @@ -1512,11 +1647,10 @@ struct _ADAPTER { struct hostapd_priv *phostapdpriv; #endif -#ifdef CONFIG_IOCTL_CFG80211 -#ifdef CONFIG_P2P - struct cfg80211_wifidirect_info cfg80211_wdinfo; -#endif /* CONFIG_P2P */ -#endif /* CONFIG_IOCTL_CFG80211 */ +#if defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE) || defined(CONFIG_IOCTL_CFG80211) + struct roch_info rochinfo; +#endif + u32 setband; ATOMIC_T bandskip; @@ -1584,15 +1718,6 @@ struct _ADAPTER { #ifdef PLATFORM_LINUX _nic_hdl pnetdev; char old_ifname[IFNAMSIZ]; - - /* used by rtw_rereg_nd_name related function */ - struct rereg_nd_name_data { - _nic_hdl old_pnetdev; - char old_ifname[IFNAMSIZ]; - u8 old_ips_mode; - u8 old_bRegUseLed; - } rereg_nd_name_priv; - u8 ndev_unregistering; int bup; struct net_device_stats stats; @@ -1614,6 +1739,12 @@ struct _ADAPTER { #endif /* CONFIG_IOCTL_CFG80211 */ +#ifdef CONFIG_PLATFORM_CMAP_INTFS + void *cmap_bss_status_evt; + u32 cmap_bss_status_evt_len; + u8 cmap_unassoc_sta_measure_en; +#endif + #endif /* PLATFORM_LINUX */ #ifdef PLATFORM_FREEBSD @@ -1636,9 +1767,6 @@ struct _ADAPTER { /* The driver will show the current P2P status when the upper application reads it. */ u8 bShowGetP2PState; #endif -#ifdef CONFIG_AUTOSUSPEND - u8 bDisableAutosuspend; -#endif u8 isprimary; /* is primary adapter or not */ /* notes: @@ -1677,6 +1805,10 @@ struct _ADAPTER { #endif #ifdef CONFIG_AP_MODE u8 bmc_tx_rate; + #if CONFIG_RTW_AP_DATA_BMC_TO_UC + u8 b2u_flags_ap_src; + u8 b2u_flags_ap_fwd; + #endif #endif /* for debug purpose */ @@ -1687,6 +1819,8 @@ struct _ADAPTER { u8 driver_tx_bw_mode; u8 rsvd_page_offset; u8 rsvd_page_num; + u8 ch_clm_ratio; + u8 ch_nhm_ratio; #ifdef CONFIG_SUPPORT_FIFO_DUMP u8 fifo_sel; u32 fifo_addr; @@ -1722,6 +1856,25 @@ struct _ADAPTER { struct mcc_adapter_priv mcc_adapterpriv; #endif /* CONFIG_MCC_MODE */ +#ifdef CONFIG_RTW_WDS + bool use_wds; /* for STA, AP mode */ + + /* for STA mode */ + struct rtw_wds_gptr_table *wds_gpt_records; + ATOMIC_T wds_gpt_record_num; + + /* for AP mode */ + #ifdef CONFIG_AP_MODE + struct rtw_wds_table *wds_paths; + ATOMIC_T wds_path_num; + #endif +#endif /* CONFIG_RTW_WDS */ + +#ifdef CONFIG_RTW_MULTI_AP + u8 multi_ap; + u8 ch_util_threshold; +#endif + #ifdef CONFIG_RTW_MESH struct rtw_mesh_cfg mesh_cfg; struct rtw_mesh_info mesh_info; @@ -1731,6 +1884,17 @@ struct _ADAPTER { _workitem mesh_work; unsigned long wrkq_flags; #endif /* CONFIG_RTW_MESH */ + +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + ATOMIC_T tbtx_tx_pause; + ATOMIC_T tbtx_remove_tx_pause; + u8 tbtx_capability; + u32 tbtx_duration; +#endif /* CONFIG_RTW_TOKEN_BASED_XMIT */ + +#ifdef RTW_SIMPLE_CONFIG + u8 rtw_simple_config; +#endif }; #define adapter_to_dvobj(adapter) ((adapter)->dvobj) @@ -1746,8 +1910,18 @@ struct _ADAPTER { #define adapter_to_rfctl(adapter) dvobj_to_rfctl(adapter_to_dvobj((adapter))) #define adapter_to_macidctl(adapter) dvobj_to_macidctl(adapter_to_dvobj((adapter))) +#ifdef CONFIG_RTW_WDS +#define adapter_use_wds(adapter) (adapter->use_wds) +#define adapter_set_use_wds(adapter, en) do { \ + (adapter)->use_wds = (en) ? 1 : 0; \ + RTW_INFO(FUNC_ADPT_FMT" set use_wds=%d\n", FUNC_ADPT_ARG(adapter), (adapter)->use_wds); \ + } while (0) +#else +#define adapter_use_wds(adapter) 0 +#endif + #define adapter_mac_addr(adapter) (adapter->mac_addr) -#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI +#if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND) #define adapter_pno_mac_addr(adapter) \ ((adapter_wdev_data(adapter))->pno_mac_addr) #endif diff --git a/include/hal_btcoex.h b/include/hal_btcoex.h index 40ddafb..a2e125e 100644 --- a/include/hal_btcoex.h +++ b/include/hal_btcoex.h @@ -49,6 +49,7 @@ void hal_btcoex_ConnectNotify(PADAPTER padapter, u8 action); void hal_btcoex_MediaStatusNotify(PADAPTER padapter, u8 mediaStatus); void hal_btcoex_SpecialPacketNotify(PADAPTER padapter, u8 pktType); void hal_btcoex_IQKNotify(PADAPTER padapter, u8 state); +void hal_btcoex_WLRFKNotify(PADAPTER padapter, u8 path, u8 type, u8 state); void hal_btcoex_BtInfoNotify(PADAPTER padapter, u8 length, u8 *tmpBuf); void hal_btcoex_BtMpRptNotify(PADAPTER padapter, u8 length, u8 *tmpBuf); void hal_btcoex_SuspendNotify(PADAPTER padapter, u8 state); @@ -61,6 +62,7 @@ s32 hal_btcoex_IsBTCoexRejectAMPDU(PADAPTER padapter); s32 hal_btcoex_IsBTCoexCtrlAMPDUSize(PADAPTER padapter); u32 hal_btcoex_GetAMPDUSize(PADAPTER padapter); void hal_btcoex_SetManualControl(PADAPTER padapter, u8 bmanual); +void hal_btcoex_set_policy_control(PADAPTER padapter, u8 btc_policy); u8 hal_btcoex_1Ant(PADAPTER padapter); u8 hal_btcoex_IsBtControlLps(PADAPTER); u8 hal_btcoex_IsLpsOn(PADAPTER); diff --git a/include/hal_btcoex_wifionly.h b/include/hal_btcoex_wifionly.h index d28bfce..407698b 100644 --- a/include/hal_btcoex_wifionly.h +++ b/include/hal_btcoex_wifionly.h @@ -19,14 +19,15 @@ #include /* Define the ICs that support wifi only cfg in coex. codes */ -#if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) +#if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) \ +|| defined(CONFIG_RTL8723F) #define CONFIG_BTCOEX_SUPPORT_WIFI_ONLY_CFG 1 #else #define CONFIG_BTCOEX_SUPPORT_WIFI_ONLY_CFG 0 #endif /* Define the ICs that support hal btc common file structure */ -#if defined(CONFIG_RTL8822C) || (defined(CONFIG_RTL8192F) && defined(CONFIG_BT_COEXIST)) +#if defined(CONFIG_RTL8822C) || (defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8723F)&& defined(CONFIG_BT_COEXIST)) #define CONFIG_BTCOEX_SUPPORT_BTC_CMN 1 #else #define CONFIG_BTCOEX_SUPPORT_BTC_CMN 0 diff --git a/include/hal_com.h b/include/hal_com.h index 266dc64..dcafbaf 100644 --- a/include/hal_com.h +++ b/include/hal_com.h @@ -118,6 +118,7 @@ #define DESC_RATEVHTSS4MCS7 0x51 #define DESC_RATEVHTSS4MCS8 0x52 #define DESC_RATEVHTSS4MCS9 0x53 +#define DESC_RATE_NUM 0x54 #define IS_CCK_HRATE(_rate) ((_rate) <= DESC_RATE11M) #define IS_OFDM_HRATE(_rate) ((_rate) >= DESC_RATE6M && (_rate) <= DESC_RATE54M) @@ -142,92 +143,8 @@ #define HRARE_SS_NUM(_rate) (IS_1SS_HRATE(_rate) ? 1 : (IS_2SS_HRATE(_rate) ? 2 : (IS_3SS_HRATE(_rate) ? 3 : (IS_4SS_HRATE(_rate) ? 4 : 0)))) -#define HDATA_RATE(rate)\ - (rate == DESC_RATE1M) ? "CCK_1M" :\ - (rate == DESC_RATE2M) ? "CCK_2M" :\ - (rate == DESC_RATE5_5M) ? "CCK5_5M" :\ - (rate == DESC_RATE11M) ? "CCK_11M" :\ - (rate == DESC_RATE6M) ? "OFDM_6M" :\ - (rate == DESC_RATE9M) ? "OFDM_9M" :\ - (rate == DESC_RATE12M) ? "OFDM_12M" :\ - (rate == DESC_RATE18M) ? "OFDM_18M" :\ - (rate == DESC_RATE24M) ? "OFDM_24M" :\ - (rate == DESC_RATE36M) ? "OFDM_36M" :\ - (rate == DESC_RATE48M) ? "OFDM_48M" :\ - (rate == DESC_RATE54M) ? "OFDM_54M" :\ - (rate == DESC_RATEMCS0) ? "MCS0" :\ - (rate == DESC_RATEMCS1) ? "MCS1" :\ - (rate == DESC_RATEMCS2) ? "MCS2" :\ - (rate == DESC_RATEMCS3) ? "MCS3" :\ - (rate == DESC_RATEMCS4) ? "MCS4" :\ - (rate == DESC_RATEMCS5) ? "MCS5" :\ - (rate == DESC_RATEMCS6) ? "MCS6" :\ - (rate == DESC_RATEMCS7) ? "MCS7" :\ - (rate == DESC_RATEMCS8) ? "MCS8" :\ - (rate == DESC_RATEMCS9) ? "MCS9" :\ - (rate == DESC_RATEMCS10) ? "MCS10" :\ - (rate == DESC_RATEMCS11) ? "MCS11" :\ - (rate == DESC_RATEMCS12) ? "MCS12" :\ - (rate == DESC_RATEMCS13) ? "MCS13" :\ - (rate == DESC_RATEMCS14) ? "MCS14" :\ - (rate == DESC_RATEMCS15) ? "MCS15" :\ - (rate == DESC_RATEMCS16) ? "MCS16" :\ - (rate == DESC_RATEMCS17) ? "MCS17" :\ - (rate == DESC_RATEMCS18) ? "MCS18" :\ - (rate == DESC_RATEMCS19) ? "MCS19" :\ - (rate == DESC_RATEMCS20) ? "MCS20" :\ - (rate == DESC_RATEMCS21) ? "MCS21" :\ - (rate == DESC_RATEMCS22) ? "MCS22" :\ - (rate == DESC_RATEMCS23) ? "MCS23" :\ - (rate == DESC_RATEMCS24) ? "MCS24" :\ - (rate == DESC_RATEMCS25) ? "MCS25" :\ - (rate == DESC_RATEMCS26) ? "MCS26" :\ - (rate == DESC_RATEMCS27) ? "MCS27" :\ - (rate == DESC_RATEMCS28) ? "MCS28" :\ - (rate == DESC_RATEMCS29) ? "MCS29" :\ - (rate == DESC_RATEMCS30) ? "MCS30" :\ - (rate == DESC_RATEMCS31) ? "MCS31" :\ - (rate == DESC_RATEVHTSS1MCS0) ? "VHTSS1MCS0" :\ - (rate == DESC_RATEVHTSS1MCS1) ? "VHTSS1MCS1" :\ - (rate == DESC_RATEVHTSS1MCS2) ? "VHTSS1MCS2" :\ - (rate == DESC_RATEVHTSS1MCS3) ? "VHTSS1MCS3" :\ - (rate == DESC_RATEVHTSS1MCS4) ? "VHTSS1MCS4" :\ - (rate == DESC_RATEVHTSS1MCS5) ? "VHTSS1MCS5" :\ - (rate == DESC_RATEVHTSS1MCS6) ? "VHTSS1MCS6" :\ - (rate == DESC_RATEVHTSS1MCS7) ? "VHTSS1MCS7" :\ - (rate == DESC_RATEVHTSS1MCS8) ? "VHTSS1MCS8" :\ - (rate == DESC_RATEVHTSS1MCS9) ? "VHTSS1MCS9" :\ - (rate == DESC_RATEVHTSS2MCS0) ? "VHTSS2MCS0" :\ - (rate == DESC_RATEVHTSS2MCS1) ? "VHTSS2MCS1" :\ - (rate == DESC_RATEVHTSS2MCS2) ? "VHTSS2MCS2" :\ - (rate == DESC_RATEVHTSS2MCS3) ? "VHTSS2MCS3" :\ - (rate == DESC_RATEVHTSS2MCS4) ? "VHTSS2MCS4" :\ - (rate == DESC_RATEVHTSS2MCS5) ? "VHTSS2MCS5" :\ - (rate == DESC_RATEVHTSS2MCS6) ? "VHTSS2MCS6" :\ - (rate == DESC_RATEVHTSS2MCS7) ? "VHTSS2MCS7" :\ - (rate == DESC_RATEVHTSS2MCS8) ? "VHTSS2MCS8" :\ - (rate == DESC_RATEVHTSS2MCS9) ? "VHTSS2MCS9" :\ - (rate == DESC_RATEVHTSS3MCS0) ? "VHTSS3MCS0" :\ - (rate == DESC_RATEVHTSS3MCS1) ? "VHTSS3MCS1" :\ - (rate == DESC_RATEVHTSS3MCS2) ? "VHTSS3MCS2" :\ - (rate == DESC_RATEVHTSS3MCS3) ? "VHTSS3MCS3" :\ - (rate == DESC_RATEVHTSS3MCS4) ? "VHTSS3MCS4" :\ - (rate == DESC_RATEVHTSS3MCS5) ? "VHTSS3MCS5" :\ - (rate == DESC_RATEVHTSS3MCS6) ? "VHTSS3MCS6" :\ - (rate == DESC_RATEVHTSS3MCS7) ? "VHTSS3MCS7" :\ - (rate == DESC_RATEVHTSS3MCS8) ? "VHTSS3MCS8" :\ - (rate == DESC_RATEVHTSS3MCS9) ? "VHTSS3MCS9" :\ - (rate == DESC_RATEVHTSS4MCS0) ? "VHTSS4MCS0" :\ - (rate == DESC_RATEVHTSS4MCS1) ? "VHTSS4MCS1" :\ - (rate == DESC_RATEVHTSS4MCS2) ? "VHTSS4MCS2" :\ - (rate == DESC_RATEVHTSS4MCS3) ? "VHTSS4MCS3" :\ - (rate == DESC_RATEVHTSS4MCS4) ? "VHTSS4MCS4" :\ - (rate == DESC_RATEVHTSS4MCS5) ? "VHTSS4MCS5" :\ - (rate == DESC_RATEVHTSS4MCS6) ? "VHTSS4MCS6" :\ - (rate == DESC_RATEVHTSS4MCS7) ? "VHTSS4MCS7" :\ - (rate == DESC_RATEVHTSS4MCS8) ? "VHTSS4MCS8" :\ - (rate == DESC_RATEVHTSS4MCS9) ? "VHTSS4MCS9" :\ - "UNKNOWN" +extern const char * const _HDATA_RATE[]; +#define HDATA_RATE(rate) ((rate) >= DESC_RATE_NUM ? _HDATA_RATE[DESC_RATE_NUM] : _HDATA_RATE[rate]) enum { UP_LINK, @@ -268,11 +185,20 @@ typedef enum _WAKEUP_REASON{ RTIME_FAIL_DMA_IDLE = 0x42, RTIME_FAIL_DMA_PAUSE = 0x43, RX_PNO = 0x55, + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + WOW_KEEPALIVE_ACK_TIMEOUT = 0x60, + WOW_KEEPALIVE_WAKE = 0x61, + #endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ AP_OFFLOAD_WAKEUP = 0x66, CLK_32K_UNLOCK = 0xFD, CLK_32K_LOCK = 0xFE }WAKEUP_REASON; +typedef enum _BCN_EARLY_INT_CASE{ + TDLS_BCN_ERLY_ON, + TDLS_BCN_ERLY_OFF +}BCN_EARLY_INT_CASE; + /* * Queue Select Value in TxDesc * */ @@ -310,7 +236,7 @@ struct dbg_rx_counter { u8 rtw_hal_get_port(_adapter *adapter); #ifdef CONFIG_MBSSID_CAM - #define DBG_MBID_CAM_DUMP + /*#define DBG_MBID_CAM_DUMP*/ void rtw_mbid_cam_init(struct dvobj_priv *dvobj); void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj); @@ -416,9 +342,12 @@ HAL_IsLegalChannel( u32 Channel ); -u8 MRateToHwRate(u8 rate); +u8 MRateToHwRate(enum MGN_RATE rate); -u8 hw_rate_to_m_rate(u8 rate); +u8 hw_rate_to_m_rate(u8 hw_rate); +#ifdef CONFIG_RTW_DEBUG +void dump_hw_rate_map_test(void *sel); +#endif void HalSetBrateCfg( PADAPTER Adapter, @@ -468,6 +397,7 @@ u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit); u8 rtw_hal_rcr_add(_adapter *adapter, u32 add); u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear); void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action); +void rtw_hal_rcr_set_chk_bssid_act_non(_adapter *adapter); void rtw_iface_enable_tsf_update(_adapter *adapter); void rtw_iface_disable_tsf_update(_adapter *adapter); @@ -506,13 +436,6 @@ void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid); u8 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value); u8 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value); -BOOLEAN -eqNByte( - u8 *str1, - u8 *str2, - u32 num -); - u32 MapCharToHexDigit( char chTmp @@ -624,9 +547,11 @@ void rtw_hal_ch_sw_iqk_info_backup(_adapter *adapter); void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case); #ifdef CONFIG_GPIO_WAKEUP - void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable); - void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval); - void rtw_hal_set_input_gpio(_adapter *padapter, u8 index); +void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable); +void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval); +void rtw_hal_set_input_gpio(_adapter *padapter, u8 index); +#define GPIO_OUTPUT_LOW 0 +#define GPIO_OUTPUT_HIGH 1 #endif #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE @@ -675,6 +600,7 @@ enum lps_pg_hdl_id { LPS_PG_PHYDM_EN, }; +u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter); u8 rtw_hal_set_lps_pg_info(_adapter *adapter); #endif @@ -683,6 +609,7 @@ void rtw_hal_construct_beacon(_adapter *padapter, u8 *pframe, u32 *pLength); void rtw_hal_construct_NullFunctionData(PADAPTER, u8 *pframe, u32 *pLength, u8 bQoS, u8 AC, u8 bEosp, u8 bForcePowerSave); +bool _rtw_wow_chk_cap(_adapter *adapter, u8 cap); #ifdef CONFIG_WOWLAN struct rtl_wow_pattern { u16 crc; @@ -691,9 +618,9 @@ struct rtl_wow_pattern { }; void rtw_wow_pattern_cam_dump(_adapter *adapter); +void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx); #ifdef CONFIG_WOW_PATTERN_HW_CAM void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context); -void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx); #endif struct rtw_ndp_info { @@ -715,7 +642,9 @@ struct rtw_ndp_info { SET_BITS_TO_LE_4BYTE(target + 2, 0, 8, _value) #endif /*CONFIG_WOWLAN*/ +#ifdef CONFIG_PROC_DEBUG void rtw_dump_phy_cap(void *sel, _adapter *adapter); +#endif void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num); #ifdef CONFIG_SUPPORT_FIFO_DUMP void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size); @@ -770,7 +699,8 @@ void rtw_hal_beamforming_config_csirate(PADAPTER adapter); #endif #endif -u8 phy_get_current_tx_num(PADAPTER pAdapter, u8 Rate); +u8 phy_get_capable_tx_num(_adapter *adapter, enum MGN_RATE rate); +u8 phy_get_current_tx_num(_adapter *adapter, enum MGN_RATE rate); #ifdef CONFIG_RTL8812A u8 * rtw_hal_set_8812a_vendor_ie(_adapter *padapter , u8 *pframe ,uint *frlen ); diff --git a/include/hal_com_h2c.h b/include/hal_com_h2c.h index 6a7b39a..c9db477 100644 --- a/include/hal_com_h2c.h +++ b/include/hal_com_h2c.h @@ -28,6 +28,7 @@ enum h2c_cmd { H2C_DISCON_DECISION = 0x04, H2C_PSD_OFFLOAD = 0x05, H2C_CUSTOMER_STR_REQ = 0x06, + H2C_TXPWR_IDX_OFFLOAD = 0x07, H2C_AP_OFFLOAD = 0x08, H2C_BCN_RSVDPAGE = 0x09, H2C_PROBERSP_RSVDPAGE = 0x0A, @@ -108,10 +109,19 @@ enum h2c_cmd { H2C_D0_SCAN_OFFLOAD_INFO = 0x86, H2C_CHNL_SWITCH_OFFLOAD = 0x87, H2C_AOAC_RSVDPAGE3 = 0x88, + H2C_GPIO_CUSTOM = 0x89, H2C_P2P_OFFLOAD_RSVD_PAGE = 0x8A, H2C_P2P_OFFLOAD = 0x8B, + H2C_WAR_OFFLOAD = 0x8D, + H2C_WAROFLD_RSVDPAGE1 = 0x8E, +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + H2C_UDP_KEEPALIVE = 0x90, +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ #ifdef CONFIG_FW_HANDLE_TXBCN H2C_FW_BCN_OFFLOAD = 0xBA, +#endif +#ifdef CONFIG_SUPPORT_DYNAMIC_TXPWR + H2C_FW_CRC5_SEARCH = 0xBB, #endif H2C_RESET_TSF = 0xC0, #ifdef CONFIG_FW_CORRECT_BCN @@ -135,7 +145,11 @@ enum h2c_cmd { #else #define H2C_MEDIA_STATUS_RPT_LEN 3 #endif +#define H2C_GPIO_CUSTOM_LEN 3 #define H2C_KEEP_ALIVE_CTRL_LEN 2 +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +#define H2C_KEEP_ALIVE_PATTERN_LEN 7 +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ #define H2C_DISCON_DECISION_LEN 3 #define H2C_AP_OFFLOAD_LEN 3 #define H2C_AP_WOW_GPIO_CTRL_LEN 4 @@ -186,16 +200,27 @@ enum h2c_cmd { #define H2C_BTC_WL_PORT_ID_LEN 1 #endif -#define H2C_BT_UNKNOWN_DEVICE_WA_LEN 1 #ifdef DBG_FW_DEBUG_MSG_PKT #define H2C_FW_DBG_MSG_PKT_LEN 2 #endif /*DBG_FW_DEBUG_MSG_PKT*/ -#define H2C_SINGLE_CHANNELSWITCH_V2_LEN 2 +#define H2C_SINGLE_CHANNELSWITCH_V2_LEN 3 +#define H2C_BT_UNKNOWN_DEVICE_WA_LEN 1 + +#ifdef CONFIG_SUPPORT_DYNAMIC_TXPWR +#define H2C_FW_CRC5_SEARCH_LEN 7 +#endif + +#ifdef CONFIG_WAR_OFFLOAD +#define H2C_WAR_OFFLOAD_LEN 3 +#define H2C_WAROFLD_RSVDPAGE1_LEN 6 +#endif /* CONFIG_WAR_OFFLOAD */ + #define eq_mac_addr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1 : 0) #define cp_mac_addr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3], (des)[4] = (src)[4], (des)[5] = (src)[5]) #define cpIpAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3]) +#define cpIpv6Addr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3], (des)[4] = (src)[4], (des)[5] = (src)[5], (des)[6] = (src)[6], (des)[7] = (src)[7], (des)[8] = (src)[8], (des)[9] = (src)[9], (des)[10] = (src)[10], (des)[11] = (src)[11], (des)[12] = (src)[12], (des)[13] = (src)[13], (des)[14] = (src)[14], (des)[15] = (src)[15]) #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) @@ -250,6 +275,40 @@ enum h2c_cmd { #define GET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(__pH2CCmd) LE_BITS_TO_1BYTE(((u8 *)(__pH2CCmd)), 3, 1) #define GET_H2CCMD_MSRRPT_PARM_ROLE(__pH2CCmd) LE_BITS_TO_1BYTE(((u8 *)(__pH2CCmd)), 4, 4) +#ifdef CONFIG_WAR_OFFLOAD +#define SET_IPHDR_VERSION(__pHeader, __Value) WriteLE1Byte(((u8 *)(__pHeader)) + 0, __Value) +#define SET_IPHDR_DSCP(__pHeader, __Value) WriteLE1Byte(((u8 *)(__pHeader)) + 1, __Value) +#define SET_IPHDR_TOTAL_LEN(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 2, __Value) +#define SET_IPHDR_IDENTIFIER(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 4, __Value) +#define SET_IPHDR_FLAGS(__pHeader, __Value) WriteLE1Byte(((u8 *)(__pHeader)) + 6, __Value) +#define SET_IPHDR_FRAG_OFFSET(__pHeader, __Value) WriteLE1Byte(((u8 *)(__pHeader)) + 7, __Value) +#define SET_IPHDR_TTL(__pHeader, __Value) WriteLE1Byte(((u8 *)(__pHeader)) + 8, __Value) +#define SET_IPHDR_PROTOCOL(__pHeader, __Value) WriteLE1Byte(((u8 *)(__pHeader)) + 9, __Value) +#define SET_IPHDR_HDR_CHECKSUM(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 10, __Value) +#define SET_IPHDR_SRC_IP_ADDR(__pHeader, __Value) cpIpAddr(((u8 *)(__pHeader))+12, (u8 *)(__Value)) +#define SET_IPHDR_DST_IP_ADDR(__pHeader, __Value) cpIpAddr(((u8 *)(__pHeader))+16, (u8 *)(__Value)) +#define SET_UDP_SRC_PORT(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 0, __Value) +#define SET_UDP_DST_PORT(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 2, __Value) +#define SET_UDP_LEN(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 4, __Value) +#define SET_UDP_CHECKSUM(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 6, __Value) + +#define SET_MDNS_HDR_FLAG(__pHeader, __Value) WriteLE1Byte(((u8 *)(__pHeader)) + 2, __Value) + +#endif /* CONFIG_WAR_OFFLOAD */ + +#ifdef CONFIG_OFFLOAD_MDNS_V6 +#define SET_IPHDRV6_VERSION(__pHeader, __Value) SET_BITS_TO_LE_1BYTE(__pHeader, 4, 4, __Value) +#define SET_IPHDRV6_TRAFFIC_CLASS(__pHeader, __Value) SET_BITS_TO_LE_2BYTE(__pHeader, 4, 8, __Value) +#define SET_IPHDRV6_FLOW_LABEL(__pHeader, __Value) SET_BITS_TO_LE_4BYTE(__pHeader, 12, 20, __Value) +#define SET_IPHDRV6_PAYLOAD_LENGTH(__pHeader, __Value) SET_BITS_TO_LE_2BYTE(((u8 *)(__pHeader)) + 4, 0, 16, __Value) +#define SET_IPHDRV6_NEXT_HEADER(__pHeader, __Value) SET_BITS_TO_LE_1BYTE((__pHeader) + 6, 0, 8, __Value) +#define SET_IPHDRV6_HOP_LIMIT(__pHeader, __Value) SET_BITS_TO_LE_1BYTE((__pHeader) + 7, 0, 8, __Value) +#define SET_IPHDRV6_SRC_IP_ADDR(__pHeader, __Value) cpIpv6Addr((u8 *)(__pHeader) + 8, (u8 *)(__Value)) +#define SET_IPHDRV6_DST_IP_ADDR(__pHeader, __Value) cpIpv6Addr((u8 *)(__pHeader) + 24, (u8 *)(__Value)) +#endif + + + #define H2C_MSR_ROLE_RSVD 0 #define H2C_MSR_ROLE_STA 1 #define H2C_MSR_ROLE_AP 2 @@ -290,6 +349,26 @@ s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool #define SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 8, __Value) #define SET_H2CCMD_DISCONDECISION_PARM_TRY_OK_BCN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) +/*UDP_KEEP_ALIVE 0x90*/ +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +/*data 0*/ +#define SET_H2CCMD_UDP_KEEP_ALIVE_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value); +#define SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 7, __Value); +/*data 1*/ +#define SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 7, 1, __Value); +#define SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 7, __Value); +/*data 2*/ +#define SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 7, 1, __Value); +#define SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_PATTERN_idx(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 7, __Value); +/*data3*/ +#define SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_LOW_BIT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value); +/*data4*/ +#define SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_HI_BIT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+4, 0, 8, __Value); +/*data5*/ +#define SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+5, 0, 8, __Value); +/*data6*/ +#define SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+6, 0, 8, __Value); +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ #ifdef CONFIG_RTW_CUSTOMER_STR #define RTW_CUSTOMER_STR_LEN 16 #define RTW_CUSTOMER_STR_FMT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" @@ -321,6 +400,14 @@ s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs); s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs); #endif /* CONFIG_RTW_CUSTOMER_STR */ +#ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX +#define H2C_TXPWR_IDX_OFFLOAD_LEN 4 +#define SET_H2CCMD_TXPWR_IDX_CCK(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_H2CCMD_TXPWR_IDX_OFDM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd + 1, 0, 8, __Value) +#define SET_H2CCMD_TXPWR_IDX_HT1SS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd + 2, 0, 8, __Value) +#define SET_H2CCMD_TXPWR_IDX_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd + 3, 0, 1, __Value) +#endif + /* _AP_Offload 0x08 */ #define SET_H2CCMD_AP_WOWLAN_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) /* _BCN_RsvdPage 0x09 */ @@ -328,6 +415,18 @@ s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs); /* _Probersp_RsvdPage 0x0a */ #define SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) /* _Probersp_RsvdPage 0x13 */ + +#define SET_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_H2CCMD_PWRMODE_PARM_RLBM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 4, __Value) +#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 4, 4, __Value) +#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_H2CCMD_PWRMODE_PARM_BCN_EARLY_C2H_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 2, 1, __Value) +#define SET_H2CCMD_PWRMODE_PARM_PWR_STATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) + +#define GET_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd) LE_BITS_TO_1BYTE(__pH2CCmd, 0, 8) +/* _PWR_MOD_CMD_0x20 */ + #define SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value) #define SET_H2CCMD_AP_WOW_GPIO_CTRL_C2H_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value) #define SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value) @@ -350,6 +449,8 @@ s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs); SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) #define SET_H2CCMD_INACTIVE_DISBBRF(__pH2CCmd, __Value) \ SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value) +#define SET_H2CCMD_INACTIVE_PORT_NUM(__pH2CCmd, __Value) \ + SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 3, __Value) #define SET_H2CCMD_INACTIVE_PS_FREQ(__pH2CCmd, __Value) \ SET_BITS_TO_LE_1BYTE(__pH2CCmd + 1, 0, 8, __Value) #define SET_H2CCMD_INACTIVE_PS_DURATION(__pH2CCmd, __Value) \ @@ -467,7 +568,9 @@ s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs); #define SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) #define SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd) + 1, 0, 4, __Value) #define SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd) + 1, 4, 4, __Value) - +#define SET_H2CCMD_SINGLE_CH_SWITCH_V2_PWR_IDX_UPDATE_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd) + 2, 0, 1, __Value) +#define SET_H2CCMD_SINGLE_CH_SWITCH_V2_IQK_UPDATE_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd) + 2, 1, 1, __Value) +#define SET_H2CCMD_SINGLE_CH_SWITCH_V2_CH_IDX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd) + 2, 4, 4, __Value) #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT) #define SET_H2CCMD_BTC_WL_PORT_ID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value) @@ -547,6 +650,11 @@ s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs); #define SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) #endif /* CONFIG_PNO_SUPPORT */ +/* _GPIO_CUSTOM_CMD_0x89 */ +#define SET_H2CCMD_CUSTOMERID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_H2CCMD_SPECIAL_WAKE_REASON(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_H2CCMD_CUSTOM_WAKE_REASON(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 1, __Value) + #ifdef CONFIG_P2P_WOWLAN /* P2P_RsvdPage_0x8a */ #define SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) @@ -568,6 +676,33 @@ s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs); #define SET_H2CCMD_LPSPG_IQK_INFO_LOC(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd) + 3, 0, 8, __Value)/*Loc_IQK_result*/ #endif +#if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR) +#define SET_H2CCMD_FW_CRC5_SEARCH_EN(cmd, v) \ + SET_BITS_TO_LE_1BYTE((cmd), 0, 1, (v)); +#define SET_H2CCMD_FW_CRC5_SEARCH_MACID(cmd, v) \ + SET_BITS_TO_LE_1BYTE((cmd), 1, 7, (v)); +#define SET_H2CCMD_FW_CRC5_SEARCH_MAC(cmd, mac) \ + do { \ + int __offset = 0; \ + for (__offset = 0; __offset < ETH_ALEN; __offset++) \ + SET_BITS_TO_LE_1BYTE((u8 *)(cmd + __offset), 0, 8, *((u8 *)(mac + __offset))); \ + } while(0) +#endif + +#ifdef CONFIG_WAR_OFFLOAD +/* WarOffload_Info_0x8D */ +#define SET_H2CCMD_WAR_CFG_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_H2CCMD_WAR_CFG_ARP_RSP_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_H2CCMD_WAR_CFG_MDNSV4_RSP_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 2, 1, __Value) +#define SET_H2CCMD_WAR_CFG_MDNSV6_RSP_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 3, 1, __Value) +#define SET_H2CCMD_WAR_CFG_MDNSV4_WAKE_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 6, 1, __Value) +#define SET_H2CCMD_WAR_CFG_MDNSV6_WAKE_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 7, 1, __Value) + +/* H2C_WAROFLD_RSVDPAGE1 */ +#define SET_H2CCMD_WAROFLD_RSVDPAGE1_LOC_PARM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd), 0, 8, __Value) +#endif /* CONFIG_WAR_OFFLOAD */ + + /* BT_UNKNOWN_DEVICE_WA_0xD1 */ #define SET_H2CCMD_BT_UNKNOWN_DEVICE_WA_HANG_CHK_EN(__pH2CCmd, __Value) \ SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) @@ -619,6 +754,18 @@ typedef struct _RSVDPAGE_LOC { u8 LocSSIDInfo; u8 LocProbePacket; #endif /* CONFIG_PNO_SUPPORT */ +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + u8 LocKeepAlive; +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ +#ifdef CONFIG_WAR_OFFLOAD + u8 LocIpParm; +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) + u8 LocMdnsPara; + u8 LocMdnsv4; + u8 LocMdnsv6; +#endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */ +#endif /* CONFIG_WAR_OFFLOAD */ + #endif /* CONFIG_WOWLAN */ u8 LocApOffloadBCN; #ifdef CONFIG_P2P_WOWLAN @@ -649,7 +796,9 @@ void rsvd_page_cache_free_data(struct rsvd_page_cache_t *cache); void rsvd_page_cache_free(struct rsvd_page_cache_t *cache); #endif +#ifdef CONFIG_WOWLAN void dump_TX_FIFO(PADAPTER padapter, u8 page_num, u16 page_size); +#endif u8 rtw_hal_set_fw_media_status_cmd(_adapter *adapter, u8 mstatus, u8 macid); #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) /* WOW command function */ diff --git a/include/hal_com_phycfg.h b/include/hal_com_phycfg.h index e2439ff..b6e74a7 100644 --- a/include/hal_com_phycfg.h +++ b/include/hal_com_phycfg.h @@ -87,10 +87,7 @@ PHY_GetRateValuesOfTxPowerByRate( u8 *RateNum ); -u8 -PHY_GetRateIndexOfTxPowerByRate( - u8 Rate -); +u8 phy_get_rate_idx_of_txpwr_by_rate(enum MGN_RATE rate); void phy_set_tx_power_index_by_rate_section( @@ -100,31 +97,16 @@ phy_set_tx_power_index_by_rate_section( u8 RateSection ); -s8 -_PHY_GetTxPowerByRate( - PADAPTER pAdapter, - u8 Band, - enum rf_path RFPath, - u8 RateIndex -); +s8 phy_get_txpwr_by_rate(_adapter *adapter + , BAND_TYPE band, enum rf_path rfpath, RATE_SECTION rs, enum MGN_RATE rate); -s8 -PHY_GetTxPowerByRate( - PADAPTER pAdapter, - u8 Band, - enum rf_path RFPath, - RATE_SECTION rs, - enum MGN_RATE rate -); +s16 phy_get_txpwr_by_rate_single_mbm(_adapter *adapter + , BAND_TYPE band, enum rf_path rfpath, RATE_SECTION rs, enum MGN_RATE rate, bool eirp); +s16 phy_get_txpwr_by_rate_total_mbm(_adapter *adapter + , BAND_TYPE band, RATE_SECTION rs, enum MGN_RATE rate, bool cap, bool eirp); -void -PHY_SetTxPowerByRate( - PADAPTER pAdapter, - u8 Band, - enum rf_path RFPath, - u8 Rate, - s8 Value -); +s16 phy_get_txpwr_by_rate_single_max_mbm(_adapter *adapter, BAND_TYPE band, enum rf_path rfpath, bool eirp); +s16 phy_get_txpwr_by_rate_total_max_mbm(_adapter *adapter, BAND_TYPE band, bool cap, bool eirp); void phy_set_tx_power_level_by_path( @@ -178,16 +160,19 @@ s8 phy_get_txpwr_lmt_diff(_adapter *adapter s8 phy_get_txpwr_lmt_sub_chs(_adapter *adapter , const char *regd_name , BAND_TYPE band, enum channel_width bw - , u8 rfpath, u8 rate, u8 ntx_idx, u8 cch, u8 opch + , u8 rfpath, u8 rate, u8 ntx_idx, u8 cch, u8 opch, bool reg_max ); #else #define phy_get_txpwr_lmt(adapter, regd_name, band, bw, tlrs, ntx_idx, cch, lock) (GET_HAL_SPEC(adapter)->txgi_max) #define phy_get_txpwr_lmt_diff(adapter, regd_name, band, bw, rfpath, rs, tlrs, ntx_idx, cch, lock) (GET_HAL_SPEC(adapter)->txgi_max) -#define phy_get_txpwr_lmt_sub_chs(adapter, regd_name, band, bw, rfpath, rate, ntx_idx, cch, opch) (GET_HAL_SPEC(adapter)->txgi_max) +#define phy_get_txpwr_lmt_sub_chs(adapter, regd_name, band, bw, rfpath, rate, ntx_idx, cch, opch, reg_max) (GET_HAL_SPEC(adapter)->txgi_max) #endif /* CONFIG_TXPWR_LIMIT */ +void dump_txpwr_tpc_settings(void *sel, _adapter *adapter); +void dump_txpwr_antenna_gain(void *sel, _adapter *adapter); + s8 phy_get_txpwr_target(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate, u8 ntx_idx - , enum channel_width bw, BAND_TYPE band, u8 cch, u8 opch, struct txpwr_idx_comp *tic); + , enum channel_width bw, BAND_TYPE band, u8 cch, u8 opch, bool reg_max, struct txpwr_idx_comp *tic); s8 phy_get_txpwr_amends(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate, u8 ntx_idx , enum channel_width bw, BAND_TYPE band, u8 cch, struct txpwr_idx_comp *tic); #ifdef CONFIG_TXPWR_PG_WITH_TSSI_OFFSET @@ -199,14 +184,14 @@ u8 hal_com_get_txpwr_idx(_adapter *adapter, enum rf_path rfpath , struct txpwr_idx_comp *tic); s16 phy_get_txpwr_single_mbm(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate - , enum channel_width bw, u8 cch, u8 opch, struct txpwr_idx_comp *tic); + , enum channel_width bw, u8 cch, u8 opch, bool reg_max, bool eirp, struct txpwr_idx_comp *tic); s16 phy_get_txpwr_total_mbm(_adapter *adapter, RATE_SECTION rs, u8 rate - , enum channel_width bw, u8 cch, u8 opch, struct txpwr_idx_comp *tic); + , enum channel_width bw, u8 cch, u8 opch, bool reg_max, bool eirp, struct txpwr_idx_comp *tic); s16 phy_get_txpwr_single_max_mbm(_adapter *adapter, u8 rfpath - , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht); + , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht, bool reg_max, bool eirp); s16 phy_get_txpwr_total_max_mbm(_adapter *adapter - , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht); + , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht, bool reg_max, bool eirp); s8 phy_get_tx_power_final_absolute_value(_adapter *adapter, u8 rfpath, u8 rate, @@ -229,8 +214,10 @@ struct txpwr_idx_comp { s8 btc; s8 extra; s8 utarget; - s8 limit; - s8 ulimit; + s8 rlimit; /* regulatory limit w/o HAL consideration */ + s8 limit; /* limit from RTK private (regulatory limit w/ HAL consideration) */ + s8 ulimit; /* user limit */ + s8 tpc; /* for amends */ s8 tpt; @@ -263,6 +250,7 @@ bool phy_is_txpwr_user_target_specified(_adapter *adapter); void dump_tx_power_index_inline(void *sel, _adapter *adapter, u8 rfpath , enum channel_width bw, u8 cch, enum MGN_RATE rate, u8 pwr_idx, struct txpwr_idx_comp *tic); +#ifdef CONFIG_PROC_DEBUG void dump_tx_power_idx_title(void *sel, _adapter *adapter , enum channel_width bw, u8 cch, u8 opch); void dump_tx_power_idx_by_path_rs(void *sel, _adapter *adapter, u8 rfpath @@ -275,6 +263,7 @@ void dump_txpwr_total_dbm_by_rs(void *sel, _adapter *adapter, u8 rs , enum channel_width bw, u8 cch, u8 opch); void dump_txpwr_total_dbm(void *sel, _adapter *adapter , enum channel_width bw, u8 cch, u8 opch); +#endif bool phy_is_tx_power_limit_needed(_adapter *adapter); bool phy_is_tx_power_by_rate_needed(_adapter *adapter); @@ -299,9 +288,11 @@ void dump_hal_txpwr_info_5g(void *sel, _adapter *adapter, u8 rfpath_num, u8 max_ void hal_load_txpwr_info(_adapter *adapter); #endif +#ifdef CONFIG_PROC_DEBUG void dump_tx_power_ext_info(void *sel, _adapter *adapter); void dump_target_tx_power(void *sel, _adapter *adapter); void dump_tx_power_by_rate(void *sel, _adapter *adapter); +#endif int rtw_get_phy_file_path(_adapter *adapter, const char *file_name); diff --git a/include/hal_com_reg.h b/include/hal_com_reg.h index 7d782f9..353a0f5 100644 --- a/include/hal_com_reg.h +++ b/include/hal_com_reg.h @@ -22,8 +22,8 @@ /* 8188E PKT_BUFF_ACCESS_CTRL value */ #define TXPKT_BUF_SELECT 0x69 -#define TXREPORT_BUF_SELECT 0x7F #define RXPKT_BUF_SELECT 0xA5 +#define TXREPORT_BUF_SELECT 0x7F #define DISABLE_TRXPKT_BUF_ACCESS 0x0 #ifndef RTW_HALMAC @@ -511,9 +511,12 @@ #define REG_WLAN_ACT_MASK_CTRL_1 0x076C /* GPIO Control */ -#define REG_SW_GPIO_SHARE_CTRL 0x1038 +#define REG_SW_GPIO_SHARE_CTRL_0 0x1038 +#define REG_SW_GPIO_SHARE_CTRL_1 0x103C #define REG_SW_GPIO_A_OUT 0x1040 #define REG_SW_GPIO_A_OEN 0x1044 +#define REG_SW_GPIO_B_OEN 0x1058 +#define REG_SW_GPIO_B_OUT 0x105C /* Hardware Port 2 */ #define REG_MACID2 0x1620 @@ -1253,10 +1256,14 @@ Current IOREG MAP /* 2 REG_LED_CFG (Offset 0x004C) */ #define BIT_SW_SPDT_SEL BIT(22) -/* 2 REG_SW_GPIO_SHARE_CTRL (Offset 0x1038) */ +/* 2 REG_SW_GPIO_SHARE_CTRL_0 (Offset 0x1038) */ #define BIT_BTGP_WAKE_LOC (BIT(10) | BIT(11)) #define BIT_SW_GPIO_FUNC BIT(0) +/* 2 REG_SW_GPIO_SHARE_CTRL_1 (Offset 0x103C) */ +#define BIT_WLMAC_DBG_LOC (BIT(9) | BIT(10)) +#define BIT_WL_GPIO_SEL (BIT(30) | BIT(31)) + /* 2 8051FWDL * 2 MCUFWDL */ #define MCUFWDL_EN BIT(0) @@ -1865,6 +1872,7 @@ Current IOREG MAP #define LAST_ENTRY_OF_TX_PKT_BUFFER_8723D 255 #define LAST_ENTRY_OF_TX_PKT_BUFFER_8710B 255 #define LAST_ENTRY_OF_TX_PKT_BUFFER_8192F 255 +#define LAST_ENTRY_OF_TX_PKT_BUFFER_8723F 255 #define POLLING_LLT_THRESHOLD 20 #if defined(CONFIG_RTL8723B) && defined(CONFIG_PCI_HCI) #define POLLING_READY_TIMEOUT_COUNT 6000 diff --git a/include/hal_data.h b/include/hal_data.h old mode 100755 new mode 100644 index 56aa02d..3262436 --- a/include/hal_data.h +++ b/include/hal_data.h @@ -224,6 +224,7 @@ struct hal_spec_t { u8 sec_cam_ent_num; u8 sec_cap; + u8 wow_cap; u8 macid_cap; u16 macid_txrpt; u8 macid_txrpt_pgsz; @@ -231,6 +232,8 @@ struct hal_spec_t { u8 rfpath_num_2g:4; /* used for tx power index path */ u8 rfpath_num_5g:4; /* used for tx power index path */ u8 rf_reg_path_num; + u8 rf_reg_path_avail_num; + u8 rf_reg_trx_path_bmp; /* [7:4]TX path bmp, [0:3]RX path bmp */ u8 max_tx_cnt; u8 tx_nss_num:4; @@ -246,9 +249,7 @@ struct hal_spec_t { u8 wl_func; /* value of WL_FUNC_XXX */ -#if CONFIG_TX_AC_LIFETIME u8 tx_aclt_unit_factor; /* how many 32us */ -#endif u8 rx_tsf_filter:1; @@ -370,7 +371,6 @@ typedef struct hal_com_data { WIRELESS_MODE CurrentWirelessMode; enum channel_width current_channel_bw; BAND_TYPE current_band_type; /* 0:2.4G, 1:5G */ - BAND_TYPE BandSet; u8 current_channel; u8 cch_20; u8 cch_40; @@ -382,7 +382,9 @@ typedef struct hal_com_data { u8 bDisableSWChannelPlan; /* flag of disable software change channel plan */ u16 BasicRateSet; u32 ReceiveConfig; - u32 rcr_backup; /* used for switching back from monitor mode */ +#ifdef CONFIG_WIFI_MONITOR + struct mon_reg_backup mon_backup; /* used for switching back from monitor mode */ +#endif /* CONFIG_WIFI_MONITOR */ u8 rx_tsf_addr_filter_config; /* for 8822B/8821C USE */ BOOLEAN bSwChnl; BOOLEAN bSetChnlBW; @@ -406,6 +408,7 @@ typedef struct hal_com_data { u8 max_tx_cnt; u8 tx_nss; /*tx Spatial Streams - GET_HAL_TX_NSS*/ u8 rx_nss; /*rx Spatial Streams - GET_HAL_RX_NSS*/ + u8 txpath_cap_num_nss[4]; /* capable path num for NSS TX, [0] for 1SS, [3] for 4SS */ u8 PackageType; u8 antenna_test; @@ -522,10 +525,18 @@ typedef struct hal_com_data { u8 target_txpwr_5g[TX_PWR_BY_RATE_NUM_RF] [NUM_OF_TARGET_TXPWR_5G]; -#if defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) + bool set_entire_txpwr; + +#if defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) \ + || defined(CONFIG_RTL8723F) u32 txagc_set_buf; #endif +#ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX + u8 txpwr_idx_offload_buf[3]; /* for CCK, OFDM, HT1SS */ + struct submit_ctx txpwr_idx_offload_sctx; +#endif + u8 txpwr_by_rate_loaded:1; u8 txpwr_by_rate_from_file:1; u8 txpwr_limit_loaded:1; @@ -585,6 +596,7 @@ typedef struct hal_com_data { u8 neediqk_24g; u8 IQK_MP_Switch; u8 bScanInProcess; + u8 phydm_init_result; /*BB and RF para match or not*/ /******** PHY DM & DM Section **********/ @@ -621,6 +633,8 @@ typedef struct hal_com_data { u8 rxagg_dma_timeout; #endif /* RTW_RX_AGGREGATION */ + bool intf_start; + #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) /* */ /* For SDIO Interface HAL related */ @@ -658,7 +672,7 @@ typedef struct hal_com_data { /* SDIO Rx FIFO related. */ /* */ u8 SdioRxFIFOCnt; -#ifdef CONFIG_RTL8822C +#if defined (CONFIG_RTL8822C) || defined (CONFIG_RTL8192F) u32 SdioRxFIFOSize; #else u16 SdioRxFIFOSize; diff --git a/include/hal_ic_cfg.h b/include/hal_ic_cfg.h index 5616ff7..822479a 100644 --- a/include/hal_ic_cfg.h +++ b/include/hal_ic_cfg.h @@ -20,6 +20,7 @@ #define RTL8821A_SUPPORT 0 #define RTL8723B_SUPPORT 0 #define RTL8723D_SUPPORT 0 +#define RTL8723F_SUPPORT 0 #define RTL8192E_SUPPORT 0 #define RTL8192F_SUPPORT 0 #define RTL8814A_SUPPORT 0 @@ -138,6 +139,8 @@ #ifndef CONFIG_TXPWR_PG_WITH_PWR_IDX #define CONFIG_TXPWR_PG_WITH_PWR_IDX #endif + #define CONFIG_STOP_RESUME_BCN_BY_TXPAUSE /*to fixed no bcn issue*/ + #define CONFIG_TSF_SYNC #endif #ifdef CONFIG_RTL8723B @@ -242,6 +245,10 @@ #ifndef CONFIG_TXPWR_PG_WITH_PWR_IDX #define CONFIG_TXPWR_PG_WITH_PWR_IDX #endif + + #if defined(CONFIG_USB_HCI) && !defined(CONFIG_FW_OFFLOAD_SET_TXPWR_IDX) + #define CONFIG_FW_OFFLOAD_SET_TXPWR_IDX + #endif #endif #ifdef CONFIG_RTL8822B @@ -367,9 +374,15 @@ #define RTW_BEAMFORMING_VERSION_2 #endif /* CONFIG_BEAMFORMING */ - #ifndef CONFIG_RTW_MAC_HIDDEN_RPT - #define CONFIG_RTW_MAC_HIDDEN_RPT - #endif /* CONFIG_RTW_MAC_HIDDEN_RPT */ + #ifdef CONFIG_NO_FW + #ifdef CONFIG_RTW_MAC_HIDDEN_RPT + #undef CONFIG_RTW_MAC_HIDDEN_RPT + #endif + #else + #ifndef CONFIG_RTW_MAC_HIDDEN_RPT + #define CONFIG_RTW_MAC_HIDDEN_RPT + #endif + #endif #ifndef DBG_RX_DFRAME_RAW_DATA #define DBG_RX_DFRAME_RAW_DATA @@ -382,6 +395,7 @@ #ifdef CONFIG_MCC_MODE #define CONFIG_MCC_MODE_V2 + #define CONFIG_MCC_PHYDM_OFFLOAD #endif /* CONFIG_MCC_MODE */ #if defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW) @@ -426,6 +440,10 @@ #ifndef CONFIG_TXPWR_PG_WITH_TSSI_OFFSET #define CONFIG_TXPWR_PG_WITH_TSSI_OFFSET #endif + + #define CONFIG_RTL8822C_XCAP_NEW_POLICY + + #define CONFIG_SUPPORT_DYNAMIC_TXPWR #endif /* CONFIG_RTL8822C */ #ifdef CONFIG_RTL8821C @@ -475,6 +493,8 @@ #ifndef CONFIG_TXPWR_PG_WITH_PWR_IDX #define CONFIG_TXPWR_PG_WITH_PWR_IDX #endif + + #define CONFIG_BT_EFUSE_MASK #endif /*CONFIG_RTL8821C*/ #ifdef CONFIG_RTL8710B @@ -513,7 +533,6 @@ #ifdef CONFIG_CONCURRENT_MODE /*#define CONFIG_AP_PORT_SWAP*/ #define CONFIG_FW_MULTI_PORT_SUPPORT - #define CONFIG_SUPPORT_AP_PORT1 #endif /* CONFIG_CONCURRENT_MODE */ /* @@ -579,7 +598,7 @@ #define CONFIG_RTW_TX_NPATH_EN /* 8814B is always 4TX */ #ifdef CONFIG_LPS - /* #define CONFIG_LPS_ACK */ /* Supported after FW v04 */ + #define CONFIG_LPS_ACK /* Supported after FW v04 */ #endif #ifndef CONFIG_TXPWR_PG_WITH_PWR_IDX @@ -589,5 +608,106 @@ #define CONFIG_TXPWR_PG_WITH_TSSI_OFFSET #endif #endif /* CONFIG_RTL8814B */ +#ifdef CONFIG_RTL8723F + #undef RTL8723F_SUPPORT + #define RTL8723F_SUPPORT 1 + /* Use HALMAC architecture, necessary for 8723F */ + #define RTW_HALMAC + + /*#define DBG_LA_MODE*/ + + #ifndef CONFIG_FW_C2H_PKT + #define CONFIG_FW_C2H_PKT + #endif /* CONFIG_FW_C2H_PKT */ + + #define RTW_TX_PA_BIAS /* Adjust TX PA Bias from eFuse */ + + #ifdef CONFIG_WOWLAN + #define CONFIG_WOW_PATTERN_IN_TXFIFO + #endif + + #ifdef CONFIG_WOWLAN + #define CONFIG_GTK_OL + /*#define CONFIG_ARP_KEEP_ALIVE*/ + + #ifdef CONFIG_GPIO_WAKEUP + #ifndef WAKEUP_GPIO_IDX + #define WAKEUP_GPIO_IDX 12 /* WIFI Chip Side */ + #endif /* !WAKEUP_GPIO_IDX */ + #endif /* CONFIG_GPIO_WAKEUP */ + #endif /* CONFIG_WOWLAN */ + + #ifdef CONFIG_CONCURRENT_MODE + #define CONFIG_AP_PORT_SWAP + #define CONFIG_FW_MULTI_PORT_SUPPORT + #endif /* CONFIG_CONCURRENT_MODE */ + + #ifdef CONFIG_NO_FW + #ifdef CONFIG_RTW_MAC_HIDDEN_RPT + #undef CONFIG_RTW_MAC_HIDDEN_RPT + #endif + #else + #ifndef CONFIG_RTW_MAC_HIDDEN_RPT + #define CONFIG_RTW_MAC_HIDDEN_RPT + #endif + #endif + + #ifndef DBG_RX_DFRAME_RAW_DATA + #define DBG_RX_DFRAME_RAW_DATA + #endif /* DBG_RX_DFRAME_RAW_DATA */ + + /*#define RTW_IQK_FW_OFFLOAD*/ + #define CONFIG_ADVANCE_OTA + + #ifdef CONFIG_MCC_MODE + #define CONFIG_MCC_MODE_V2 + #define CONFIG_MCC_PHYDM_OFFLOAD + #endif /* CONFIG_MCC_MODE */ + + #if defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW) + #define CONFIG_TDLS_CH_SW_V2 + #endif + + #ifndef RTW_CHANNEL_SWITCH_OFFLOAD + #ifdef CONFIG_TDLS_CH_SW_V2 + #define RTW_CHANNEL_SWITCH_OFFLOAD + #endif + #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */ + + #if defined(CONFIG_RTW_MESH) && !defined(RTW_PER_CMD_SUPPORT_FW) + /* Supported since fw v22.1 */ + #define RTW_PER_CMD_SUPPORT_FW + #endif /* RTW_PER_CMD_SUPPORT_FW */ + #define CONFIG_SUPPORT_FIFO_DUMP + #define CONFIG_HW_P0_TSF_SYNC + #define CONFIG_BCN_RECV_TIME + + /*#define CONFIG_TCP_CSUM_OFFLOAD_TX*/ + #if defined(CONFIG_TCP_CSUM_OFFLOAD_TX) && !defined(CONFIG_RTW_NETIF_SG) + #define CONFIG_RTW_NETIF_SG + #endif + #define CONFIG_TCP_CSUM_OFFLOAD_RX + + #ifdef CONFIG_P2P_PS + #define CONFIG_P2P_PS_NOA_USE_MACID_SLEEP + #endif + + #define CONFIG_RTS_FULL_BW + + #ifdef CONFIG_LPS + #define CONFIG_LPS_ACK + #endif + + #ifndef CONFIG_TXPWR_PG_WITH_PWR_IDX + #define CONFIG_TXPWR_PG_WITH_PWR_IDX + #endif + #ifndef CONFIG_TXPWR_PG_WITH_TSSI_OFFSET + #define CONFIG_TXPWR_PG_WITH_TSSI_OFFSET + #endif + + #define CONFIG_BT_EFUSE_MASK + + #define CONFIG_WRITE_BCN_LEN_TO_FW +#endif /* CONFIG_RTL8723F */ #endif /*__HAL_IC_CFG_H__*/ diff --git a/include/hal_intf.h b/include/hal_intf.h index 1ed2b70..34dbdd2 100644 --- a/include/hal_intf.h +++ b/include/hal_intf.h @@ -42,6 +42,7 @@ enum _CHIP_TYPE { RTL8192F, RTL8822C, RTL8814B, + RTL8723F, MAX_CHIP_TYPE }; @@ -108,6 +109,7 @@ typedef enum _HW_VARIABLES { HW_VAR_SET_RPWM, HW_VAR_CPWM, HW_VAR_H2C_FW_PWRMODE, + HW_VAR_H2C_FW_PWRMODE_RFON_CTRL, HW_VAR_H2C_INACTIVE_IPS, HW_VAR_H2C_PS_TUNE_PARAM, HW_VAR_H2C_FW_JOINBSSRPT, @@ -197,11 +199,8 @@ typedef enum _HW_VARIABLES { HW_VAR_MDIO, HW_VAR_L1OFF_CAPABILITY, HW_VAR_L1OFF_NIC_SUPPORT, -#ifdef CONFIG_TDLS -#ifdef CONFIG_TDLS_CH_SW - HW_VAR_TDLS_BCN_EARLY_C2H_RPT, -#endif -#endif + HW_VAR_BCN_EARLY_C2H_RPT, + HW_VAR_SET_DRV_ERLY_INT, HW_VAR_DUMP_MAC_TXFIFO, HW_VAR_PWR_CMD, #ifdef CONFIG_FW_HANDLE_TXBCN @@ -211,12 +210,16 @@ typedef enum _HW_VARIABLES { HW_VAR_ENABLE_RX_BAR, HW_VAR_TSF_AUTO_SYNC, HW_VAR_LPS_STATE_CHK, + HW_VAR_LPS_RFON_CHK, #ifdef CONFIG_RTS_FULL_BW HW_VAR_SET_RTS_BW, #endif #if defined(CONFIG_PCI_HCI) HW_VAR_ENSWBCN, #endif +#ifdef CONFIG_WOWLAN + HW_VAR_VENDOR_WOW_MODE, +#endif /* CONFIG_WOWLAN */ } HW_VARIABLES; typedef enum _HAL_DEF_VARIABLE { @@ -300,7 +303,13 @@ struct hal_ops { * mgnt_xmit should be implemented to run in interrupt context */ s32(*mgnt_xmit)(_adapter *padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32(*hal_mgmt_xmitframe_enqueue)(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32(*hal_xmitframe_enqueue)(_adapter *padapter, struct xmit_frame *pxmitframe); + #if defined (CONFIG_CONCURRENT_MODE) && defined (CONFIG_TSF_SYNC) + void(*tsf_sync)(_adapter *Adapter); + #endif #ifdef CONFIG_XMIT_THREAD_MODE s32(*xmit_thread_handler)(_adapter *padapter); #endif @@ -518,6 +527,8 @@ typedef enum _HARDWARE_TYPE { HARDWARE_TYPE_RTL8814BE, HARDWARE_TYPE_RTL8814BU, HARDWARE_TYPE_RTL8814BS, + HARDWARE_TYPE_RTL8723FU, + HARDWARE_TYPE_RTL8723FS, HARDWARE_TYPE_MAX, } HARDWARE_TYPE; @@ -650,6 +661,11 @@ typedef enum _HARDWARE_TYPE { #define IS_HARDWARE_TYPE_8814B(_Adapter) \ (IS_HARDWARE_TYPE_8814BE(_Adapter) || IS_HARDWARE_TYPE_8814BU(_Adapter) || IS_HARDWARE_TYPE_8814BS(_Adapter)) +#define IS_HARDWARE_TYPE_8723FU(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8723FU) +#define IS_HARDWARE_TYPE_8723FS(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8723FS) +#define IS_HARDWARE_TYPE_8723F(_Adapter) \ + (IS_HARDWARE_TYPE_8723FU(_Adapter) || IS_HARDWARE_TYPE_8723FS(_Adapter)) + #define IS_HARDWARE_TYPE_JAGUAR2(_Adapter) \ (IS_HARDWARE_TYPE_8814A(_Adapter) || IS_HARDWARE_TYPE_8821B(_Adapter) || IS_HARDWARE_TYPE_8822B(_Adapter) || IS_HARDWARE_TYPE_8821C(_Adapter)) @@ -659,6 +675,8 @@ typedef enum _HARDWARE_TYPE { #define IS_HARDWARE_TYPE_JAGUAR3(_Adapter) \ (IS_HARDWARE_TYPE_8814B(_Adapter) || IS_HARDWARE_TYPE_8822C(_Adapter)) +#define IS_HARDWARE_TYPE_JAGUAR3_11N(_Adapter) IS_HARDWARE_TYPE_8723F(_Adapter) + #define IS_HARDWARE_TYPE_JAGUAR_ALL(_Adapter) \ (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(_Adapter) || IS_HARDWARE_TYPE_JAGUAR3(_Adapter)) @@ -741,6 +759,9 @@ u8 rtw_hal_pci_l1off_capability(_adapter *padapter); u8 rtw_hal_intf_ps_func(_adapter *padapter, HAL_INTF_PS_FUNC efunc_id, u8 *val); +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtw_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtw_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtw_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtw_hal_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe); @@ -841,6 +862,7 @@ s32 rtw_hal_macid_sleep(_adapter *adapter, u8 macid); s32 rtw_hal_macid_wakeup(_adapter *adapter, u8 macid); s32 rtw_hal_macid_sleep_all_used(_adapter *adapter); s32 rtw_hal_macid_wakeup_all_used(_adapter *adapter); + s32 rtw_hal_macid_drop(_adapter *adapter, u8 macid); s32 rtw_hal_macid_undrop(_adapter *adapter, u8 macid); diff --git a/include/hal_pg.h b/include/hal_pg.h old mode 100755 new mode 100644 index f4c0b2a..2df6a39 --- a/include/hal_pg.h +++ b/include/hal_pg.h @@ -588,7 +588,7 @@ */ #define EEPROM_TX_PWR_INX_8822C 0x10 #define EEPROM_ChannelPlan_8822C 0xB8 -#define EEPROM_XTAL_8822C 0xB9 +#define EEPROM_XTAL_B9_8822C 0xB9 #define EEPROM_IQK_LCK_8822C 0xBB #define EEPROM_2G_5G_PA_TYPE_8822C 0xBC /* PATH A & PATH B */ @@ -612,6 +612,10 @@ #define EEPROM_COUNTRY_CODE_8822C 0xCB #define EEPROM_THERMAL_METER_A_8822C 0xD0 #define EEPROM_THERMAL_METER_B_8822C 0xD1 + +#define EEPROM_XTAL_110_8822C 0x110 +#define EEPROM_XTAL_111_8822C 0x111 + /* RTL8822CU */ #define EEPROM_MAC_ADDR_8822CU 0x157 #define EEPROM_VID_8822CU 0x100 @@ -705,14 +709,8 @@ #define EEPROM_TX_PWR_INX_8814B 0x10 #define EEPROM_ChannelPlan_8814B 0xB8 #define EEPROM_XTAL_8814B 0xB9 -#define EEPROM_THERMAL_METER_8814B 0xBA #define EEPROM_IQK_LCK_8814B 0xBB -#define EEPROM_PA_TYPE_8814B 0xBC -#define EEPROM_LNA_TYPE_AB_2G_8814B 0xBD -#define EEPROM_LNA_TYPE_CD_2G_8814B 0xBE -#define EEPROM_LNA_TYPE_AB_5G_8814B 0xBF -#define EEPROM_LNA_TYPE_CD_5G_8814B 0xC0 #define EEPROM_RF_BOARD_OPTION_8814B 0xC1 #define EEPROM_RF_FEATURE_OPTION_8814B 0xC2 #define EEPROM_RF_BT_SETTING_8814B 0xC3 @@ -725,6 +723,11 @@ #define EEPROM_RFE_OPTION_8814B 0xCA #define EEPROM_COUNTRY_CODE_8814B 0xCB +#define EEPROM_THERMAL_METER_A_8814B 0xD0 +#define EEPROM_THERMAL_METER_B_8814B 0xD1 +#define EEPROM_THERMAL_METER_C_8814B 0xD2 +#define EEPROM_THERMAL_METER_D_8814B 0xD3 + #define EEPROM_MAC_ADDR_8814BE 0x120 #define EEPROM_VID_8814B 0x126 #define EEPROM_DID_8814B 0x128 @@ -737,6 +740,47 @@ #define EEPROM_PID_8814BU 0x152 #define EEPROM_USB_OPTIONAL_FUNCTION0_8814BU 0x154 +/* + * ==================================================== + * EEPROM/Efuse PG Offset for 8723F + * ==================================================== + */ +#define EEPROM_TX_PWR_INX_8723F 0x10 +#define EEPROM_ChannelPlan_8723F 0xB8 +#define EEPROM_XTAL_B9_8723F 0xB9 +#define EEPROM_THERMAL_METER_8723F 0xBA +#define EEPROM_IQK_LCK_8723F 0xBB +#define EEPROM_2G_5G_PA_TYPE_8723F 0xBC +/* PATH A & PATH B */ +#define EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8723F 0xBD +/* PATH C & PATH D */ +#define EEPROM_2G_LNA_TYPE_GAIN_SEL_CD_8723F 0xBE +/* PATH A & PATH B */ +#define EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8723F 0xBF +/* PATH C & PATH D */ +#define EEPROM_5G_LNA_TYPE_GAIN_SEL_CD_8723F 0xC0 + +#define EEPROM_RF_BOARD_OPTION_8723F 0xC1 +#define EEPROM_FEATURE_OPTION_8723F 0xC2 +#define EEPROM_RF_BT_SETTING_8723F 0xC3 +#define EEPROM_VERSION_8723F 0xC4 +#define EEPROM_CustomID_8723F 0xC5 +#define EEPROM_TX_BBSWING_2G_8723F 0xC6 +#define EEPROM_TX_PWR_CALIBRATE_RATE_8723F 0xC8 +#define EEPROM_RF_ANTENNA_OPT_8723F 0xC9 +#define EEPROM_RFE_OPTION_8723F 0xCA +#define EEPROM_COUNTRY_CODE_8723F 0xCB + +/* RTL8723FU */ +#define EEPROM_MAC_ADDR_8723FU 0x108 +#define EEPROM_VID_8723FU 0x100 +#define EEPROM_PID_8723FU 0x102 +#define EEPROM_USB_OPTIONAL_FUNCTION0_8723FU 0x104 +#define EEPROM_USB_MODE_8723FU 0x03 + +/* RTL8723FS */ +#define EEPROM_MAC_ADDR_8723FS 0x11A + /* **************************************************** * EEPROM/Efuse Value Type * **************************************************** */ @@ -792,6 +836,7 @@ #define EEPROM_Default_ThermalMeter_8188GTV 0x18 #define EEPROM_Default_ThermalMeter_8814A 0x18 #define EEPROM_Default_ThermalMeter_8192F 0x1A +#define EEPROM_Default_ThermalMeter_8814B 0x20 #define EEPROM_Default_CrystalCap 0x0 #define EEPROM_Default_CrystalCap_8723A 0x20 @@ -802,10 +847,13 @@ #define EEPROM_Default_CrystalCap_8723B 0x20 #define EEPROM_Default_CrystalCap_8703B 0x20 #define EEPROM_Default_CrystalCap_8723D 0x20 +#define EEPROM_Default_CrystalCap_8723F 0x3F #define EEPROM_Default_CrystalCap_8188F 0x20 #define EEPROM_Default_CrystalCap_8188GTV 0x20 #define EEPROM_Default_CrystalCap_8192F 0x20 -#define EEPROM_Default_CrystalCap_8822C 0x3F +#define EEPROM_Default_CrystalCap_B9_8822C 0x3F +#define EEPROM_Default_CrystalCap_110_8822C 0x40 +#define EEPROM_Default_CrystalCap_111_8822C 0x40 #define EEPROM_Default_CrystalCap_8814B 0x40 #define EEPROM_Default_CrystalFreq 0x0 #define EEPROM_Default_TxPowerLevel_92C 0x22 @@ -937,6 +985,7 @@ typedef enum _BT_CoType { BT_RTL8192F = 16, BT_RTL8822C = 17, BT_RTL8814B = 18, + BT_RTL8723F = 19, } BT_CoType, *PBT_CoType; typedef enum _BT_RadioShared { diff --git a/include/hal_sdio.h b/include/hal_sdio.h index 9e76f6e..dbdbdca 100644 --- a/include/hal_sdio.h +++ b/include/hal_sdio.h @@ -30,9 +30,9 @@ u32 rtw_hal_get_sdio_tx_max_length(PADAPTER padapter, u8 queue_idx); bool sdio_power_on_check(PADAPTER padapter); #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT -#if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8821A) +#if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) ||defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8723D) void rtw_hal_sdio_avail_page_threshold_init(_adapter *adapter); -void rtw_hal_sdio_avail_page_threshold_en(_adapter *adapter, u8 qidx); +void rtw_hal_sdio_avail_page_threshold_en(_adapter *adapter, u8 qidx, u8 pg_num); #endif #endif /* CONFIG_SDIO_TX_ENABLE_AVAL_INT */ @@ -40,7 +40,7 @@ void rtw_hal_sdio_avail_page_threshold_en(_adapter *adapter, u8 qidx); void sd_c2h_hisr_hdl(_adapter *adapter); #endif -#if defined(CONFIG_RTL8188F) || defined (CONFIG_RTL8188GTV) || defined (CONFIG_RTL8192F) +#if defined(CONFIG_RTL8188F) || defined (CONFIG_RTL8188GTV) || defined (CONFIG_RTL8192F) || defined(CONFIG_RTL8723D) #define SDIO_LOCAL_CMD_ADDR(addr) ((SDIO_LOCAL_DEVICE_ID << 13) | ((addr) & SDIO_LOCAL_MSK)) #endif @@ -81,4 +81,15 @@ void dbg_rtw_sdio_free_xmitbuf_sema_down(struct xmit_priv *xmit, const char *cal #endif /* SDIO_FREE_XMIT_BUF_SEMA */ #endif /* !CONFIG_SDIO_TX_TASKLET */ +s32 sdio_initrecvbuf(struct recv_buf *recvbuf, _adapter *adapter); +void sdio_freerecvbuf(struct recv_buf *recvbuf); + +#ifdef CONFIG_SDIO_RECVBUF_PWAIT +void dump_recvbuf_pwait_conf(void *sel, struct recv_priv *recvpriv); +#ifdef CONFIG_SDIO_RECVBUF_PWAIT_RUNTIME_ADJUST +int recvbuf_pwait_config_req(struct recv_priv *recvpriv, enum rtw_pwait_type type, s32 time, s32 cnt_lmt); +int recvbuf_pwait_config_hdl(struct recv_priv *recvpriv, struct recv_buf *rbuf); +#endif /* CONFIG_SDIO_RECVBUF_PWAIT_RUNTIME_ADJUST */ +#endif /* CONFIG_SDIO_RECVBUF_PWAIT */ + #endif /* __HAL_SDIO_H_ */ diff --git a/include/ieee80211.h b/include/ieee80211.h index fe64b37..62d0f66 100644 --- a/include/ieee80211.h +++ b/include/ieee80211.h @@ -26,7 +26,7 @@ #ifdef CONFIG_AP_MODE -#define RTL_IOCTL_HOSTAPD (SIOCIWFIRSTPRIV + 28) +#define RTL_IOCTL_HOSTAPD (SIOCDEVPRIVATE + 2) /* RTL871X_IOCTL_HOSTAPD ioctl() cmd: */ enum { @@ -55,6 +55,7 @@ enum { RTL871X_HOSTAPD_ACL_ADD_STA = 22, RTL871X_HOSTAPD_ACL_REMOVE_STA = 23, }; +#endif /* CONFIG_AP_MODE */ /* STA flags */ #define WLAN_STA_AUTH BIT(0) @@ -72,10 +73,11 @@ enum { #define WLAN_STA_WPS BIT(12) #define WLAN_STA_MAYBE_WPS BIT(13) #define WLAN_STA_VHT BIT(14) +#define WLAN_STA_WDS BIT(15) +#define WLAN_STA_MULTI_AP BIT(16) +#define WLAN_STA_AMSDU_DISABLE BIT(17) #define WLAN_STA_NONERP BIT(31) -#endif - #define IEEE_CMD_SET_WPA_PARAM 1 #define IEEE_CMD_SET_WPA_IE 2 #define IEEE_CMD_SET_ENCRYPTION 3 @@ -111,7 +113,13 @@ enum { #define WPA_CIPHER_WEP104 BIT(2) #define WPA_CIPHER_TKIP BIT(3) #define WPA_CIPHER_CCMP BIT(4) - +#define WPA_CIPHER_GCMP BIT(5) +#define WPA_CIPHER_GCMP_256 BIT(6) +#define WPA_CIPHER_CCMP_256 BIT(7) +#define WPA_CIPHER_BIP_CMAC_128 BIT(8) +#define WPA_CIPHER_BIP_GMAC_128 BIT(9) +#define WPA_CIPHER_BIP_GMAC_256 BIT(10) +#define WPA_CIPHER_BIP_CMAC_256 BIT(11) #define WPA_SELECTOR_LEN 4 @@ -125,6 +133,9 @@ extern u8 WPA_CIPHER_SUITE_WEP40[]; extern u8 WPA_CIPHER_SUITE_TKIP[]; extern u8 WPA_CIPHER_SUITE_WRAP[]; extern u8 WPA_CIPHER_SUITE_CCMP[]; +extern u8 RSN_CIPHER_SUITE_GCMP[]; +extern u8 RSN_CIPHER_SUITE_GCMP_256[]; +extern u8 RSN_CIPHER_SUITE_CCMP_256[]; extern u8 WPA_CIPHER_SUITE_WEP104[]; @@ -490,12 +501,21 @@ struct rtw_ieee80211s_hdr { } __attribute__((packed)); #endif +/* Some IEEE 802.11x packet types are corresponding to parsing_eapol_packet() */ enum eap_type { EAP_PACKET = 0, + NON_EAPOL, EAPOL_START, EAPOL_LOGOFF, EAPOL_KEY, - EAPOL_ENCAP_ASF_ALERT + EAPOL_ENCAP_ASF_ALERT, + EAPOL_PACKET, + EAPOL_WPA_GROUP_KEY_1_2, + EAPOL_WPA_GROUP_KEY_2_2, + EAPOL_1_4, + EAPOL_2_4, + EAPOL_3_4, + EAPOL_4_4, }; #define IEEE80211_3ADDR_LEN 24 @@ -665,6 +685,7 @@ struct ieee80211_snap_hdr { #define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7 #define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8 #define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 +#define WLAN_REASON_IEEE_802_1X_AUTH_FAILED 23 #define WLAN_REASON_MESH_PEER_CANCELED 52 #define WLAN_REASON_MESH_MAX_PEERS 53 #define WLAN_REASON_MESH_CONFIG 54 @@ -740,6 +761,8 @@ struct ieee80211_snap_hdr { #define WLAN_EID_GENERIC (WLAN_EID_VENDOR_SPECIFIC) #define WLAN_EID_VHT_CAPABILITY 191 #define WLAN_EID_VHT_OPERATION 192 +#define WLAN_EID_WIDE_BANDWIDTH_CHANNEL_SWITCH 194 +#define WLAN_EID_CHANNEL_SWITCH_WRAPPER 196 #define WLAN_EID_VHT_OP_MODE_NOTIFY 199 #define WLAN_EID_EXTENSION 255 #define WLAN_EID_EXT_OWE_DH_PARAM 32 @@ -766,18 +789,19 @@ struct ieee80211_snap_hdr { #define IEEE80211_NUM_OFDM_RATESLEN 8 -#define IEEE80211_CCK_RATE_1MB 0x02 -#define IEEE80211_CCK_RATE_2MB 0x04 -#define IEEE80211_CCK_RATE_5MB 0x0B -#define IEEE80211_CCK_RATE_11MB 0x16 -#define IEEE80211_OFDM_RATE_LEN 8 -#define IEEE80211_OFDM_RATE_6MB 0x0C -#define IEEE80211_OFDM_RATE_9MB 0x12 + +#define IEEE80211_CCK_RATE_1MB 0x02 +#define IEEE80211_CCK_RATE_2MB 0x04 +#define IEEE80211_CCK_RATE_5MB 0x0B +#define IEEE80211_CCK_RATE_11MB 0x16 +#define IEEE80211_OFDM_RATE_LEN 8 +#define IEEE80211_OFDM_RATE_6MB 0x0C +#define IEEE80211_OFDM_RATE_9MB 0x12 #define IEEE80211_OFDM_RATE_12MB 0x18 #define IEEE80211_OFDM_RATE_18MB 0x24 -#define IEEE80211_PBCC_RATE_22MB 0x2C #define IEEE80211_OFDM_RATE_24MB 0x30 -#define IEEE80211_PBCC_RATE_33MB 0x42 +#define IEEE80211_PBCC_RATE_22MB 0x2C +#define IEEE80211_FREAK_RATE_22_5MB 0x2D #define IEEE80211_OFDM_RATE_36MB 0x48 #define IEEE80211_OFDM_RATE_48MB 0x60 #define IEEE80211_OFDM_RATE_54MB 0x6C @@ -930,92 +954,7 @@ enum MGN_RATE { #define IS_3T_RATE(_rate) (IS_HT3SS_RATE((_rate)) || IS_VHT3SS_RATE((_rate))) #define IS_4T_RATE(_rate) (IS_HT4SS_RATE((_rate)) || IS_VHT4SS_RATE((_rate))) -#define MGN_RATE_STR(_rate) \ - (_rate == MGN_1M) ? "CCK_1M" : \ - (_rate == MGN_2M) ? "CCK_2M" : \ - (_rate == MGN_5_5M) ? "CCK_5.5M" : \ - (_rate == MGN_11M) ? "CCK_11M" : \ - (_rate == MGN_6M) ? "OFDM_6M" : \ - (_rate == MGN_9M) ? "OFDM_9M" : \ - (_rate == MGN_12M) ? "OFDM_12M" : \ - (_rate == MGN_18M) ? "OFDM_18M" : \ - (_rate == MGN_24M) ? "OFDM_24M" : \ - (_rate == MGN_36M) ? "OFDM_36M" : \ - (_rate == MGN_48M) ? "OFDM_48M" : \ - (_rate == MGN_54M) ? "OFDM_54M" : \ - (_rate == MGN_MCS32) ? "MCS32" : \ - (_rate == MGN_MCS0) ? "MCS0" : \ - (_rate == MGN_MCS1) ? "MCS1" : \ - (_rate == MGN_MCS2) ? "MCS2" : \ - (_rate == MGN_MCS3) ? "MCS3" : \ - (_rate == MGN_MCS4) ? "MCS4" : \ - (_rate == MGN_MCS5) ? "MCS5" : \ - (_rate == MGN_MCS6) ? "MCS6" : \ - (_rate == MGN_MCS7) ? "MCS7" : \ - (_rate == MGN_MCS8) ? "MCS8" : \ - (_rate == MGN_MCS9) ? "MCS9" : \ - (_rate == MGN_MCS10) ? "MCS10" : \ - (_rate == MGN_MCS11) ? "MCS11" : \ - (_rate == MGN_MCS12) ? "MCS12" : \ - (_rate == MGN_MCS13) ? "MCS13" : \ - (_rate == MGN_MCS14) ? "MCS14" : \ - (_rate == MGN_MCS15) ? "MCS15" : \ - (_rate == MGN_MCS16) ? "MCS16" : \ - (_rate == MGN_MCS17) ? "MCS17" : \ - (_rate == MGN_MCS18) ? "MCS18" : \ - (_rate == MGN_MCS19) ? "MCS19" : \ - (_rate == MGN_MCS20) ? "MCS20" : \ - (_rate == MGN_MCS21) ? "MCS21" : \ - (_rate == MGN_MCS22) ? "MCS22" : \ - (_rate == MGN_MCS23) ? "MCS23" : \ - (_rate == MGN_MCS24) ? "MCS24" : \ - (_rate == MGN_MCS25) ? "MCS25" : \ - (_rate == MGN_MCS26) ? "MCS26" : \ - (_rate == MGN_MCS27) ? "MCS27" : \ - (_rate == MGN_MCS28) ? "MCS28" : \ - (_rate == MGN_MCS29) ? "MCS29" : \ - (_rate == MGN_MCS30) ? "MCS30" : \ - (_rate == MGN_MCS31) ? "MCS31" : \ - (_rate == MGN_VHT1SS_MCS0) ? "VHT1SMCS0" : \ - (_rate == MGN_VHT1SS_MCS1) ? "VHT1SMCS1" : \ - (_rate == MGN_VHT1SS_MCS2) ? "VHT1SMCS2" : \ - (_rate == MGN_VHT1SS_MCS3) ? "VHT1SMCS3" : \ - (_rate == MGN_VHT1SS_MCS4) ? "VHT1SMCS4" : \ - (_rate == MGN_VHT1SS_MCS5) ? "VHT1SMCS5" : \ - (_rate == MGN_VHT1SS_MCS6) ? "VHT1SMCS6" : \ - (_rate == MGN_VHT1SS_MCS7) ? "VHT1SMCS7" : \ - (_rate == MGN_VHT1SS_MCS8) ? "VHT1SMCS8" : \ - (_rate == MGN_VHT1SS_MCS9) ? "VHT1SMCS9" : \ - (_rate == MGN_VHT2SS_MCS0) ? "VHT2SMCS0" : \ - (_rate == MGN_VHT2SS_MCS1) ? "VHT2SMCS1" : \ - (_rate == MGN_VHT2SS_MCS2) ? "VHT2SMCS2" : \ - (_rate == MGN_VHT2SS_MCS3) ? "VHT2SMCS3" : \ - (_rate == MGN_VHT2SS_MCS4) ? "VHT2SMCS4" : \ - (_rate == MGN_VHT2SS_MCS5) ? "VHT2SMCS5" : \ - (_rate == MGN_VHT2SS_MCS6) ? "VHT2SMCS6" : \ - (_rate == MGN_VHT2SS_MCS7) ? "VHT2SMCS7" : \ - (_rate == MGN_VHT2SS_MCS8) ? "VHT2SMCS8" : \ - (_rate == MGN_VHT2SS_MCS9) ? "VHT2SMCS9" : \ - (_rate == MGN_VHT3SS_MCS0) ? "VHT3SMCS0" : \ - (_rate == MGN_VHT3SS_MCS1) ? "VHT3SMCS1" : \ - (_rate == MGN_VHT3SS_MCS2) ? "VHT3SMCS2" : \ - (_rate == MGN_VHT3SS_MCS3) ? "VHT3SMCS3" : \ - (_rate == MGN_VHT3SS_MCS4) ? "VHT3SMCS4" : \ - (_rate == MGN_VHT3SS_MCS5) ? "VHT3SMCS5" : \ - (_rate == MGN_VHT3SS_MCS6) ? "VHT3SMCS6" : \ - (_rate == MGN_VHT3SS_MCS7) ? "VHT3SMCS7" : \ - (_rate == MGN_VHT3SS_MCS8) ? "VHT3SMCS8" : \ - (_rate == MGN_VHT3SS_MCS9) ? "VHT3SMCS9" : \ - (_rate == MGN_VHT4SS_MCS0) ? "VHT4SMCS0" : \ - (_rate == MGN_VHT4SS_MCS1) ? "VHT4SMCS1" : \ - (_rate == MGN_VHT4SS_MCS2) ? "VHT4SMCS2" : \ - (_rate == MGN_VHT4SS_MCS3) ? "VHT4SMCS3" : \ - (_rate == MGN_VHT4SS_MCS4) ? "VHT4SMCS4" : \ - (_rate == MGN_VHT4SS_MCS5) ? "VHT4SMCS5" : \ - (_rate == MGN_VHT4SS_MCS6) ? "VHT4SMCS6" : \ - (_rate == MGN_VHT4SS_MCS7) ? "VHT4SMCS7" : \ - (_rate == MGN_VHT4SS_MCS8) ? "VHT4SMCS8" : \ - (_rate == MGN_VHT4SS_MCS9) ? "VHT4SMCS9" : "UNKNOWN" +const char *MGN_RATE_STR(enum MGN_RATE rate); typedef enum _RATE_SECTION { CCK = 0, @@ -1513,6 +1452,9 @@ enum rtw_ieee80211_category { RTW_WLAN_CATEGORY_SELF_PROTECTED = 15, RTW_WLAN_CATEGORY_WMM = 17, RTW_WLAN_CATEGORY_VHT = 21, +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + RTW_WLAN_CATEGORY_TBTX = 25, +#endif RTW_WLAN_CATEGORY_P2P = 0x7f,/* P2P action frames */ }; @@ -1582,6 +1524,24 @@ enum _PUBLIC_ACTION { ACT_PUBLIC_GAS_COMEBACK_RSP = 13, ACT_PUBLIC_TDLS_DISCOVERY_RSP = 14, ACT_PUBLIC_LOCATION_TRACK = 15, + ACT_PUBLIC_QAB_REQ, + ACT_PUBLIC_QAB_RSP, + ACT_PUBLIC_QMF_POLICY, + ACT_PUBLIC_QMF_POLICY_CHANGE, + ACT_PUBLIC_QLOAD_REQ, + ACT_PUBLIC_QLOAD_REPORT, + ACT_PUBLIC_HCCA_TXOP_ADV, + ACT_PUBLIC_HCCA_TXOP_RSP, + ACT_PUBLIC_PUBLIC_KEY, + ACT_PUBLIC_CH_AVAILABILITY_QUERY, + ACT_PUBLIC_CH_SCHEDULE_MGMT, + ACT_PUBLIC_CONTACT_VERI_SIGNAL, + ACT_PUBLIC_GDD_ENABLE_REQ, + ACT_PUBLIC_GDD_ENABLE_RSP, + ACT_PUBLIC_NETWORK_CH_CONTROL, + ACT_PUBLIC_WHITE_SPACE_MAP_ANN, + ACT_PUBLIC_FTM_REQ, + ACT_PUBLIC_FTM, ACT_PUBLIC_MAX }; @@ -1645,26 +1605,6 @@ enum rtw_ieee80211_vht_actioncode { RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION = 2, }; -/*IEEE 802.11r action code*/ -#ifdef CONFIG_RTW_80211R -enum rtw_ieee80211_ft_actioncode { - RTW_WLAN_ACTION_FT_RESV, - RTW_WLAN_ACTION_FT_REQ, - RTW_WLAN_ACTION_FT_RSP, - RTW_WLAN_ACTION_FT_CONF, - RTW_WLAN_ACTION_FT_ACK, - RTW_WLAN_ACTION_FT_MAX, -}; -#endif - -#ifdef CONFIG_RTW_WNM -enum rtw_ieee80211_wnm_actioncode { - RTW_WLAN_ACTION_WNM_BTM_QUERY = 6, - RTW_WLAN_ACTION_WNM_BTM_REQ = 7, - RTW_WLAN_ACTION_WNM_BTM_RSP = 8, -}; -#endif - #define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs) * 00:50:F2 */ #ifndef PLATFORM_FREEBSD /* Baron BSD has defined */ @@ -1690,6 +1630,9 @@ enum rtw_ieee80211_wnm_actioncode { #define OUI_BROADCOM 0x00904c /* Broadcom (Epigram) */ +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT +#define OUI_REALTEK 0x00e04c /* Realtek */ +#endif #define VENDOR_HT_CAPAB_OUI_TYPE 0x33 /* 00-90-4c:0x33 */ enum rtw_ieee80211_rann_flags { @@ -1875,6 +1818,10 @@ struct rtw_ieee802_11_elems { u8 *rann; u8 rann_len; #endif +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + u8 *tbtx_cap; + u8 tbtx_cap_len; +#endif }; typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes; @@ -1912,6 +1859,18 @@ void rtw_set_supported_rate(u8 *SupportedRates, uint mode) ; #define MFP_OPTIONAL 2 #define MFP_REQUIRED 3 +/*For amsdu mode */ +#define GET_RSN_CAP_SPP_OPT(cap) LE_BITS_TO_2BYTE(((u8 *)(cap)), 10, 2) +#define SET_RSN_CAP_SPP(cap, spp) SET_BITS_TO_LE_2BYTE(((u8 *)(cap)), 10, 2, spp) +#define SPP_CAP BIT(0) +#define SPP_REQ BIT(1) + +enum rtw_amsdu_mode { + RTW_AMSDU_MODE_NON_SPP = 0, + RTW_AMSDU_MODE_SPP = 1, + RTW_AMSDU_MODE_ALL_DROP = 2, +}; + struct rsne_info { u8 *gcs; u16 pcs_cnt; @@ -1930,10 +1889,10 @@ int rtw_rsne_info_parse(const u8 *ie, uint ie_len, struct rsne_info *info); unsigned char *rtw_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit); unsigned char *rtw_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit); int rtw_get_wpa_cipher_suite(u8 *s); -int rtw_get_wpa2_cipher_suite(u8 *s); +int rtw_get_rsn_cipher_suite(u8 *s); int rtw_get_wapi_ie(u8 *in_ie, uint in_len, u8 *wapi_ie, u16 *wapi_len); int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, u32 *akm); -int rtw_parse_wpa2_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, u32 *akm, u8 *mfp_opt); +int rtw_parse_wpa2_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *gmcs, u32 *akm, u8 *mfp_opt, u8* spp_opt); int rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie, u16 *wpa_len); @@ -1955,6 +1914,7 @@ u8 *rtw_get_owe_ie(const u8 *in_ie, uint in_len, u8 *owe_ie, uint *owe_ielen); for (ie = (void *)buf; (((u8 *)ie) - ((u8 *)buf) + 1) < buf_len; ie = (void *)(((u8 *)ie) + *(((u8 *)ie)+1) + 2)) void dump_ies(void *sel, const u8 *buf, u32 buf_len); +#ifdef CONFIG_RTW_DEBUG #ifdef CONFIG_80211N_HT #define HT_SC_OFFSET_MAX 4 @@ -1965,6 +1925,7 @@ void dump_ht_cap_ie_content(void *sel, const u8 *buf, u32 buf_len); #endif void dump_wps_ie(void *sel, const u8 *ie, u32 ie_len); +#endif /* CONFIG_RTW_DEBUG */ void rtw_ies_get_chbw(u8 *ies, int ies_len, u8 *ch, u8 *bw, u8 *offset, u8 ht, u8 vht); @@ -1975,9 +1936,12 @@ bool rtw_is_chbw_grouped(u8 ch_a, u8 bw_a, u8 offset_a void rtw_sync_chbw(u8 *req_ch, u8 *req_bw, u8 *req_offset , u8 *g_ch, u8 *g_bw, u8 *g_offset); +#ifdef CONFIG_P2P u32 rtw_get_p2p_merged_ies_len(u8 *in_ie, u32 in_len); int rtw_p2p_merge_ies(u8 *in_ie, u32 in_len, u8 *merge_ie); +#ifdef CONFIG_RTW_DEBUG void dump_p2p_ie(void *sel, const u8 *ie, u32 ie_len); +#endif u8 *rtw_get_p2p_ie(const u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen); u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id, u8 *buf_attr, u32 *len_attr); u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id, u8 *buf_content, uint *len_content); @@ -1987,16 +1951,32 @@ uint rtw_del_p2p_attr(u8 *ie, uint ielen_ori, u8 attr_id); u8 *rtw_bss_ex_get_p2p_ie(WLAN_BSSID_EX *bss_ex, u8 *p2p_ie, uint *p2p_ielen); void rtw_bss_ex_del_p2p_ie(WLAN_BSSID_EX *bss_ex); void rtw_bss_ex_del_p2p_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id); +#endif /* CONFIG_P2P */ +uint rtw_del_wfd_ie(u8 *ies, uint ies_len_ori, const char *msg); +void rtw_bss_ex_del_wfd_ie(WLAN_BSSID_EX *bss_ex); +#ifdef CONFIG_WFD +#ifdef CONFIG_RTW_DEBUG void dump_wfd_ie(void *sel, const u8 *ie, u32 ie_len); +#endif u8 *rtw_get_wfd_ie(const u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen); u8 *rtw_get_wfd_attr(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id, u8 *buf_attr, u32 *len_attr); u8 *rtw_get_wfd_attr_content(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id, u8 *buf_content, uint *len_content); -uint rtw_del_wfd_ie(u8 *ies, uint ies_len_ori, const char *msg); uint rtw_del_wfd_attr(u8 *ie, uint ielen_ori, u8 attr_id); u8 *rtw_bss_ex_get_wfd_ie(WLAN_BSSID_EX *bss_ex, u8 *wfd_ie, uint *wfd_ielen); -void rtw_bss_ex_del_wfd_ie(WLAN_BSSID_EX *bss_ex); void rtw_bss_ex_del_wfd_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id); +#endif + +#define MULTI_AP_SUB_ELEM_TYPE 0x06 +#define MULTI_AP_TEAR_DOWN BIT(4) +#define MULTI_AP_FRONTHAUL_BSS BIT(5) +#define MULTI_AP_BACKHAUL_BSS BIT(6) +#define MULTI_AP_BACKHAUL_STA BIT(7) +#ifdef CONFIG_RTW_MULTI_AP +void dump_multi_ap_ie(void *sel, const u8 *ie, u32 ie_len); +u8 rtw_get_multi_ap_ie_ext(const u8 *ies, int ies_len); +u8 *rtw_set_multi_ap_ie_ext(u8 *pbuf, uint *frlen, u8 val); +#endif uint rtw_get_rateset_len(u8 *rateset); @@ -2017,6 +1997,8 @@ void rtw_macaddr_cfg(u8 *out, const u8 *hw_mac_addr); u16 rtw_ht_mcs_rate(u8 bw_40MHz, u8 short_GI, unsigned char *MCS_rate); u8 rtw_ht_mcsset_to_nss(u8 *supp_mcs_set); u32 rtw_ht_mcs_set_to_bitmap(u8 *mcs_set, u8 nss); +u8 rtw_ht_cap_get_rx_nss(u8 *ht_cap); +u8 rtw_ht_cap_get_tx_nss(u8 *ht_cap); int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8 *category, u8 *action); const char *action_public_str(u8 action); @@ -2027,5 +2009,8 @@ void macstr2num(u8 *dst, u8 *src); u8 convert_ip_addr(u8 hch, u8 mch, u8 lch); int wifirate2_ratetbl_inx(unsigned char rate); +/* For amsdu mode. */ +/*void rtw_set_spp_amsdu_mode(u8 mode, u8 *rsn_ie, int rsn_ie_len); */ +u8 rtw_check_amsdu_disable(u8 mode, u8 spp_opt); #endif /* IEEE80211_H */ diff --git a/include/mlme_osdep.h b/include/mlme_osdep.h index 81256b5..131eb09 100644 --- a/include/mlme_osdep.h +++ b/include/mlme_osdep.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2019 Realtek Corporation. + * Copyright(c) 2007 - 2017 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -16,7 +16,7 @@ #define __MLME_OSDEP_H_ extern void rtw_os_indicate_disconnect(_adapter *adapter, u16 reason, u8 locally_generated); -extern int rtw_os_indicate_connect(_adapter *adapter); +extern void rtw_os_indicate_connect(_adapter *adapter); void rtw_os_indicate_scan_done(_adapter *padapter, bool aborted); extern void rtw_report_sec_ie(_adapter *adapter, u8 authmode, u8 *sec_ie); diff --git a/include/osdep_intf.h b/include/osdep_intf.h index ed0ebd4..63e535e 100644 --- a/include/osdep_intf.h +++ b/include/osdep_intf.h @@ -90,9 +90,7 @@ void rtw_os_ndevs_unregister(struct dvobj_priv *dvobj); int rtw_os_ndevs_init(struct dvobj_priv *dvobj); void rtw_os_ndevs_deinit(struct dvobj_priv *dvobj); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) -u16 rtw_recv_select_queue(struct sk_buff *skb); -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) */ +u16 rtw_os_recv_select_queue(u8 *msdu, enum rtw_rx_llc_hdl llc_hdl); int rtw_ndev_notifier_register(void); void rtw_ndev_notifier_unregister(void); @@ -100,6 +98,10 @@ void rtw_inetaddr_notifier_register(void); void rtw_inetaddr_notifier_unregister(void); #include "../os_dep/linux/rtw_proc.h" +#include "../os_dep/linux/nlrtw.h" +#ifdef CONFIG_PLATFORM_CMAP_INTFS +#include "../os_dep/linux/custom_multiap_intfs/custom_multiap_intfs.h" +#endif #ifdef CONFIG_IOCTL_CFG80211 #include "../os_dep/linux/ioctl_cfg80211.h" diff --git a/include/osdep_service.h b/include/osdep_service.h index 13929b0..4ec16b5 100644 --- a/include/osdep_service.h +++ b/include/osdep_service.h @@ -30,6 +30,7 @@ #define RTW_XBUF_UNAVAIL 11 #define RTW_TX_BALANCE 12 #define RTW_TX_WAIT_MORE_FRAME 13 +#define RTW_QUEUE_MGMT 14 /* #define RTW_STATUS_TIMEDOUT -110 */ @@ -69,6 +70,9 @@ #ifndef BIT #define BIT(x) (1 << (x)) #endif +#ifndef BIT_ULL +#define BIT_ULL(x) (1ULL << (x)) +#endif #define CHECK_BIT(a, b) (!!((a) & (b))) @@ -309,6 +313,7 @@ u32 rtw_os_pkt_len(_pkt *pkt); extern void _rtw_memcpy(void *dec, const void *sour, u32 sz); extern void _rtw_memmove(void *dst, const void *src, u32 sz); extern int _rtw_memcmp(const void *dst, const void *src, u32 sz); +extern int _rtw_memcmp2(const void *dst, const void *src, u32 sz); extern void _rtw_memset(void *pbuf, int c, u32 sz); extern void _rtw_init_listhead(_list *list); @@ -380,6 +385,30 @@ extern bool _rtw_time_after(systime a, systime b); #define rtw_time_before(a,b) _rtw_time_after(b,a) #endif +sysptime rtw_sptime_get(void); +sysptime rtw_sptime_set(s64 secs, const u32 nsecs); +sysptime rtw_sptime_zero(void); + +int rtw_sptime_cmp(const sysptime cmp1, const sysptime cmp2); +bool rtw_sptime_eql(const sysptime cmp1, const sysptime cmp2); +bool rtw_sptime_is_zero(const sysptime sptime); +sysptime rtw_sptime_sub(const sysptime lhs, const sysptime rhs); +sysptime rtw_sptime_add(const sysptime lhs, const sysptime rhs); + +s64 rtw_sptime_to_ms(const sysptime sptime); +sysptime rtw_ms_to_sptime(u64 ms); +s64 rtw_sptime_to_us(const sysptime sptime); +sysptime rtw_us_to_sptime(u64 us); +s64 rtw_sptime_to_ns(const sysptime sptime); +sysptime rtw_ns_to_sptime(u64 ns); + +s64 rtw_sptime_diff_ms(const sysptime start, const sysptime end); +s64 rtw_sptime_pass_ms(const sysptime start); +s64 rtw_sptime_diff_us(const sysptime start, const sysptime end); +s64 rtw_sptime_pass_us(const sysptime start); +s64 rtw_sptime_diff_ns(const sysptime start, const sysptime end); +s64 rtw_sptime_pass_ns(const sysptime start); + extern void rtw_sleep_schedulable(int ms); extern void rtw_msleep_os(int ms); @@ -399,6 +428,39 @@ extern void rtw_udelay_os(int us); extern void rtw_yield_os(void); +enum rtw_pwait_type { + RTW_PWAIT_TYPE_MSLEEP, + RTW_PWAIT_TYPE_USLEEP, + RTW_PWAIT_TYPE_YIELD, + RTW_PWAIT_TYPE_MDELAY, + RTW_PWAIT_TYPE_UDELAY, + + RTW_PWAIT_TYPE_NUM, +}; + +#define RTW_PWAIT_TYPE_VALID(type) (type < RTW_PWAIT_TYPE_NUM) + +struct rtw_pwait_conf { + enum rtw_pwait_type type; + s32 wait_time; + s32 wait_cnt_lmt; +}; + +struct rtw_pwait_ctx { + struct rtw_pwait_conf conf; + s32 wait_cnt; + void (*wait_hdl)(int us); +}; + +extern const char *_rtw_pwait_type_str[]; +#define rtw_pwait_type_str(type) (RTW_PWAIT_TYPE_VALID(type) ? _rtw_pwait_type_str[type] : _rtw_pwait_type_str[RTW_PWAIT_TYPE_NUM]) + +#define rtw_pwctx_reset(pwctx) (pwctx)->wait_cnt = 0 +#define rtw_pwctx_wait(pwctx) do { (pwctx)->wait_hdl((pwctx)->conf.wait_time); (pwctx)->wait_cnt++; } while(0) +#define rtw_pwctx_waited(pwctx) ((pwctx)->wait_cnt) +#define rtw_pwctx_exceed(pwctx) ((pwctx)->conf.wait_cnt_lmt >= 0 && (pwctx)->wait_cnt >= (pwctx)->conf.wait_cnt_lmt) + +int rtw_pwctx_config(struct rtw_pwait_ctx *pwctx, enum rtw_pwait_type type, s32 time, s32 cnt_lmt); extern void rtw_init_timer(_timer *ptimer, void *padapter, void *pfunc, void *ctx); @@ -596,7 +658,7 @@ static inline int largest_bit_64(u64 bitmask) int i; for (i = 63; i >= 0; i--) - if (bitmask & BIT(i)) + if (bitmask & BIT_ULL(i)) break; return i; @@ -604,6 +666,7 @@ static inline int largest_bit_64(u64 bitmask) #define rtw_abs(a) (a < 0 ? -a : a) #define rtw_min(a, b) ((a > b) ? b : a) +#define rtw_max(a, b) ((a > b) ? a : b) #define rtw_is_range_a_in_b(hi_a, lo_a, hi_b, lo_b) (((hi_a) <= (hi_b)) && ((lo_a) >= (lo_b))) #define rtw_is_range_overlap(hi_a, lo_a, hi_b, lo_b) (((hi_a) > (lo_b)) && ((lo_a) < (hi_b))) @@ -788,11 +851,13 @@ struct blacklist_ent { systime exp_time; }; +#ifdef CONFIG_RTW_MESH int rtw_blacklist_add(_queue *blist, const u8 *addr, u32 timeout_ms); int rtw_blacklist_del(_queue *blist, const u8 *addr); int rtw_blacklist_search(_queue *blist, const u8 *addr); void rtw_blacklist_flush(_queue *blist); void dump_blacklist(void *sel, _queue *blist, const char *title); +#endif /* String handler */ @@ -808,6 +873,8 @@ int hex2num_i(char c); int hex2byte_i(const char *hex); int hexstr2bin(const char *hex, u8 *buf, size_t len); +int hwaddr_aton_i(const char *txt, u8 *addr); + /* * Write formatted output to sized buffer */ diff --git a/include/osdep_service_linux.h b/include/osdep_service_linux.h index ca59daf..fca4cf6 100644 --- a/include/osdep_service_linux.h +++ b/include/osdep_service_linux.h @@ -96,6 +96,10 @@ #ifdef CONFIG_IOCTL_CFG80211 /* #include */ #include +#else + #ifdef CONFIG_REGD_SRC_FROM_OS + #error "CONFIG_REGD_SRC_FROM_OS requires CONFIG_IOCTL_CFG80211" + #endif #endif /* CONFIG_IOCTL_CFG80211 */ @@ -126,11 +130,6 @@ #ifdef CONFIG_USB_HCI typedef struct urb *PURB; - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)) - #ifdef CONFIG_USB_SUSPEND - #define CONFIG_AUTOSUSPEND 1 - #endif - #endif #endif #if defined(CONFIG_RTW_GRO) && (!defined(CONFIG_RTW_NAPI)) @@ -222,6 +221,7 @@ typedef void *timer_hdl_context; #endif typedef unsigned long systime; +typedef ktime_t sysptime; typedef struct tasklet_struct _tasklet; #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)) @@ -351,13 +351,13 @@ __inline static _list *get_list_head(_queue *queue) return &(queue->queue); } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) static inline void timer_hdl(struct timer_list *in_timer) #else static inline void timer_hdl(unsigned long cntx) #endif { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) _timer *ptimer = from_timer(ptimer, in_timer, timer); #else _timer *ptimer = (_timer *)cntx; @@ -370,7 +370,7 @@ __inline static void _init_timer(_timer *ptimer, _nic_hdl nic_hdl, void *pfunc, ptimer->function = pfunc; ptimer->arg = cntx; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) timer_setup(&ptimer->timer, timer_hdl, 0); #else /* setup_timer(ptimer, pfunc,(u32)cntx); */ @@ -390,6 +390,11 @@ __inline static void _cancel_timer(_timer *ptimer, u8 *bcancelled) *bcancelled = del_timer_sync(&ptimer->timer) == 1 ? 1 : 0; } +__inline static void _cancel_timer_async(_timer *ptimer) +{ + del_timer(&ptimer->timer); +} + static inline void _init_workitem(_workitem *pwork, void *pfunc, void *cntx) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)) diff --git a/include/pci_osintf.h b/include/pci_osintf.h index 3308ced..077064a 100644 --- a/include/pci_osintf.h +++ b/include/pci_osintf.h @@ -15,7 +15,7 @@ #ifndef __PCI_OSINTF_H #define __PCI_OSINTF_H -#ifdef RTK_129X_PLATFORM +#ifdef CONFIG_PLATFORM_RTK129X #define PCIE_SLOT1_MEM_START 0x9804F000 #define PCIE_SLOT1_MEM_LEN 0x1000 #define PCIE_SLOT1_CTRL_START 0x9804EC00 @@ -38,9 +38,6 @@ void PlatformClearPciPMEStatus(PADAPTER Adapter); void rtw_pci_aspm_config(_adapter *padapter); void rtw_pci_aspm_config_l1off_general(_adapter *padapter, u8 eanble); -#ifdef CONFIG_64BIT_DMA - u8 PlatformEnableDMA64(PADAPTER Adapter); -#endif #ifdef CONFIG_PCI_DYNAMIC_ASPM void rtw_pci_set_aspm_lnkctl(_adapter *padapter, u8 mode); void rtw_pci_set_l1_latency(_adapter *padapter, u8 mode); diff --git a/include/recv_osdep.h b/include/recv_osdep.h index 733a3e7..4521c00 100644 --- a/include/recv_osdep.h +++ b/include/recv_osdep.h @@ -25,7 +25,9 @@ void rtw_rframe_set_os_pkt(union recv_frame *rframe); extern int rtw_recv_indicatepkt(_adapter *adapter, union recv_frame *precv_frame); extern void rtw_recv_returnpacket(_nic_hdl cnxt, _pkt *preturnedpkt); +#ifdef CONFIG_WIFI_MONITOR extern int rtw_recv_monitor(_adapter *padapter, union recv_frame *precv_frame); +#endif /* CONFIG_WIFI_MONITOR */ #ifdef CONFIG_HOSTAPD_MLME extern void rtw_hostapd_mlme_rx(_adapter *padapter, union recv_frame *precv_frame); @@ -45,10 +47,11 @@ int rtw_os_recvframe_duplicate_skb(_adapter *padapter, union recv_frame *pclonef void rtw_os_free_recvframe(union recv_frame *precvframe); -int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf); +int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf, u32 size); int rtw_os_recvbuf_resource_free(_adapter *padapter, struct recv_buf *precvbuf); -_pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, const u8 *da, const u8 *sa, u8 *msdu ,u16 msdu_len); +_pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, const u8 *da, const u8 *sa + , u8 *msdu ,u16 msdu_len, enum rtw_rx_llc_hdl llc_hdl); void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, union recv_frame *rframe); void rtw_os_read_port(_adapter *padapter, struct recv_buf *precvbuf); diff --git a/include/rtl8188e_hal.h b/include/rtl8188e_hal.h index 611cc73..9665896 100644 --- a/include/rtl8188e_hal.h +++ b/include/rtl8188e_hal.h @@ -138,8 +138,13 @@ typedef struct _RT_8188E_FIRMWARE_HDR { /* For WoWLan , more reserved page */ #ifdef CONFIG_WOWLAN + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + #define WOWLAN_KEEP_ALIVE_PAGE 0x02 /*for keep alive packet*/ + #else + #define WOWLAN_KEEP_ALIVE_PAGE 0x00 + #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ /* 1 ArpRsp + 2 NbrAdv + 2 NDPInfo + 1 RCI + 1 AOAC = 7 pages */ - #define WOWLAN_PAGE_NUM_88E 0x07 + #define WOWLAN_PAGE_NUM_88E (0x07+ WOWLAN_KEEP_ALIVE_PAGE) #else #define WOWLAN_PAGE_NUM_88E 0x00 #endif diff --git a/include/rtl8188e_xmit.h b/include/rtl8188e_xmit.h index f625576..bf8bf36 100644 --- a/include/rtl8188e_xmit.h +++ b/include/rtl8188e_xmit.h @@ -238,15 +238,16 @@ struct txrpt_ccx_88e { void rtl8188e_fill_fake_txdesc(PADAPTER padapter, u8 *pDesc, u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame); void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc); -#if defined(CONFIG_CONCURRENT_MODE) - void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc); -#endif +void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc); #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) s32 rtl8188es_init_xmit_priv(PADAPTER padapter); void rtl8188es_free_xmit_priv(PADAPTER padapter); s32 rtl8188es_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8188es_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8188es_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8188es_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); thread_return rtl8188es_xmit_thread(thread_context context); s32 rtl8188es_xmit_buf_handler(PADAPTER padapter); @@ -261,6 +262,9 @@ void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc); void rtl8188eu_free_xmit_priv(PADAPTER padapter); s32 rtl8188eu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8188eu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8188eu_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8188eu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8188eu_xmit_buf_handler(PADAPTER padapter); void rtl8188eu_xmit_tasklet(void *priv); @@ -273,6 +277,9 @@ void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc); void rtl8188ee_xmitframe_resume(_adapter *padapter); s32 rtl8188ee_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8188ee_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8188ee_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8188ee_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8188ee_xmit_tasklet(void *priv); #endif diff --git a/include/rtl8188f_cmd.h b/include/rtl8188f_cmd.h index a90a630..6f33708 100644 --- a/include/rtl8188f_cmd.h +++ b/include/rtl8188f_cmd.h @@ -189,12 +189,6 @@ void rtl8188f_download_rsvd_page(PADAPTER padapter, u8 mstatus); void rtl8188f_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); #endif /* CONFIG_P2P */ -#ifdef CONFIG_TDLS -#ifdef CONFIG_TDLS_CH_SW -void rtl8188f_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); -#endif -#endif - #ifdef CONFIG_P2P_WOWLAN void rtl8188f_set_p2p_wowlan_offload_cmd(PADAPTER padapter); #endif diff --git a/include/rtl8188f_recv.h b/include/rtl8188f_recv.h index ca06598..44b51fd 100644 --- a/include/rtl8188f_recv.h +++ b/include/rtl8188f_recv.h @@ -21,9 +21,7 @@ #ifdef CONFIG_MINIMAL_MEMORY_USAGE #define MAX_RECVBUF_SZ (4000) /* about 4K */ #else - #ifdef CONFIG_PLATFORM_MSTAR - #define MAX_RECVBUF_SZ (8192) /* 8K */ - #elif defined(CONFIG_PLATFORM_HISILICON) + #ifdef CONFIG_PLATFORM_HISILICON #define MAX_RECVBUF_SZ (16384) /* 16k */ #else #define MAX_RECVBUF_SZ (32768) /* 32k */ @@ -37,7 +35,8 @@ #elif defined(CONFIG_PCI_HCI) #define MAX_RECVBUF_SZ (4000) /* about 4K */ #elif defined(CONFIG_SDIO_HCI) - #define MAX_RECVBUF_SZ (RX_DMA_BOUNDARY_8188F + 1) + /* minmum 4K, multiple of 8-byte is required, multiple of sdio block size is prefered */ + #define MAX_RECVBUF_SZ _RND(RX_DMA_BOUNDARY_8188F + 1, 8) #endif /* CONFIG_SDIO_HCI */ /* Rx smooth factor */ diff --git a/include/rtl8188f_xmit.h b/include/rtl8188f_xmit.h index 40493ce..7dafd9e 100644 --- a/include/rtl8188f_xmit.h +++ b/include/rtl8188f_xmit.h @@ -287,15 +287,16 @@ void rtl8188f_update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem); void rtl8188f_fill_fake_txdesc(PADAPTER padapter, u8 *pDesc, u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame); -#if defined(CONFIG_CONCURRENT_MODE) void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc); -#endif #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) s32 rtl8188fs_init_xmit_priv(PADAPTER padapter); void rtl8188fs_free_xmit_priv(PADAPTER padapter); s32 rtl8188fs_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8188fs_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtl8188fs_hal_mgmt_xmitframe_enqueue(PADAPTER, struct xmit_frame *); +#endif s32 rtl8188fs_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8188fs_xmit_buf_handler(PADAPTER padapter); thread_return rtl8188fs_xmit_thread(thread_context context); @@ -312,6 +313,9 @@ s32 rtl8188fu_init_xmit_priv(PADAPTER padapter); void rtl8188fu_free_xmit_priv(PADAPTER padapter); s32 rtl8188fu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8188fu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtl8188fu_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8188fu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); /* s32 rtl8812au_xmit_buf_handler(PADAPTER padapter); */ void rtl8188fu_xmit_tasklet(void *priv); diff --git a/include/rtl8192e_cmd.h b/include/rtl8192e_cmd.h index 5efdf99..a9c8be8 100644 --- a/include/rtl8192e_cmd.h +++ b/include/rtl8192e_cmd.h @@ -126,12 +126,6 @@ s32 c2h_handler_8192e(_adapter *adapter, u8 id, u8 seq, u8 plen, u8 *payload); void rtl8192e_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); #endif /* CONFIG_P2P */ -#ifdef CONFIG_TDLS - #ifdef CONFIG_TDLS_CH_SW - void rtl8192e_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); - #endif -#endif - /* / TX Feedback Content */ #define USEC_UNIT_FOR_8192E_C2H_TX_RPT_QUEUE_TIME 256 diff --git a/include/rtl8192e_xmit.h b/include/rtl8192e_xmit.h index 559eefe..f84c6fa 100644 --- a/include/rtl8192e_xmit.h +++ b/include/rtl8192e_xmit.h @@ -358,6 +358,9 @@ void rtl8192e_cal_txdesc_chksum(u8 *ptxdesc); void rtl8192eu_free_xmit_priv(PADAPTER padapter); s32 rtl8192eu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8192eu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8192eu_hal_mgmt_xmitframe_enqueue(PADAPTER padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8192eu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8192eu_xmit_buf_handler(PADAPTER padapter); #define hal_xmit_handler rtl8192eu_xmit_buf_handler @@ -369,6 +372,9 @@ void rtl8192e_cal_txdesc_chksum(u8 *ptxdesc); s32 rtl8192ee_init_xmit_priv(PADAPTER padapter); void rtl8192ee_free_xmit_priv(PADAPTER padapter); struct xmit_buf *rtl8192ee_dequeue_xmitbuf(struct rtw_tx_ring *ring); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8192ee_hal_mgmt_xmitframe_enqueue(PADAPTER padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8192ee_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8192ee_xmitframe_resume(_adapter *padapter); s32 rtl8192ee_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); @@ -382,6 +388,9 @@ void rtl8192e_cal_txdesc_chksum(u8 *ptxdesc); s32 rtl8192es_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8192es_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8192es_hal_mgmt_xmitframe_enqueue(PADAPTER padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8192es_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); thread_return rtl8192es_xmit_thread(thread_context context); s32 rtl8192es_xmit_buf_handler(PADAPTER padapter); @@ -439,9 +448,7 @@ u8 BWMapping_92E(PADAPTER Adapter, struct pkt_attrib *pattrib); u8 SCMapping_92E(PADAPTER Adapter, struct pkt_attrib *pattrib); void fill_txdesc_phy(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc); void fill_txdesc_vcs(struct pkt_attrib *pattrib, u8 *ptxdesc); -#if defined(CONFIG_CONCURRENT_MODE) - void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc); -#endif +void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc); void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void fill_txdesc_sectype(struct pkt_attrib *pattrib, u8 *ptxdesc); diff --git a/include/rtl8192f_cmd.h b/include/rtl8192f_cmd.h index 69ee674..44ea670 100644 --- a/include/rtl8192f_cmd.h +++ b/include/rtl8192f_cmd.h @@ -179,16 +179,35 @@ void rtl8192f_download_BTCoex_AP_mode_rsvd_page(PADAPTER padapter); void rtl8192f_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); #endif /* CONFIG_P2P */ -#ifdef CONFIG_TDLS -#ifdef CONFIG_TDLS_CH_SW -void rtl8192f_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); -#endif -#endif - #ifdef CONFIG_P2P_WOWLAN void rtl8192f_set_p2p_wowlan_offload_cmd(PADAPTER padapter); #endif +/* AP_REQ_TXREP_CMD 0x43 */ +#define SET_8192F_H2CCMD_TXREP_PARM_STA1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8192F_H2CCMD_TXREP_PARM_STA2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_8192F_H2CCMD_TXREP_PARM_RTY(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 2, __Value) + +/* C2H_AP_REQ_TXRPT */ +#define GET_8192F_C2H_TC2H_APREQ_TXRPT_MACID1(_Header) LE_BITS_TO_1BYTE((_Header + 0), 0, 8) +#define GET_8192F_C2H_TC2H_APREQ_TXRPT_TXOK1(_Header) LE_BITS_TO_2BYTE((_Header + 1), 0, 16) +#define GET_8192F_C2H_TC2H_APREQ_TXRPT_TXFAIL1(_Header) LE_BITS_TO_2BYTE((_Header + 3), 0, 16) +#define GET_8192F_C2H_TC2H_APREQ_TXRPT_INIRATE1(_Header) LE_BITS_TO_1BYTE((_Header + 5), 0, 8) +#define GET_8192F_C2H_TC2H_APREQ_TXRPT_MACID2(_Header) LE_BITS_TO_1BYTE((_Header + 6), 0, 8) +#define GET_8192F_C2H_TC2H_APREQ_TXRPT_TXOK2(_Header) LE_BITS_TO_2BYTE((_Header + 7), 0, 16) +#define GET_8192F_C2H_TC2H_APREQ_TXRPT_TXFAIL2(_Header) LE_BITS_TO_2BYTE((_Header + 9), 0, 16) +#define GET_8192F_C2H_TC2H_APREQ_TXRPT_INIRATE2(_Header) LE_BITS_TO_1BYTE((_Header + 11), 0, 8) + +/* C2H_SPC_STAT */ +#define GET_8192F_C2H_SPC_STAT_IDX(_Header) LE_BITS_TO_1BYTE((_Header + 0), 0, 8) + /* Tip :TYPE_A data3 is msb and data0 is lsb */ +#define GET_8192F_C2H_SPC_STAT_TYPEA_RETRY(_Header) LE_BITS_TO_4BYTE((_Header + 1), 0, 32) +#define GET_8192F_C2H_SPC_STAT_TYPEB_PKT1(_Header) LE_BITS_TO_2BYTE((_Header + 1), 0, 16) +#define GET_8192F_C2H_SPC_STAT_TYPEB_RETRY1(_Header) LE_BITS_TO_2BYTE((_Header + 3), 0, 16) +#define GET_8192F_C2H_SPC_STAT_TYPEB_PKT2(_Header) LE_BITS_TO_2BYTE((_Header + 5), 0, 16) +#define GET_8192F_C2H_SPC_STAT_TYPEB_RETRY2(_Header) LE_BITS_TO_2BYTE((_Header + 7), 0, 16) + +void rtl8192f_req_txrpt_cmd(PADAPTER, u8 macid); s32 FillH2CCmd8192F(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); u8 GetTxBufferRsvdPageNum8192F(_adapter *padapter, bool wowlan); #endif diff --git a/include/rtl8192f_dm.h b/include/rtl8192f_dm.h index 43e6396..36ed77b 100644 --- a/include/rtl8192f_dm.h +++ b/include/rtl8192f_dm.h @@ -23,5 +23,7 @@ void rtl8192f_HalDmWatchDog(PADAPTER Adapter); /* void rtl8192c_dm_CheckTXPowerTracking(PADAPTER Adapter); */ /* void rtl8192c_dm_RF_Saving(PADAPTER pAdapter, u8 bForceInNormal); */ - +#if defined (CONFIG_CONCURRENT_MODE) && defined (CONFIG_TSF_SYNC) +void rtl8192f_sync_tsfr(_adapter *Adapter); +#endif/*(CONFIG_CONCURRENT_MODE) && defined (CONFIG_TSF_SYNC)*/ #endif diff --git a/include/rtl8192f_hal.h b/include/rtl8192f_hal.h index 73ee785..e7d6db5 100644 --- a/include/rtl8192f_hal.h +++ b/include/rtl8192f_hal.h @@ -117,12 +117,23 @@ typedef struct _RT_8192F_FIRMWARE_HDR { * NS offload: 2 NDP info: 1 */ #ifdef CONFIG_WOWLAN + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + #define WOWLAN_KEEP_ALIVE_PAGE 0x02 /*for keep alive packet*/ + #else + #define WOWLAN_KEEP_ALIVE_PAGE 0x00 + #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ /* 7 pages for wow rsvd page + 2 pages for pattern */ - #define WOWLAN_PAGE_NUM_8192F 0x09 + #define WOWLAN_PAGE_NUM_8192F (0x09 + WOWLAN_KEEP_ALIVE_PAGE) #else #define WOWLAN_PAGE_NUM_8192F 0x00 #endif +#ifdef CONFIG_WOW_PATTERN_IN_TXFIFO + /* REG_TXBUF_WKCAM_OFFSET 0x1B1[15:0] */ + #define WKCAM_OFFSET_BIT_MASK 0xFFFF + #define WKCAM_OFFSET_BIT_MASK_OFFSET 0 +#endif + #ifdef CONFIG_PNO_SUPPORT #undef WOWLAN_PAGE_NUM_8192F #define WOWLAN_PAGE_NUM_8192F 0x15 diff --git a/include/rtl8192f_led.h b/include/rtl8192f_led.h index 22530b4..0dbb27c 100644 --- a/include/rtl8192f_led.h +++ b/include/rtl8192f_led.h @@ -24,6 +24,23 @@ * Interface to manipulate LED objects. * ******************************************************************************** */ #ifdef CONFIG_USB_HCI +/** REG_LED_CFG (0x4C) **/ +/* LED0 GPIO Enable, 0: disable, 1: enable*/ +#define LED0_GPIO_ENABLE_8192FU (BIT21) +/* LED0 Disabled for analog signal usage, 0:Enable (output mode), 1: disable (input mode) */ +#define LED0_DISABLE_ANALOGSIGNAL_8192FU (BIT7) +/* LED0 software value, 0: turn off, 1:turn on */ +#define LED0_SW_VALUE_8192FU (BIT3) + +/** REG_GPIO_MUXCFG (0x40) **/ +/* Enable LED[1:0] for RFE CTRL[7:6], 0: BT, 1: Wi-Fi */ +#define ENABLE_LED0_AND_LED1_CTRL_BY_WIFI_8192FU (BIT3) + +/** REG_SW_GPIO_SHARE_CTRL_0 (0x1038) **/ +/* LED Output PIN Location, 0: GPIOA_0, 1:GPIOB_4*/ +#define LED_OUTPUT_PIN_LOCATION_8192FU (BIT16) + +u8 rtl8192fu_CfgLed0Hw(PADAPTER padapter); void rtl8192fu_InitSwLeds(PADAPTER padapter); void rtl8192fu_DeInitSwLeds(PADAPTER padapter); #endif diff --git a/include/rtl8192f_rf.h b/include/rtl8192f_rf.h index 364df6a..2f6c917 100644 --- a/include/rtl8192f_rf.h +++ b/include/rtl8192f_rf.h @@ -21,13 +21,6 @@ #define CONFIG_8192F_TYPE3_DRV_DIS #define CONFIG_8192F_TYPE4_DRV_DIS /*unused*/ -#define CONFIG_8192F_TYPE13_DRV_DIS -#define CONFIG_8192F_TYPE14_DRV_DIS -#define CONFIG_8192F_TYPE15_DRV_DIS -#define CONFIG_8192F_TYPE16_DRV_DIS -#define CONFIG_8192F_TYPE17_DRV_DIS -#define CONFIG_8192F_TYPE18_DRV_DIS -#define CONFIG_8192F_TYPE19_DRV_DIS #define CONFIG_8192F_TYPE20_DRV_DIS #define CONFIG_8192F_TYPE21_DRV_DIS #define CONFIG_8192F_TYPE22_DRV_DIS @@ -47,6 +40,8 @@ #define CONFIG_8192F_TYPE1_DRV_DIS #define CONFIG_8192F_TYPE5_DRV_DIS #define CONFIG_8192F_TYPE10_DRV_DIS +#define CONFIG_8192F_TYPE13_DRV_DIS +#define CONFIG_8192F_TYPE14_DRV_DIS /*pcie*/ #define CONFIG_8192F_TYPE0_DRV_DIS #define CONFIG_8192F_TYPE6_DRV_DIS @@ -54,6 +49,11 @@ #define CONFIG_8192F_TYPE8_DRV_DIS #define CONFIG_8192F_TYPE9_DRV_DIS #define CONFIG_8192F_TYPE12_DRV_DIS +#define CONFIG_8192F_TYPE15_DRV_DIS +#define CONFIG_8192F_TYPE16_DRV_DIS +#define CONFIG_8192F_TYPE17_DRV_DIS +#define CONFIG_8192F_TYPE18_DRV_DIS +#define CONFIG_8192F_TYPE19_DRV_DIS #endif/*CONFIG_SDIO_HCI*/ #ifdef CONFIG_USB_HCI @@ -67,6 +67,11 @@ #define CONFIG_8192F_TYPE8_DRV_DIS #define CONFIG_8192F_TYPE9_DRV_DIS #define CONFIG_8192F_TYPE12_DRV_DIS +#define CONFIG_8192F_TYPE15_DRV_DIS +#define CONFIG_8192F_TYPE16_DRV_DIS +#define CONFIG_8192F_TYPE17_DRV_DIS +#define CONFIG_8192F_TYPE18_DRV_DIS +#define CONFIG_8192F_TYPE19_DRV_DIS #endif/*CONFIG_USB_HCI*/ #ifdef CONFIG_PCI_HCI @@ -77,6 +82,8 @@ #define CONFIG_8192F_TYPE1_DRV_DIS #define CONFIG_8192F_TYPE5_DRV_DIS #define CONFIG_8192F_TYPE10_DRV_DIS +#define CONFIG_8192F_TYPE13_DRV_DIS +#define CONFIG_8192F_TYPE14_DRV_DIS #endif/*CONFIG_PCI_HCI*/ int PHY_RF6052_Config8192F(PADAPTER pdapter); diff --git a/include/rtl8192f_spec.h b/include/rtl8192f_spec.h index cf5e276..b34d944 100644 --- a/include/rtl8192f_spec.h +++ b/include/rtl8192f_spec.h @@ -144,6 +144,7 @@ #define REG_RQPN_NPQ_8192F 0x0214 #define REG_DWBCN1_CTRL_8192F 0x0228 #define REG_RQPN_EXQ1_EXQ2 0x0230 +#define REG_TQPNT3_V1_8192F 0x0234 /* ----------------------------------------------------- * @@ -397,7 +398,8 @@ #define REG_LTR_ACTIVE_LATENCY_V1_8192F 0x079C /* GPIO Control */ -#define REG_SW_GPIO_SHARE_CTRL_8192F 0x1038 +#define REG_SW_GPIO_SHARE_CTRL_8192F_0 0x1038 +#define REG_SW_GPIO_SHARE_CTRL_8192F_1 0x103c #define REG_SW_GPIO_A_OUT_8192F 0x1040 #define REG_SW_GPIO_A_OEN_8192F 0x1044 diff --git a/include/rtl8192f_xmit.h b/include/rtl8192f_xmit.h index 6e0f1ea..1763f57 100644 --- a/include/rtl8192f_xmit.h +++ b/include/rtl8192f_xmit.h @@ -485,9 +485,7 @@ void rtl8192f_fill_txdesc_vcs(PADAPTER padapter, struct pkt_attrib *pattrib, str void rtl8192f_fill_txdesc_phy(PADAPTER padapter, struct pkt_attrib *pattrib, struct tx_desc *ptxdesc); void rtl8192f_fill_fake_txdesc(PADAPTER padapter, u8 *pDesc, u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame); -#if defined(CONFIG_CONCURRENT_MODE) - void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc); -#endif +void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc); void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) @@ -495,6 +493,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8192fs_free_xmit_priv(PADAPTER padapter); s32 rtl8192fs_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8192fs_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8192fs_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8192fs_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8192fs_xmit_buf_handler(PADAPTER padapter); thread_return rtl8192fs_xmit_thread(thread_context context); @@ -506,6 +507,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8192fu_free_xmit_priv(PADAPTER padapter); s32 rtl8192fu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8192fu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8192fu_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8192fu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8192fu_xmit_buf_handler(PADAPTER padapter); #define hal_xmit_handler rtl8192fu_xmit_buf_handler @@ -521,6 +525,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8192fe_xmitframe_resume(_adapter *padapter); s32 rtl8192fe_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8192fe_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8192fe_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8192fe_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8192fe_xmit_tasklet(void *priv); #endif diff --git a/include/rtl8703b_cmd.h b/include/rtl8703b_cmd.h index 0b2bd83..522a3bc 100644 --- a/include/rtl8703b_cmd.h +++ b/include/rtl8703b_cmd.h @@ -188,12 +188,6 @@ void rtl8703b_download_rsvd_page(PADAPTER padapter, u8 mstatus); void rtl8703b_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); #endif /* CONFIG_P2P */ -#ifdef CONFIG_TDLS - #ifdef CONFIG_TDLS_CH_SW - void rtl8703b_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); - #endif -#endif - #ifdef CONFIG_P2P_WOWLAN void rtl8703b_set_p2p_wowlan_offload_cmd(PADAPTER padapter); #endif diff --git a/include/rtl8703b_xmit.h b/include/rtl8703b_xmit.h index 40c7bb2..9ec00a6 100644 --- a/include/rtl8703b_xmit.h +++ b/include/rtl8703b_xmit.h @@ -286,9 +286,7 @@ void rtl8703b_update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem); void rtl8703b_fill_fake_txdesc(PADAPTER padapter, u8 *pDesc, u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame); -#if defined(CONFIG_CONCURRENT_MODE) - void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc); -#endif +void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc); void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) @@ -296,6 +294,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8703bs_free_xmit_priv(PADAPTER padapter); s32 rtl8703bs_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8703bs_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8703bs_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8703bs_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8703bs_xmit_buf_handler(PADAPTER padapter); thread_return rtl8703bs_xmit_thread(thread_context context); @@ -311,6 +312,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8703bu_free_xmit_priv(PADAPTER padapter); s32 rtl8703bu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8703bu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8703bu_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8703bu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); /* s32 rtl8812au_xmit_buf_handler(PADAPTER padapter); */ void rtl8703bu_xmit_tasklet(void *priv); @@ -325,6 +329,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8703be_xmitframe_resume(_adapter *padapter); s32 rtl8703be_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8703be_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8703be_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8703be_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8703be_xmit_tasklet(void *priv); #endif diff --git a/include/rtl8710b_cmd.h b/include/rtl8710b_cmd.h index 20d4ff9..0237d18 100644 --- a/include/rtl8710b_cmd.h +++ b/include/rtl8710b_cmd.h @@ -160,12 +160,6 @@ void rtl8710b_download_rsvd_page(PADAPTER padapter, u8 mstatus); void rtl8710b_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); #endif /* CONFIG_P2P */ -#ifdef CONFIG_TDLS -#ifdef CONFIG_TDLS_CH_SW -void rtl8710b_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); -#endif -#endif - #ifdef CONFIG_P2P_WOWLAN void rtl8710b_set_p2p_wowlan_offload_cmd(PADAPTER padapter); #endif diff --git a/include/rtl8710b_xmit.h b/include/rtl8710b_xmit.h index a6b49cd..b3ec6f5 100644 --- a/include/rtl8710b_xmit.h +++ b/include/rtl8710b_xmit.h @@ -476,9 +476,7 @@ void rtl8710b_fill_txdesc_vcs(PADAPTER padapter, struct pkt_attrib *pattrib, str void rtl8710b_fill_txdesc_phy(PADAPTER padapter, struct pkt_attrib *pattrib, struct tx_desc *ptxdesc); void rtl8710b_fill_fake_txdesc(PADAPTER padapter, u8 *pDesc, u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame); -#if defined(CONFIG_CONCURRENT_MODE) - void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc); -#endif +void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc); void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) @@ -499,6 +497,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8710bu_free_xmit_priv(PADAPTER padapter); s32 rtl8710bu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8710bu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8710bu_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8710bu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8710bu_xmit_tasklet(void *priv); s32 rtl8710bu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); diff --git a/include/rtl8723b_cmd.h b/include/rtl8723b_cmd.h index 9da5633..d4da956 100644 --- a/include/rtl8723b_cmd.h +++ b/include/rtl8723b_cmd.h @@ -188,12 +188,6 @@ void rtl8723b_download_rsvd_page(PADAPTER padapter, u8 mstatus); void rtl8723b_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); #endif /* CONFIG_P2P */ -#ifdef CONFIG_TDLS - #ifdef CONFIG_TDLS_CH_SW - void rtl8723b_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); - #endif -#endif - #ifdef CONFIG_P2P_WOWLAN void rtl8723b_set_p2p_wowlan_offload_cmd(PADAPTER padapter); #endif diff --git a/include/rtl8723b_hal.h b/include/rtl8723b_hal.h old mode 100755 new mode 100644 diff --git a/include/rtl8723b_led.h b/include/rtl8723b_led.h old mode 100755 new mode 100644 diff --git a/include/rtl8723b_recv.h b/include/rtl8723b_recv.h old mode 100755 new mode 100644 diff --git a/include/rtl8723b_spec.h b/include/rtl8723b_spec.h old mode 100755 new mode 100644 diff --git a/include/rtl8723b_xmit.h b/include/rtl8723b_xmit.h old mode 100755 new mode 100644 index 22b3bac..51691e9 --- a/include/rtl8723b_xmit.h +++ b/include/rtl8723b_xmit.h @@ -286,9 +286,7 @@ void rtl8723b_update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem); void rtl8723b_fill_fake_txdesc(PADAPTER padapter, u8 *pDesc, u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame); -#if defined(CONFIG_CONCURRENT_MODE) - void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc); -#endif +void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc); void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) @@ -296,6 +294,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8723bs_free_xmit_priv(PADAPTER padapter); s32 rtl8723bs_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8723bs_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8723bs_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8723bs_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8723bs_xmit_buf_handler(PADAPTER padapter); thread_return rtl8723bs_xmit_thread(thread_context context); @@ -311,6 +312,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8723bu_free_xmit_priv(PADAPTER padapter); s32 rtl8723bu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8723bu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8723bu_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8723bu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); /* s32 rtl8812au_xmit_buf_handler(PADAPTER padapter); */ void rtl8723bu_xmit_tasklet(void *priv); @@ -325,6 +329,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8723be_xmitframe_resume(_adapter *padapter); s32 rtl8723be_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8723be_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8723be_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8723be_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8723be_xmit_tasklet(void *priv); #endif diff --git a/include/rtl8723d_cmd.h b/include/rtl8723d_cmd.h index 41c6cb9..9c65b4b 100644 --- a/include/rtl8723d_cmd.h +++ b/include/rtl8723d_cmd.h @@ -174,12 +174,6 @@ void rtl8723d_download_rsvd_page(PADAPTER padapter, u8 mstatus); void rtl8723d_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); #endif /* CONFIG_P2P */ -#ifdef CONFIG_TDLS -#ifdef CONFIG_TDLS_CH_SW -void rtl8723d_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); -#endif -#endif - #ifdef CONFIG_P2P_WOWLAN void rtl8723d_set_p2p_wowlan_offload_cmd(PADAPTER padapter); #endif diff --git a/include/rtl8723d_xmit.h b/include/rtl8723d_xmit.h index b1636ad..91fb52c 100644 --- a/include/rtl8723d_xmit.h +++ b/include/rtl8723d_xmit.h @@ -477,9 +477,7 @@ void rtl8723d_fill_txdesc_vcs(PADAPTER padapter, struct pkt_attrib *pattrib, str void rtl8723d_fill_txdesc_phy(PADAPTER padapter, struct pkt_attrib *pattrib, struct tx_desc *ptxdesc); void rtl8723d_fill_fake_txdesc(PADAPTER padapter, u8 *pDesc, u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame); -#if defined(CONFIG_CONCURRENT_MODE) - void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc); -#endif +void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc); void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) @@ -487,6 +485,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8723ds_free_xmit_priv(PADAPTER padapter); s32 rtl8723ds_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8723ds_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8723ds_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8723ds_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8723ds_xmit_buf_handler(PADAPTER padapter); thread_return rtl8723ds_xmit_thread(thread_context context); @@ -500,6 +501,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8723du_free_xmit_priv(PADAPTER padapter); s32 rtl8723du_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8723du_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8723du_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8723du_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8723du_xmit_tasklet(void *priv); s32 rtl8723du_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); @@ -513,6 +517,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8723de_xmitframe_resume(_adapter *padapter); s32 rtl8723de_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8723de_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8723de_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8723de_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8723de_xmit_tasklet(void *priv); #endif diff --git a/include/rtl8723f_hal.h b/include/rtl8723f_hal.h new file mode 100644 index 0000000..3918b4c --- /dev/null +++ b/include/rtl8723f_hal.h @@ -0,0 +1,245 @@ +/****************************************************************************** + * + * Copyright(c) 2019 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#ifndef _RTL8723F_HAL_H_ +#define _RTL8723F_HAL_H_ + +#include /* BIT(x) */ +#include /* PADAPTER */ +#include "../hal/halmac/halmac_api.h" /* MAC REG definition */ + +#define MAX_RECVBUF_SZ 16384 /* 16KB (RX_FIFO_SIZE_8723F), TX: 32KB */ + +/* + * MAC Register definition + */ +#define REG_LEDCFG0 REG_LED_CFG_8723F /* rtw_mp.c */ +#define MSR (REG_CR_8723F + 2) /* rtw_mp.c & hal_com.c */ +#define MSR1 REG_CR_EXT_8723F /* rtw_mp.c & hal_com.c */ +#define REG_C2HEVT_MSG_NORMAL 0x1A0 /* hal_com.c */ +#define REG_C2HEVT_CLEAR 0x1AF /* hal_com.c */ +#define REG_BCN_CTRL_1 REG_BCN_CTRL_CLINT0_8723F /* hal_com.c */ + +#define REG_WOWLAN_WAKE_REASON 0x01C7 /* hal_com.c */ +#define REG_GPIO_PIN_CTRL_2 REG_GPIO_EXT_CTRL_8723F /* hal_com.c */ +#define REG_FIFOPAGE REG_FIFOPAGE_INFO_8723F /* hal_com.c */ +#define REG_RXPKTBUF_CTRL REG_PKTBUF_DBG_CTRL_8723F /* hal_com.c */ +#define REG_WKFMCAM_NUM REG_WKFMCAM_CMD_8723F /* hal_com.c */ +#define REG_RSV_CTRL REG_REG_ACCESS_CTRL_8723F /* hal_com.c */ +#define REG_CAMCMD REG_KEYCAMCMD_8723F /* hal_com.c */ +#define REG_CAMWRITE REG_KEYCAM_WD_8723F /* hal_com.c */ + +#define BIT_AUTO_SYNC_BY_TBTT BIT_EN_TSFAUTO_SYNC_8723F /* hal_com.c */ +#define BIT_DIS_ATIM_ROOT_8723F 23 /* REG_HIQ_NO_LMT_EN_V2[23], disable ATIM ROOT */ +#define BIT_SECCAM_POLLING_8723F BIT_KEYCAM_POLLING_8723F /* rtl8723f_ops.c */ +#define BIT_GET_NETYPE2 BIT_GET_P2_NETSTATE_8723F /* hal_halmac.c */ +#define BIT_GET_NETYPE3 BIT_GET_P3_NETSTATE_8723F /* hal_halmac.c */ +#define BIT_GET_NETYPE4 BIT_GET_P4_NETSTATE_8723F /* hal_halmac.c */ + +#ifdef CONFIG_WOW_PATTERN_IN_TXFIFO +#define WKCAM_OFFSET_BIT_MASK 0xFFF +#define WKCAM_OFFSET_BIT_MASK_OFFSET 12 +#define REG_TXBUF_WKCAM_OFFSET 0x1B4 //BIT_TXBUF_WKCAM_OFFSET [24:12] +#define REG_PKT_BUFF_ACCESS_CTRL 0x106 /* hal_com.c */ +#endif + +/* RXERR_RPT, for rtw_mp.c */ +#define RXERR_TYPE_OFDM_PPDU 0 +#define RXERR_TYPE_OFDM_FALSE_ALARM 2 +#define RXERR_TYPE_OFDM_MPDU_OK 0 +#define RXERR_TYPE_OFDM_MPDU_FAIL 1 +#define RXERR_TYPE_CCK_PPDU 3 +#define RXERR_TYPE_CCK_FALSE_ALARM 5 +#define RXERR_TYPE_CCK_MPDU_OK 3 +#define RXERR_TYPE_CCK_MPDU_FAIL 4 +#define RXERR_TYPE_HT_PPDU 8 +#define RXERR_TYPE_HT_FALSE_ALARM 9 +#define RXERR_TYPE_HT_MPDU_TOTAL 6 +#define RXERR_TYPE_HT_MPDU_OK 6 +#define RXERR_TYPE_HT_MPDU_FAIL 7 +#define RXERR_TYPE_RX_FULL_DROP 10 + +#define RXERR_COUNTER_MASK BIT_MASK_RPT_COUNTER_8723F +#define RXERR_RPT_RST BIT_RXERR_RPT_RST_8723F +#define _RXERR_RPT_SEL(type) (BIT_RXERR_RPT_SEL_V1_3_0_8723F(type) \ + | ((type & 0x10) ? BIT_RXERR_RPT_SEL_V1_4_8723F : 0)) + +/* + * BB Register definition + */ +#define rPMAC_Reset 0x100 /* hal_mp.c */ + +#define rFPGA0_RFMOD 0x800 +#define rFPGA0_TxInfo 0x804 +#define rOFDMCCKEN_Jaguar 0x808 /* hal_mp.c */ +#define rFPGA0_TxGainStage 0x80C /* phydm only */ +#define rFPGA0_XA_HSSIParameter1 0x820 /* hal_mp.c */ +#define rFPGA0_XA_HSSIParameter2 0x824 /* hal_mp.c */ +#define rFPGA0_XB_HSSIParameter1 0x828 /* hal_mp.c */ +#define rFPGA0_XB_HSSIParameter2 0x82C /* hal_mp.c */ +#define rTxAGC_B_Rate18_06 0x830 +#define rTxAGC_B_Rate54_24 0x834 +#define rTxAGC_B_CCK1_55_Mcs32 0x838 +#define rCCAonSec_Jaguar 0x838 /* hal_mp.c */ +#define rTxAGC_B_Mcs03_Mcs00 0x83C +#define rTxAGC_B_Mcs07_Mcs04 0x848 +#define rTxAGC_B_Mcs11_Mcs08 0x84C +#define rFPGA0_XA_RFInterfaceOE 0x860 +#define rFPGA0_XB_RFInterfaceOE 0x864 +#define rTxAGC_B_Mcs15_Mcs12 0x868 +#define rTxAGC_B_CCK11_A_CCK2_11 0x86C +#define rFPGA0_XAB_RFInterfaceSW 0x870 +#define rFPGA0_XAB_RFParameter 0x878 +#define rFPGA0_AnalogParameter4 0x88C /* hal_mp.c & phydm */ +#define rFPGA0_XB_LSSIReadBack 0x8A4 /* phydm */ +#define rHSSIRead_Jaguar 0x8B0 /* RF read addr (rtl8723f_phy.c) */ + +#define rC_TxScale_Jaguar2 0x181C /* Pah_C TX scaling factor (hal_mp.c) */ +#define rC_IGI_Jaguar2 0x1850 /* Initial Gain for path-C (hal_mp.c) */ + +#define rFPGA1_TxInfo 0x90C /* hal_mp.c */ +#define rSingleTone_ContTx_Jaguar 0x914 /* hal_mp.c */ +/* TX BeamForming */ +#define REG_BB_TX_PATH_SEL_1_8723F 0x93C /* rtl8723f_phy.c */ +#define REG_BB_TX_PATH_SEL_2_8723F 0x940 /* rtl8723f_phy.c */ + +/* TX BeamForming */ +#define REG_BB_TXBF_ANT_SET_BF1_8723F 0x19AC /* rtl8723f_phy.c */ +#define REG_BB_TXBF_ANT_SET_BF0_8723F 0x19B4 /* rtl8723f_phy.c */ + +#define rCCK0_System 0xA00 +#define rCCK0_AFESetting 0xA04 + +#define rCCK0_DSPParameter2 0xA1C +#define rCCK0_TxFilter1 0xA20 +#define rCCK0_TxFilter2 0xA24 +#define rCCK0_DebugPort 0xA28 +#define rCCK0_FalseAlarmReport 0xA2C + +#define rD_TxScale_Jaguar2 0x1A1C /* Path_D TX scaling factor (hal_mp.c) */ +#define rD_IGI_Jaguar2 0x1A50 /* Initial Gain for path-D (hal_mp.c) */ + +#define rOFDM0_TRxPathEnable 0xC04 +#define rOFDM0_TRMuxPar 0xC08 +#define rA_TxScale_Jaguar 0xC1C /* Pah_A TX scaling factor (hal_mp.c) */ +#define rOFDM0_RxDetector1 0xC30 /* rtw_mp.c */ +#define rOFDM0_ECCAThreshold 0xC4C /* phydm only */ +#define rOFDM0_XAAGCCore1 0xC50 /* phydm only */ +#define rA_IGI_Jaguar 0xC50 /* Initial Gain for path-A (hal_mp.c) */ +#define rOFDM0_XBAGCCore1 0xC58 /* phydm only */ +#define rOFDM0_XATxIQImbalance 0xC80 /* phydm only */ +#define rA_LSSIWrite_Jaguar 0xC90 /* RF write addr, LSSI Parameter (rtl8822b_phy.c) */ + +#define rOFDM1_LSTF 0xD00 +#define rOFDM1_TRxPathEnable 0xD04 /* hal_mp.c */ +#define rA_PIRead_Jaguar 0xD04 /* RF readback with PI (rtl8723f_phy.c) */ +#define rA_SIRead_Jaguar 0xD08 /* RF readback with SI (rtl8723f_phy.c) */ +#define rB_PIRead_Jaguar 0xD44 /* RF readback with PI (rtl8723f_phy.c) */ +#define rB_SIRead_Jaguar 0xD48 /* RF readback with SI (rtl8723f_phy.c) */ + +#define rTxAGC_A_Rate18_06 0xE00 +#define rTxAGC_A_Rate54_24 0xE04 +#define rTxAGC_A_CCK1_Mcs32 0xE08 +#define rTxAGC_A_Mcs03_Mcs00 0xE10 +#define rTxAGC_A_Mcs07_Mcs04 0xE14 +#define rTxAGC_A_Mcs11_Mcs08 0xE18 +#define rTxAGC_A_Mcs15_Mcs12 0xE1C +#define rB_TxScale_Jaguar 0xE1C /* Path_B TX scaling factor (hal_mp.c) */ +#define rB_IGI_Jaguar 0xE50 /* Initial Gain for path-B (hal_mp.c) */ +#define rB_LSSIWrite_Jaguar 0xE90 /* RF write addr, LSSI Parameter (rtl8822b_phy.c) */ +/* RFE */ +#define rA_RFE_Pinmux_Jaguar 0xCB0 /* hal_mp.c */ +#define rB_RFE_Pinmux_Jaguar 0xEB0 /* Path_B RFE control pinmux */ +#define rA_RFE_Inv_Jaguar 0xCB4 /* Path_A RFE cotrol */ +#define rB_RFE_Inv_Jaguar 0xEB4 /* Path_B RFE control */ +#define rA_RFE_Jaguar 0xCB8 /* Path_A RFE cotrol */ +#define rB_RFE_Jaguar 0xEB8 /* Path_B RFE control */ +#define rA_RFE_Inverse_Jaguar 0xCBC /* Path_A RFE control inverse */ +#define rB_RFE_Inverse_Jaguar 0xEBC /* Path_B RFE control inverse */ +#define r_ANTSEL_SW_Jaguar 0x900 /* ANTSEL SW Control */ +#define bMask_RFEInv_Jaguar 0x3FF00000 +#define bMask_AntselPathFollow_Jaguar 0x00030000 + +#define rC_RFE_Pinmux_Jaguar 0x18B4 /* Path_C RFE cotrol pinmux*/ +#define rD_RFE_Pinmux_Jaguar 0x1AB4 /* Path_D RFE cotrol pinmux*/ +#define rA_RFE_Sel_Jaguar2 0x1990 + +/* Page1(0x100) */ +#define bBBResetB 0x100 + +/* Page8(0x800) */ +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 +/* Reg 0x80C rFPGA0_TxGainStage */ +#define bXBTxAGC 0xF00 +#define bXCTxAGC 0xF000 +#define bXDTxAGC 0xF0000 + +/* PageA(0xA00) */ +#define bCCKBBMode 0x3 + +#define bCCKScramble 0x8 +#define bCCKTxRate 0x3000 + +/* General */ +#define bMaskByte0 0xFF /* mp, rtw_odm.c & phydm */ +#define bMaskByte1 0xFF00 /* hal_mp.c & phydm */ +#define bMaskByte2 0xFF0000 /* hal_mp.c & phydm */ +#define bMaskByte3 0xFF000000 /* hal_mp.c & phydm */ +#define bMaskHWord 0xFFFF0000 /* hal_com.c, rtw_mp.c */ +#define bMaskLWord 0x0000FFFF /* mp, hal_com.c & phydm */ +#define bMaskDWord 0xFFFFFFFF /* mp, hal, rtw_odm.c & phydm */ + +#define bEnable 0x1 /* hal_mp.c, rtw_mp.c */ +#define bDisable 0x0 /* rtw_mp.c */ + +#define MAX_STALL_TIME 50 /* unit: us, hal_com_phycfg.c */ + +#define Rx_Smooth_Factor 20 /* phydm only */ + +/* + * RF Register definition + */ +#define RF_AC 0x00 +#define RF_AC_Jaguar 0x00 /* hal_mp.c */ +#define RF_CHNLBW 0x18 /* rtl8723f_phy.c */ +#define RF_ModeTableAddr 0x30 /* rtl8723f_phy.c */ +#define RF_ModeTableData0 0x31 /* rtl8723f_phy.c */ +#define RF_ModeTableData1 0x32 /* rtl8723f_phy.c */ +#define RF_0x52 0x52 +#define RF_WeLut_Jaguar 0xEF /* rtl8723f_phy.c */ + +/* rtw_lps_state_chk() @hal_com.c */ +#define BIT_PWRBIT_OW_EN BIT_WMAC_TCR_PWRMGT_CTL_8723F + +/* +* General Functions +*/ +void rtl8723f_init_hal_spec(PADAPTER); /* hal/hal_com.c */ + +#ifdef CONFIG_MP_INCLUDED +/* MP Functions */ +#include /* struct mp_priv */ +void rtl8723f_prepare_mp_txdesc(PADAPTER, struct mp_priv *); /* rtw_mp.c */ +void rtl8723f_mp_config_rfpath(PADAPTER); /* hal_mp.c */ +#endif +void hw_var_set_dl_rsvd_page(PADAPTER adapter, u8 mstatus); + +#ifdef CONFIG_USB_HCI +#include +#elif defined(CONFIG_SDIO_HCI) +#include +#endif + +#endif /* _RTL8723F_HAL_H_ */ diff --git a/include/rtl8723fs_hal.h b/include/rtl8723fs_hal.h new file mode 100644 index 0000000..f1b938a --- /dev/null +++ b/include/rtl8723fs_hal.h @@ -0,0 +1,31 @@ +/****************************************************************************** + * + * Copyright(c) 2019 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#ifndef _RTL8723FS_HAL_H_ +#define _RTL8723FS_HAL_H_ + +#include /* PADAPTER */ + +/* rtl8723fs_ops.c */ +void rtl8723fs_set_hal_ops(PADAPTER); + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +void rtl8723fs_disable_interrupt_but_cpwm2(PADAPTER adapter); +#endif + +/* rtl8723fs_xmit.c */ +s32 rtl8723fs_dequeue_writeport(PADAPTER); +#define _dequeue_writeport(a) rtl8723fs_dequeue_writeport(a) + +#endif /* _RTL8723FS_HAL_H_ */ diff --git a/include/rtl8723fu_hal.h b/include/rtl8723fu_hal.h new file mode 100644 index 0000000..69de776 --- /dev/null +++ b/include/rtl8723fu_hal.h @@ -0,0 +1,61 @@ +/****************************************************************************** + * + * Copyright(c) 2019 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#ifndef _RTL8723FU_HAL_H_ +#define _RTL8723FU_HAL_H_ + +#ifdef CONFIG_USB_HCI + #include /* PADAPTER */ + + #ifdef CONFIG_USB_HCI + #ifdef USB_PACKET_OFFSET_SZ + #define PACKET_OFFSET_SZ (USB_PACKET_OFFSET_SZ) + #else + #define PACKET_OFFSET_SZ (8) + #endif + #define TXDESC_OFFSET (TXDESC_SIZE + PACKET_OFFSET_SZ) + #endif + + /* undefine MAX_RECVBUF_SZ from rtl8723f_hal.h */ + #ifdef MAX_RECVBUF_SZ + #undef MAX_RECVBUF_SZ + #endif + + /* recv_buffer must be large than usb agg size */ + #ifndef MAX_RECVBUF_SZ + #ifndef CONFIG_MINIMAL_MEMORY_USAGE + #ifdef CONFIG_PLATFORM_NOVATEK_NT72668 + #define MAX_RECVBUF_SZ (15360) /* 15k */ + #elif defined(CONFIG_PLATFORM_HISILICON) + /* use 16k to workaround for HISILICON platform */ + #define MAX_RECVBUF_SZ (16384) + #else + #define MAX_RECVBUF_SZ (32768) + #endif + #else + #define MAX_RECVBUF_SZ (4000) + #endif + #endif /* !MAX_RECVBUF_SZ */ + + /* rtl8723fu_ops.c */ + void rtl8723fu_set_hal_ops(PADAPTER padapter); + void rtl8723fu_set_hw_type(struct dvobj_priv *pdvobj); + + /* rtl8723fu_io.c */ + void rtl8723fu_set_intf_ops(struct _io_ops *pops); + +#endif /* CONFIG_USB_HCI */ + + +#endif /* _RTL8723FU_HAL_H_ */ diff --git a/include/rtl8812a_cmd.h b/include/rtl8812a_cmd.h index a89a628..4a34736 100644 --- a/include/rtl8812a_cmd.h +++ b/include/rtl8812a_cmd.h @@ -118,12 +118,6 @@ void rtl8812_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); void rtl8812_set_FwPwrModeInIPS_cmd(PADAPTER padapter, u8 cmd_param); #endif -#ifdef CONFIG_TDLS -#ifdef CONFIG_TDLS_CH_SW -void rtl8812_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); -#endif -#endif - /* ------------------------------------ * C2H format * ------------------------------------ */ diff --git a/include/rtl8812a_xmit.h b/include/rtl8812a_xmit.h index 6105a8e..32bf20f 100644 --- a/include/rtl8812a_xmit.h +++ b/include/rtl8812a_xmit.h @@ -318,9 +318,7 @@ void rtl8812a_fill_fake_txdesc(PADAPTER padapter, u8 *pDesc, u32 BufferLen, u8 I void rtl8812a_fill_txdesc_sectype(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8812a_fill_txdesc_vcs(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8812a_fill_txdesc_phy(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc); -#if defined(CONFIG_CONCURRENT_MODE) void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc); -#endif void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); #ifdef CONFIG_USB_HCI @@ -328,6 +326,9 @@ s32 rtl8812au_init_xmit_priv(PADAPTER padapter); void rtl8812au_free_xmit_priv(PADAPTER padapter); s32 rtl8812au_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8812au_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtl8812au_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8812au_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8812au_xmit_buf_handler(PADAPTER padapter); void rtl8812au_xmit_tasklet(void *priv); @@ -341,6 +342,9 @@ struct xmit_buf *rtl8812ae_dequeue_xmitbuf(struct rtw_tx_ring *ring); void rtl8812ae_xmitframe_resume(_adapter *padapter); s32 rtl8812ae_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8812ae_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtl8812ae_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8812ae_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8812ae_xmit_tasklet(void *priv); diff --git a/include/rtl8814a_cmd.h b/include/rtl8814a_cmd.h old mode 100755 new mode 100644 index 67813fb..02ed211 --- a/include/rtl8814a_cmd.h +++ b/include/rtl8814a_cmd.h @@ -141,11 +141,7 @@ void rtl8814_set_FwPwrMode_cmd(PADAPTER padapter, u8 PSMode); u8 GetTxBufferRsvdPageNum8814(_adapter *padapter, bool wowlan); void rtl8814_req_txrpt_cmd(PADAPTER padapter, u8 macid); -#ifdef CONFIG_TDLS - #ifdef CONFIG_TDLS_CH_SW - void rtl8814_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); - #endif -#endif +void rtl8814a_set_FwPwrModeInIPS_cmd(PADAPTER padapter, u8 cmd_param); void Set_RA_LDPC_8814( diff --git a/include/rtl8814a_hal.h b/include/rtl8814a_hal.h old mode 100755 new mode 100644 index 3643d11..fb11eb7 --- a/include/rtl8814a_hal.h +++ b/include/rtl8814a_hal.h @@ -318,6 +318,7 @@ void rtl8814_stop_thread(PADAPTER padapter); BOOLEAN InterruptRecognized8814AE(PADAPTER Adapter); void UpdateInterruptMask8814AE(PADAPTER Adapter, u32 AddMSR, u32 AddMSR1, u32 RemoveMSR, u32 RemoveMSR1); void InitMAC_TRXBD_8814AE(PADAPTER Adapter); + void rtl8814ae_reset_desc_ring(_adapter *padapter); u16 get_txbd_rw_reg(u16 ff_hwaddr); #endif diff --git a/include/rtl8814a_recv.h b/include/rtl8814a_recv.h old mode 100755 new mode 100644 diff --git a/include/rtl8814a_spec.h b/include/rtl8814a_spec.h old mode 100755 new mode 100644 index 616f5fd..a27ab88 --- a/include/rtl8814a_spec.h +++ b/include/rtl8814a_spec.h @@ -486,6 +486,11 @@ #define REG_MGQ_HIQ_INFO_8814A 0x1410 #define REG_CMDQ_BCNQ_INFO_8814A 0x1414 +#define REG_MACID_DROP0_8814A 0x1450 +#define REG_MACID_DROP1_8814A 0x1454 +#define REG_MACID_DROP2_8814A 0x1458 +#define REG_MACID_DROP3_8814A 0x145C + #define DDMA_LEN_MASK 0x0001FFFF #define FW_CHKSUM_DUMMY_SZ 8 #define DDMA_CH_CHKSUM_CNT BIT(24) diff --git a/include/rtl8814a_xmit.h b/include/rtl8814a_xmit.h old mode 100755 new mode 100644 index f1fcc65..8901fde --- a/include/rtl8814a_xmit.h +++ b/include/rtl8814a_xmit.h @@ -264,9 +264,7 @@ void rtl8814a_fill_fake_txdesc(PADAPTER padapter, u8 *pDesc, u32 BufferLen, u8 I void rtl8814a_fill_txdesc_sectype(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8814a_fill_txdesc_vcs(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8814a_fill_txdesc_phy(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc); -#if defined(CONFIG_CONCURRENT_MODE) - void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc); -#endif +void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc); void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); #ifdef CONFIG_USB_HCI @@ -274,6 +272,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8814au_free_xmit_priv(PADAPTER padapter); s32 rtl8814au_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8814au_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8814au_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8814au_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8814au_xmit_buf_handler(PADAPTER padapter); void rtl8814au_xmit_tasklet(void *priv); @@ -287,6 +288,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8814ae_xmitframe_resume(_adapter *padapter); s32 rtl8814ae_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8814ae_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8814ae_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8814ae_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8814ae_xmit_tasklet(void *priv); #ifdef CONFIG_XMIT_THREAD_MODE diff --git a/include/rtl8814b_hal.h b/include/rtl8814b_hal.h old mode 100755 new mode 100644 diff --git a/include/rtl8814bu_hal.h b/include/rtl8814bu_hal.h old mode 100755 new mode 100644 diff --git a/include/rtl8821a_xmit.h b/include/rtl8821a_xmit.h index 5d973cd..28323b7 100644 --- a/include/rtl8821a_xmit.h +++ b/include/rtl8821a_xmit.h @@ -140,6 +140,9 @@ s32 InitXmitPriv8821AS(PADAPTER padapter); void FreeXmitPriv8821AS(PADAPTER padapter); s32 XmitBufHandler8821AS(PADAPTER padapter); s32 MgntXmit8821AS(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtl8821as_hal_mgmt_xmit_enqueue(PADAPTER adapter, struct xmit_frame *pxmitframe); +#endif s32 HalXmitNoLock8821AS(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 HalXmit8821AS(PADAPTER padapter, struct xmit_frame *pxmitframe); #ifndef CONFIG_SDIO_TX_TASKLET diff --git a/include/rtl8821ce_hal.h b/include/rtl8821ce_hal.h old mode 100755 new mode 100644 diff --git a/include/rtl8822be_hal.h b/include/rtl8822be_hal.h old mode 100755 new mode 100644 diff --git a/include/rtl8822c_hal.h b/include/rtl8822c_hal.h old mode 100755 new mode 100644 index 2231b21..0230d93 --- a/include/rtl8822c_hal.h +++ b/include/rtl8822c_hal.h @@ -34,7 +34,11 @@ #endif #define MAX_RECVBUF_SZ (DEF_RECVBUF_SZ + RX_FIFO_EXPANDING) #else /* !CONFIG_SUPPORT_TRX_SHARED */ +#ifdef CONFIG_PCI_HCI +#define MAX_RECVBUF_SZ 12288 /* 12KB */ +#else #define MAX_RECVBUF_SZ 24576 /* 24KB, TX: 256KB */ +#endif /* !CONFIG_PCI_HCI */ #endif /* !CONFIG_SUPPORT_TRX_SHARED */ /* diff --git a/include/rtl8822ce_hal.h b/include/rtl8822ce_hal.h old mode 100755 new mode 100644 diff --git a/include/rtl8822cs_hal.h b/include/rtl8822cs_hal.h old mode 100755 new mode 100644 diff --git a/include/rtl8822cu_hal.h b/include/rtl8822cu_hal.h old mode 100755 new mode 100644 diff --git a/include/rtw_ap.h b/include/rtw_ap.h index 38cfca0..64cb1a8 100644 --- a/include/rtw_ap.h +++ b/include/rtw_ap.h @@ -1,114 +1,143 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2017 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - *****************************************************************************/ -#ifndef __RTW_AP_H_ -#define __RTW_AP_H_ - - -#ifdef CONFIG_AP_MODE - -/* external function */ -extern void rtw_indicate_sta_assoc_event(_adapter *padapter, struct sta_info *psta); -extern void rtw_indicate_sta_disassoc_event(_adapter *padapter, struct sta_info *psta); - - -void init_mlme_ap_info(_adapter *padapter); -void free_mlme_ap_info(_adapter *padapter); -u8 rtw_set_tim_ie(u8 dtim_cnt, u8 dtim_period - , const u8 *tim_bmp, u8 tim_bmp_len, u8 *tim_ie); -/* void update_BCNTIM(_adapter *padapter); */ -void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *data, u8 len); -void rtw_remove_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index); -void _update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx, u8 flags, const char *tag); -#define update_beacon(adapter, ie_id, oui, tx, flags) _update_beacon((adapter), (ie_id), (oui), (tx), (flags), __func__) -/*update_beacon - (flags) can set to normal enqueue (0) and RTW_CMDF_WAIT_ACK enqueue. - (flags) = RTW_CMDF_DIRECTLY is not currently implemented, it will do normal enqueue.*/ - -void rtw_ap_update_sta_ra_info(_adapter *padapter, struct sta_info *psta); - -void expire_timeout_chk(_adapter *padapter); -void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta); -void rtw_start_bss_hdl_after_chbw_decided(_adapter *adapter); -void start_bss_network(_adapter *padapter, struct createbss_parm *parm); -int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len); -void rtw_ap_restore_network(_adapter *padapter); - -#if CONFIG_RTW_MACADDR_ACL -void rtw_macaddr_acl_init(_adapter *adapter, u8 period); -void rtw_macaddr_acl_deinit(_adapter *adapter, u8 period); -void rtw_macaddr_acl_clear(_adapter *adapter, u8 period); -void rtw_set_macaddr_acl(_adapter *adapter, u8 period, int mode); -int rtw_acl_add_sta(_adapter *adapter, u8 period, const u8 *addr); -int rtw_acl_remove_sta(_adapter *adapter, u8 period, const u8 *addr); -#endif /* CONFIG_RTW_MACADDR_ACL */ - -u8 rtw_ap_set_sta_key(_adapter *adapter, const u8 *addr, u8 alg, const u8 *key, u8 keyid, u8 gk); -u8 rtw_ap_set_pairwise_key(_adapter *padapter, struct sta_info *psta); -int rtw_ap_set_group_key(_adapter *padapter, u8 *key, u8 alg, int keyid); -int rtw_ap_set_wep_key(_adapter *padapter, u8 *key, u8 keylen, int keyid, u8 set_tx); - -#ifdef CONFIG_NATIVEAP_MLME -void associated_clients_update(_adapter *padapter, u8 updated, u32 sta_info_type); -void bss_cap_update_on_sta_join(_adapter *padapter, struct sta_info *psta); -u8 bss_cap_update_on_sta_leave(_adapter *padapter, struct sta_info *psta); -void sta_info_update(_adapter *padapter, struct sta_info *psta); -void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta); -u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reason, bool enqueue); -int rtw_sta_flush(_adapter *padapter, bool enqueue); -int rtw_ap_inform_ch_switch(_adapter *padapter, u8 new_ch, u8 ch_offset); -void start_ap_mode(_adapter *padapter); -void stop_ap_mode(_adapter *padapter); -#endif - -void rtw_ap_update_bss_chbw(_adapter *adapter, WLAN_BSSID_EX *bss, u8 ch, u8 bw, u8 offset); -u8 rtw_ap_chbw_decision(_adapter *adapter, u8 ifbmp, u8 excl_ifbmp - , s16 req_ch, s8 req_bw, s8 req_offset, u8 *ch, u8 *bw, u8 *offset, u8 *chbw_allow); - -#ifdef CONFIG_AUTO_AP_MODE -void rtw_auto_ap_rx_msg_dump(_adapter *padapter, union recv_frame *precv_frame, u8 *ehdr_pos); -extern void rtw_start_auto_ap(_adapter *adapter); -#endif /* CONFIG_AUTO_AP_MODE */ - -void rtw_ap_parse_sta_capability(_adapter *adapter, struct sta_info *sta, u8 *cap); -u16 rtw_ap_parse_sta_supported_rates(_adapter *adapter, struct sta_info *sta, u8 *tlv_ies, u16 tlv_ies_len); -u16 rtw_ap_parse_sta_security_ie(_adapter *adapter, struct sta_info *sta, struct rtw_ieee802_11_elems *elems); -void rtw_ap_parse_sta_wmm_ie(_adapter *adapter, struct sta_info *sta, u8 *tlv_ies, u16 tlv_ies_len); -void rtw_ap_parse_sta_ht_ie(_adapter *adapter, struct sta_info *sta, struct rtw_ieee802_11_elems *elems); -void rtw_ap_parse_sta_vht_ie(_adapter *adapter, struct sta_info *sta, struct rtw_ieee802_11_elems *elems); - -void update_bmc_sta(_adapter *padapter); - -#ifdef CONFIG_BMC_TX_RATE_SELECT -void rtw_update_bmc_sta_tx_rate(_adapter *adapter); -#endif - -void rtw_process_ht_action_smps(_adapter *padapter, u8 *ta, u8 ctrl_field); -void rtw_process_public_act_bsscoex(_adapter *padapter, u8 *pframe, uint frame_len); -#ifdef CONFIG_80211N_HT -int rtw_ht_operation_update(_adapter *padapter); -#endif /* CONFIG_80211N_HT */ -u8 rtw_ap_sta_states_check(_adapter *adapter); - -#ifdef CONFIG_FW_HANDLE_TXBCN -#define rtw_ap_get_nums(adapter) (adapter_to_dvobj(adapter)->nr_ap_if) -bool rtw_ap_nums_check(_adapter *adapter); -#endif - -#ifdef CONFIG_SWTIMER_BASED_TXBCN -void tx_beacon_handlder(struct dvobj_priv *pdvobj); -void tx_beacon_timer_handlder(void *ctx); -#endif /*CONFIG_SWTIMER_BASED_TXBCN*/ - -#endif /* end of CONFIG_AP_MODE */ -#endif /*__RTW_AP_H_*/ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#ifndef __RTW_AP_H_ +#define __RTW_AP_H_ + + +#ifdef CONFIG_AP_MODE + +/* external function */ +extern void rtw_indicate_sta_assoc_event(_adapter *padapter, struct sta_info *psta); +extern void rtw_indicate_sta_disassoc_event(_adapter *padapter, struct sta_info *psta); + + +void init_mlme_ap_info(_adapter *padapter); +void free_mlme_ap_info(_adapter *padapter); +u8 rtw_set_tim_ie(u8 dtim_cnt, u8 dtim_period + , const u8 *tim_bmp, u8 tim_bmp_len, u8 *tim_ie); +/* void update_BCNTIM(_adapter *padapter); */ +void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *data, u8 len); +void rtw_remove_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index); +void _update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx, u8 flags, const char *tag); +#define update_beacon(adapter, ie_id, oui, tx, flags) _update_beacon((adapter), (ie_id), (oui), (tx), (flags), __func__) +/*update_beacon - (flags) can set to normal enqueue (0) and RTW_CMDF_WAIT_ACK enqueue. + (flags) = RTW_CMDF_DIRECTLY is not currently implemented, it will do normal enqueue.*/ + +void rtw_ap_update_sta_ra_info(_adapter *padapter, struct sta_info *psta); + +void expire_timeout_chk(_adapter *padapter); +void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta); +void rtw_start_bss_hdl_after_chbw_decided(_adapter *adapter); +void start_bss_network(_adapter *padapter, struct createbss_parm *parm); +int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len); +void rtw_ap_restore_network(_adapter *padapter); + +#if CONFIG_RTW_MACADDR_ACL +void rtw_macaddr_acl_init(_adapter *adapter, u8 period); +void rtw_macaddr_acl_deinit(_adapter *adapter, u8 period); +void rtw_macaddr_acl_clear(_adapter *adapter, u8 period); +void rtw_set_macaddr_acl(_adapter *adapter, u8 period, int mode); +int rtw_acl_add_sta(_adapter *adapter, u8 period, const u8 *addr); +int rtw_acl_remove_sta(_adapter *adapter, u8 period, const u8 *addr); +#endif /* CONFIG_RTW_MACADDR_ACL */ + +u8 rtw_ap_set_sta_key(_adapter *adapter, const u8 *addr, u8 alg, const u8 *key, u8 keyid, u8 gk); +u8 rtw_ap_set_pairwise_key(_adapter *padapter, struct sta_info *psta); +int rtw_ap_set_group_key(_adapter *padapter, u8 *key, u8 alg, int keyid); +int rtw_ap_set_wep_key(_adapter *padapter, u8 *key, u8 keylen, int keyid, u8 set_tx); + +#ifdef CONFIG_NATIVEAP_MLME +void associated_clients_update(_adapter *padapter, u8 updated, u32 sta_info_type); +void bss_cap_update_on_sta_join(_adapter *padapter, struct sta_info *psta); +u8 bss_cap_update_on_sta_leave(_adapter *padapter, struct sta_info *psta); +void sta_info_update(_adapter *padapter, struct sta_info *psta); +void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta); +u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reason, bool enqueue); +int rtw_sta_flush(_adapter *padapter, bool enqueue); +int rtw_ap_inform_ch_switch(_adapter *padapter, u8 new_ch, u8 ch_offset); +void start_ap_mode(_adapter *padapter); +void stop_ap_mode(_adapter *padapter); +#endif + +void rtw_ap_update_bss_chbw(_adapter *adapter, WLAN_BSSID_EX *bss, u8 ch, u8 bw, u8 offset); +u8 rtw_ap_chbw_decision(_adapter *adapter, u8 ifbmp, u8 excl_ifbmp + , s16 req_ch, s8 req_bw, s8 req_offset, u8 *ch, u8 *bw, u8 *offset, u8 *chbw_allow, bool *set_u_ch); + +#ifdef CONFIG_AUTO_AP_MODE +void rtw_auto_ap_rx_msg_dump(_adapter *padapter, union recv_frame *precv_frame, u8 *ehdr_pos); +extern void rtw_start_auto_ap(_adapter *adapter); +#endif /* CONFIG_AUTO_AP_MODE */ + +void rtw_ap_parse_sta_capability(_adapter *adapter, struct sta_info *sta, u8 *cap); +u16 rtw_ap_parse_sta_supported_rates(_adapter *adapter, struct sta_info *sta, u8 *tlv_ies, u16 tlv_ies_len); +u16 rtw_ap_parse_sta_security_ie(_adapter *adapter, struct sta_info *sta, struct rtw_ieee802_11_elems *elems); +void rtw_ap_parse_sta_wmm_ie(_adapter *adapter, struct sta_info *sta, u8 *tlv_ies, u16 tlv_ies_len); +void rtw_ap_parse_sta_ht_ie(_adapter *adapter, struct sta_info *sta, struct rtw_ieee802_11_elems *elems); +void rtw_ap_parse_sta_vht_ie(_adapter *adapter, struct sta_info *sta, struct rtw_ieee802_11_elems *elems); +void rtw_ap_parse_sta_multi_ap_ie(_adapter *adapter, struct sta_info *sta, u8 *ies, int ies_len); + +/* b2u flags */ +#define RTW_AP_B2U_ALL BIT0 +#define RTW_AP_B2U_GA_UCAST BIT1 /* WDS group addressed unicast frame, forward only */ +#define RTW_AP_B2U_BCAST BIT2 +#define RTW_AP_B2U_IP_MCAST BIT3 + +#define rtw_ap_src_b2u_policy_chk(flags, da) ( \ + (flags & RTW_AP_B2U_ALL) \ + || ((flags & RTW_AP_B2U_BCAST) && is_broadcast_mac_addr(da)) \ + || ((flags & RTW_AP_B2U_IP_MCAST) && (IP_MCAST_MAC(da) || ICMPV6_MCAST_MAC(da))) \ + ) + +#define rtw_ap_fwd_b2u_policy_chk(flags, da, gaucst) ( \ + (flags & RTW_AP_B2U_ALL) \ + || ((flags & RTW_AP_B2U_GA_UCAST) && gaucst) \ + || ((flags & RTW_AP_B2U_BCAST) && is_broadcast_mac_addr(da)) \ + || ((flags & RTW_AP_B2U_IP_MCAST) && (IP_MCAST_MAC(da) || ICMPV6_MCAST_MAC(da))) \ + ) + +void dump_ap_b2u_flags(void *sel, _adapter *adapter); + +int rtw_ap_addr_resolve(_adapter *adapter, u16 os_qid, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list); +int rtw_ap_rx_data_validate_hdr(_adapter *adapter, union recv_frame *rframe, struct sta_info **sta); +int rtw_ap_rx_msdu_act_check(union recv_frame *rframe + , const u8 *da, const u8 *sa + , u8 *msdu, enum rtw_rx_llc_hdl llc_hdl + , struct xmit_frame **fwd_frame, _list *b2u_list); + +void update_bmc_sta(_adapter *padapter); + +#ifdef CONFIG_BMC_TX_RATE_SELECT +void rtw_update_bmc_sta_tx_rate(_adapter *adapter); +#endif + +void rtw_process_ht_action_smps(_adapter *padapter, u8 *ta, u8 ctrl_field); +void rtw_process_public_act_bsscoex(_adapter *padapter, u8 *pframe, uint frame_len); +#ifdef CONFIG_80211N_HT +int rtw_ht_operation_update(_adapter *padapter); +#endif /* CONFIG_80211N_HT */ +u8 rtw_ap_sta_states_check(_adapter *adapter); + +#ifdef CONFIG_FW_HANDLE_TXBCN +#define rtw_ap_get_nums(adapter) (adapter_to_dvobj(adapter)->nr_ap_if) +bool rtw_ap_nums_check(_adapter *adapter); +#endif + +#ifdef CONFIG_SWTIMER_BASED_TXBCN +void tx_beacon_handlder(struct dvobj_priv *pdvobj); +void tx_beacon_timer_handlder(void *ctx); +#endif /*CONFIG_SWTIMER_BASED_TXBCN*/ + +#endif /* end of CONFIG_AP_MODE */ +#endif /*__RTW_AP_H_*/ diff --git a/include/rtw_btcoex.h b/include/rtw_btcoex.h index cd37ee5..3361dbe 100644 --- a/include/rtw_btcoex.h +++ b/include/rtw_btcoex.h @@ -57,6 +57,12 @@ typedef enum _BTCOEX_SUSPEND_STATE { BTCOEX_SUSPEND_STATE_MAX } BTCOEX_SUSPEND_STATE, *PBTCOEX_SUSPEND_STATE; +typedef enum _BTCOEX_POLICY_CONTROL { + BTCOEX_POLICY_CONTROL_AUTO, + BTCOEX_POLICY_CONTROL_FORCE_FREERUN, + BTCOEX_POLICY_CONTROL_FORCE_TDMA +} BTCOEX_POLICY_CONTROL, *PBTCOEX_POLICY_CONTROL; + #define SET_BT_MP_OPER_RET(OpCode, StatusCode) ((OpCode << 8) | StatusCode) #define GET_OP_CODE_FROM_BT_MP_OPER_RET(RetCode) ((RetCode & 0xF0) >> 8) #define GET_STATUS_CODE_FROM_BT_MP_OPER_RET(RetCode) (RetCode & 0x0F) @@ -376,6 +382,7 @@ void rtw_btcoex_ScanNotify(PADAPTER, u8 type); void rtw_btcoex_MediaStatusNotify(PADAPTER, u8 mediaStatus); void rtw_btcoex_SpecialPacketNotify(PADAPTER, u8 pktType); void rtw_btcoex_IQKNotify(PADAPTER padapter, u8 state); +void rtw_btcoex_WLRFKNotify(PADAPTER padapter, u8 path, u8 type, u8 state); void rtw_btcoex_BtInfoNotify(PADAPTER, u8 length, u8 *tmpBuf); void rtw_btcoex_BtMpRptNotify(PADAPTER, u8 length, u8 *tmpBuf); void rtw_btcoex_SuspendNotify(PADAPTER, u8 state); @@ -391,6 +398,7 @@ s32 rtw_btcoex_IsBTCoexRejectAMPDU(PADAPTER padapter); s32 rtw_btcoex_IsBTCoexCtrlAMPDUSize(PADAPTER); u32 rtw_btcoex_GetAMPDUSize(PADAPTER); void rtw_btcoex_SetManualControl(PADAPTER, u8 bmanual); +void rtw_btcoex_set_policy_control(PADAPTER, u8 btc_policy); u8 rtw_btcoex_1Ant(PADAPTER); u8 rtw_btcoex_IsBtControlLps(PADAPTER); u8 rtw_btcoex_IsLpsOn(PADAPTER); diff --git a/include/rtw_cmd.h b/include/rtw_cmd.h index 397efbe..4f49d92 100644 --- a/include/rtw_cmd.h +++ b/include/rtw_cmd.h @@ -183,9 +183,10 @@ extern void rtw_cmd_clr_isr(struct cmd_priv *pcmdpriv); extern void rtw_evt_notify_isr(struct evt_priv *pevtpriv); #ifdef CONFIG_P2P u8 p2p_protocol_wk_cmd(_adapter *padapter, int intCmdType); +#endif /* CONFIG_P2P */ #ifdef CONFIG_IOCTL_CFG80211 -struct p2p_roch_parm { +struct rtw_roch_parm { u64 cookie; struct wireless_dev *wdev; struct ieee80211_channel ch; @@ -193,18 +194,15 @@ struct p2p_roch_parm { unsigned int duration; }; -u8 p2p_roch_cmd(_adapter *adapter +u8 rtw_roch_cmd(_adapter *adapter , u64 cookie, struct wireless_dev *wdev , struct ieee80211_channel *ch, enum nl80211_channel_type ch_type , unsigned int duration , u8 flags ); -u8 p2p_cancel_roch_cmd(_adapter *adapter, u64 cookie, struct wireless_dev *wdev, u8 flags); -#endif /* CONFIG_IOCTL_CFG80211 */ -#endif /* CONFIG_P2P */ +u8 rtw_cancel_roch_cmd(_adapter *adapter, u64 cookie, struct wireless_dev *wdev, u8 flags); -#ifdef CONFIG_IOCTL_CFG80211 u8 rtw_mgnt_tx_cmd(_adapter *adapter, u8 tx_ch, u8 no_cck, const u8 *buf, size_t len, int wait_ack, u8 flags); struct mgnt_tx_parm { u8 tx_ch; @@ -248,6 +246,7 @@ enum rtw_drvextra_cmd_id { #ifdef CONFIG_RTW_REPEATER_SON RSON_SCAN_WK_CID, #endif + ROCH_WK_CID, MGNT_TX_WK_CID, REQ_PER_CMD_WK_CID, SSMPS_WK_CID, @@ -257,6 +256,9 @@ enum rtw_drvextra_cmd_id { AC_PARM_CMD_WK_CID, #ifdef CONFIG_AP_MODE STOP_AP_WK_CID, +#endif +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + TBTX_CONTROL_TX_WK_CID, #endif MAX_WK_CID }; @@ -288,26 +290,6 @@ enum RFINTFS { HWPI, }; -/* -Caller Mode: Infra, Ad-HoC(C) - -Notes: To enter USB suspend mode - -Command Mode - -*/ -struct usb_suspend_parm { - u32 action;/* 1: sleep, 0:resume */ -}; - -/* -Caller Mode: Infra, Ad-HoC - -Notes: To join a known BSS. - -Command-Event Mode - -*/ /* Caller Mode: Infra, Ad-Hoc @@ -351,20 +333,6 @@ struct createbss_parm { s8 req_offset; }; -#if 0 -/* Caller Mode: AP, Ad-HoC, Infra */ -/* Notes: To set the NIC mode of RTL8711 */ -/* Command Mode */ -/* The definition of mode: */ - -#define IW_MODE_AUTO 0 /* Let the driver decides which AP to join */ -#define IW_MODE_ADHOC 1 /* Single cell network (Ad-Hoc Clients) */ -#define IW_MODE_INFRA 2 /* Multi cell network, roaming, .. */ -#define IW_MODE_MASTER 3 /* Synchronisation master or Access Point */ -#define IW_MODE_REPEAT 4 /* Wireless Repeater (forwarder) */ -#define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */ -#define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */ -#endif struct setopmode_parm { u8 mode; @@ -396,6 +364,7 @@ struct sitesurvey_parm { u8 bw; /* 0: use default */ bool acs; /* aim to trigger channel selection when scan done */ + u8 reason; }; /* @@ -428,7 +397,7 @@ struct setkey_parm { u8 algorithm; /* encryption algorithm, could be none, wep40, TKIP, CCMP, wep104 */ u8 keyid; u8 set_tx; /* 1: main tx key for wep. 0: other key. */ - u8 key[16]; /* this could be 40 or 104 */ + u8 key[32]; /* this could be 40 or 104 */ }; /* @@ -444,7 +413,7 @@ struct set_stakey_parm { u8 addr[ETH_ALEN]; u8 algorithm; u8 keyid; - u8 key[16]; + u8 key[32]; u8 gk; }; @@ -454,182 +423,6 @@ struct set_stakey_rsp { u8 rsvd; }; -/* -Caller Ad-Hoc/AP - -Command -Rsp(AID == CAMID) mode - -This is to force fw to add an sta_data entry per driver's request. - -FW will write an cam entry associated with it. - -*/ -struct set_assocsta_parm { - u8 addr[ETH_ALEN]; -}; - -struct set_assocsta_rsp { - u8 cam_id; - u8 rsvd[3]; -}; - -/* - Caller Ad-Hoc/AP - Command mode - This is to force fw to del an sta_data entry per driver's request - FW will invalidate the cam entry associated with it. -*/ -struct del_assocsta_parm { - u8 addr[ETH_ALEN]; -}; - -/* -Caller Mode: AP/Ad-HoC(M) - -Notes: To notify fw that given staid has changed its power state - -Command Mode - -*/ -struct setstapwrstate_parm { - u8 staid; - u8 status; - u8 hwaddr[6]; -}; - -/* -Caller Mode: Any - -Notes: To setup the basic rate of RTL8711 - -Command Mode - -*/ -struct setbasicrate_parm { - u8 basicrates[NumRates]; -}; - -/* -Caller Mode: Any - -Notes: To read the current basic rate - -Command-Rsp Mode - -*/ -struct getbasicrate_parm { - u32 rsvd; -}; - -struct getbasicrate_rsp { - u8 basicrates[NumRates]; -}; - -/* -Caller Mode: Any - -Notes: To setup the data rate of RTL8711 - -Command Mode - -*/ -struct setdatarate_parm { -#ifdef MP_FIRMWARE_OFFLOAD - u32 curr_rateidx; -#else - u8 mac_id; - u8 datarates[NumRates]; -#endif -}; - -/* -Caller Mode: Any - -Notes: To read the current data rate - -Command-Rsp Mode - -*/ -struct getdatarate_parm { - u32 rsvd; - -}; -struct getdatarate_rsp { - u8 datarates[NumRates]; -}; - -/* -Caller Mode: Any - -Notes: To set the channel/modem/band -This command will be used when channel/modem/band is changed. - -Command Mode - -*/ -struct setphy_parm { - u8 rfchannel; - u8 modem; -}; - -/* -Caller Mode: Any - -Notes: To get the current setting of channel/modem/band - -Command-Rsp Mode - -*/ -struct getphy_parm { - u32 rsvd; - -}; -struct getphy_rsp { - u8 rfchannel; - u8 modem; -}; - -struct readBB_parm { - u8 offset; -}; -struct readBB_rsp { - u8 value; -}; - -struct readTSSI_parm { - u8 offset; -}; -struct readTSSI_rsp { - u8 value; -}; - -struct readMAC_parm { - u8 len; - u32 addr; -}; - -struct writeBB_parm { - u8 offset; - u8 value; -}; - -struct readRF_parm { - u8 offset; -}; -struct readRF_rsp { - u32 value; -}; - -struct writeRF_parm { - u32 offset; - u32 value; -}; - -struct getrfintfs_parm { - u8 rfintfs; -}; - - struct Tx_Beacon_param { WLAN_BSSID_EX network; }; @@ -727,162 +520,6 @@ struct drvextra_cmd_parm { }; /*------------------- Below are used for RF/BB tunning ---------------------*/ - -struct setantenna_parm { - u8 tx_antset; - u8 rx_antset; - u8 tx_antenna; - u8 rx_antenna; -}; - -struct enrateadaptive_parm { - u32 en; -}; - -struct settxagctbl_parm { - u32 txagc[MAX_RATES_LENGTH]; -}; - -struct gettxagctbl_parm { - u32 rsvd; -}; -struct gettxagctbl_rsp { - u32 txagc[MAX_RATES_LENGTH]; -}; - -struct setagcctrl_parm { - u32 agcctrl; /* 0: pure hw, 1: fw */ -}; - - -struct setssup_parm { - u32 ss_ForceUp[MAX_RATES_LENGTH]; -}; - -struct getssup_parm { - u32 rsvd; -}; -struct getssup_rsp { - u8 ss_ForceUp[MAX_RATES_LENGTH]; -}; - - -struct setssdlevel_parm { - u8 ss_DLevel[MAX_RATES_LENGTH]; -}; - -struct getssdlevel_parm { - u32 rsvd; -}; -struct getssdlevel_rsp { - u8 ss_DLevel[MAX_RATES_LENGTH]; -}; - -struct setssulevel_parm { - u8 ss_ULevel[MAX_RATES_LENGTH]; -}; - -struct getssulevel_parm { - u32 rsvd; -}; -struct getssulevel_rsp { - u8 ss_ULevel[MAX_RATES_LENGTH]; -}; - - -struct setcountjudge_parm { - u8 count_judge[MAX_RATES_LENGTH]; -}; - -struct getcountjudge_parm { - u32 rsvd; -}; -struct getcountjudge_rsp { - u8 count_judge[MAX_RATES_LENGTH]; -}; - - -struct setratable_parm { - u8 ss_ForceUp[NumRates]; - u8 ss_ULevel[NumRates]; - u8 ss_DLevel[NumRates]; - u8 count_judge[NumRates]; -}; - -struct getratable_parm { - uint rsvd; -}; -struct getratable_rsp { - u8 ss_ForceUp[NumRates]; - u8 ss_ULevel[NumRates]; - u8 ss_DLevel[NumRates]; - u8 count_judge[NumRates]; -}; - - -/* to get TX,RX retry count */ -struct gettxretrycnt_parm { - unsigned int rsvd; -}; -struct gettxretrycnt_rsp { - unsigned long tx_retrycnt; -}; - -struct getrxretrycnt_parm { - unsigned int rsvd; -}; -struct getrxretrycnt_rsp { - unsigned long rx_retrycnt; -}; - -/* to get BCNOK,BCNERR count */ -struct getbcnokcnt_parm { - unsigned int rsvd; -}; -struct getbcnokcnt_rsp { - unsigned long bcnokcnt; -}; - -struct getbcnerrcnt_parm { - unsigned int rsvd; -}; -struct getbcnerrcnt_rsp { - unsigned long bcnerrcnt; -}; - -/* to get current TX power level */ -struct getcurtxpwrlevel_parm { - unsigned int rsvd; -}; -struct getcurtxpwrlevel_rsp { - unsigned short tx_power; -}; - -struct setprobereqextraie_parm { - unsigned char e_id; - unsigned char ie_len; - unsigned char ie[0]; -}; - -struct setassocreqextraie_parm { - unsigned char e_id; - unsigned char ie_len; - unsigned char ie[0]; -}; - -struct setproberspextraie_parm { - unsigned char e_id; - unsigned char ie_len; - unsigned char ie[0]; -}; - -struct setassocrspextraie_parm { - unsigned char e_id; - unsigned char ie_len; - unsigned char ie[0]; -}; - - struct addBaReq_parm { unsigned int tid; u8 addr[ETH_ALEN]; @@ -896,86 +533,41 @@ struct addBaRsp_parm { u8 size; }; -/*H2C Handler index: 46 */ struct set_ch_parm { u8 ch; u8 bw; u8 ch_offset; }; -#ifdef MP_FIRMWARE_OFFLOAD -/*H2C Handler index: 47 */ -struct SetTxPower_parm { - u8 TxPower; -}; - -/*H2C Handler index: 48 */ -struct SwitchAntenna_parm { - u16 antenna_tx; - u16 antenna_rx; - /* R_ANTENNA_SELECT_CCK cck_txrx; */ - u8 cck_txrx; -}; - -/*H2C Handler index: 49 */ -struct SetCrystalCap_parm { - u32 curr_crystalcap; -}; - -/*H2C Handler index: 50 */ -struct SetSingleCarrierTx_parm { - u8 bStart; -}; - -/*H2C Handler index: 51 */ -struct SetSingleToneTx_parm { - u8 bStart; - u8 curr_rfpath; -}; - -/*H2C Handler index: 52 */ -struct SetCarrierSuppressionTx_parm { - u8 bStart; - u32 curr_rateidx; -}; - -/*H2C Handler index: 53 */ -struct SetContinuousTx_parm { - u8 bStart; - u8 CCK_flag; /*1:CCK 2:OFDM*/ - u32 curr_rateidx; -}; - -/*H2C Handler index: 54 */ -struct SwitchBandwidth_parm { - u8 curr_bandwidth; -}; - -#endif /* MP_FIRMWARE_OFFLOAD */ - -/*H2C Handler index: 59 */ struct SetChannelPlan_param { + enum regd_src_t regd_src; const struct country_chplan *country_ent; u8 channel_plan; }; -/*H2C Handler index: 60 */ +struct get_channel_plan_param { + struct get_chplan_resp **resp; +}; + struct LedBlink_param { void *pLed; }; -/*H2C Handler index: 62 */ struct TDLSoption_param { u8 addr[ETH_ALEN]; u8 option; }; -/*H2C Handler index: 64 */ struct RunInThread_param { void (*func)(void *); void *context; }; +#ifdef CONFIG_WRITE_BCN_LEN_TO_FW +struct write_bcnlen_param { + u16 bcn_len; +}; +#endif #define GEN_CMD_CODE(cmd) cmd ## _CMD_ @@ -1005,12 +597,12 @@ Result: #define H2C_ENQ_HEAD_FAIL 0x09 #define H2C_CMD_FAIL 0x0A -extern u8 rtw_setassocsta_cmd(_adapter *padapter, u8 *mac_addr); -extern u8 rtw_setstandby_cmd(_adapter *padapter, uint action); void rtw_init_sitesurvey_parm(_adapter *padapter, struct sitesurvey_parm *pparm); u8 rtw_sitesurvey_cmd(_adapter *padapter, struct sitesurvey_parm *pparm); +#ifdef CONFIG_AP_MODE u8 rtw_create_ibss_cmd(_adapter *adapter, int flags); u8 rtw_startbss_cmd(_adapter *adapter, int flags); +#endif #define REQ_CH_NONE -1 #define REQ_CH_INT_INFO -2 @@ -1018,11 +610,6 @@ u8 rtw_startbss_cmd(_adapter *adapter, int flags); #define REQ_BW_ORI -2 #define REQ_OFFSET_NONE -1 -u8 rtw_change_bss_chbw_cmd(_adapter *adapter, int flags - , u8 ifbmp, u8 excl_ifbmp, s16 req_ch, s8 req_bw, s8 req_offset); - -extern u8 rtw_setphy_cmd(_adapter *padapter, u8 modem, u8 ch); - struct sta_info; extern u8 rtw_setstakey_cmd(_adapter *padapter, struct sta_info *sta, u8 key_type, bool enqueue); extern u8 rtw_clearstakey_cmd(_adapter *padapter, struct sta_info *sta, u8 enqueue); @@ -1030,24 +617,14 @@ extern u8 rtw_clearstakey_cmd(_adapter *padapter, struct sta_info *sta, u8 enque extern u8 rtw_joinbss_cmd(_adapter *padapter, struct wlan_network *pnetwork); u8 rtw_disassoc_cmd(_adapter *padapter, u32 deauth_timeout_ms, int flags); #ifdef CONFIG_AP_MODE +u8 rtw_change_bss_chbw_cmd(_adapter *adapter, int flags + , u8 ifbmp, u8 excl_ifbmp, s16 req_ch, s8 req_bw, s8 req_offset); u8 rtw_stop_ap_cmd(_adapter *adapter, u8 flags); #endif +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT +u8 rtw_tx_control_cmd(_adapter *adapter); +#endif extern u8 rtw_setopmode_cmd(_adapter *padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype, u8 flags); -extern u8 rtw_setdatarate_cmd(_adapter *padapter, u8 *rateset); -extern u8 rtw_setbasicrate_cmd(_adapter *padapter, u8 *rateset); -extern u8 rtw_getmacreg_cmd(_adapter *padapter, u8 len, u32 addr); -extern void rtw_usb_catc_trigger_cmd(_adapter *padapter, const char *caller); -extern u8 rtw_setbbreg_cmd(_adapter *padapter, u8 offset, u8 val); -extern u8 rtw_setrfreg_cmd(_adapter *padapter, u8 offset, u32 val); -extern u8 rtw_getbbreg_cmd(_adapter *padapter, u8 offset, u8 *pval); -extern u8 rtw_getrfreg_cmd(_adapter *padapter, u8 offset, u8 *pval); -extern u8 rtw_setrfintfs_cmd(_adapter *padapter, u8 mode); -extern u8 rtw_setrttbl_cmd(_adapter *padapter, struct setratable_parm *prate_table); -extern u8 rtw_getrttbl_cmd(_adapter *padapter, struct getratable_rsp *pval); - -extern u8 rtw_gettssi_cmd(_adapter *padapter, u8 offset, u8 *pval); -extern u8 rtw_setfwdig_cmd(_adapter *padapter, u8 type); -extern u8 rtw_setfwra_cmd(_adapter *padapter, u8 type); extern u8 rtw_addbareq_cmd(_adapter *padapter, u8 tid, u8 *addr); extern u8 rtw_addbarsp_cmd(_adapter *padapter, u8 *addr, u16 tid, u8 status, u8 size, u16 start_seq); @@ -1101,9 +678,14 @@ u8 rtw_enable_hw_update_tsf_cmd(_adapter *padapter); u8 rtw_periodic_tsf_update_end_cmd(_adapter *adapter); u8 rtw_set_chbw_cmd(_adapter *padapter, u8 ch, u8 bw, u8 ch_offset, u8 flags); +u8 rtw_iqk_cmd(_adapter *padapter, u8 flags); u8 rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, u8 swconfig); u8 rtw_set_country_cmd(_adapter *adapter, int flags, const char *country_code, u8 swconfig); +#ifdef CONFIG_REGD_SRC_FROM_OS +u8 rtw_sync_os_regd_cmd(_adapter *adapter, int flags, const char *country_code, u8 dfs_region); +#endif +u8 rtw_get_chplan_cmd(_adapter *adapter, int flags, struct get_chplan_resp **resp); extern u8 rtw_led_blink_cmd(_adapter *padapter, void *pLed); extern u8 rtw_set_csa_cmd(_adapter *adapter); @@ -1147,6 +729,14 @@ u8 set_txq_params_cmd(_adapter *adapter, u32 ac_parm, u8 ac_type); #if defined(CONFIG_RTW_MESH) && defined(RTW_PER_CMD_SUPPORT_FW) u8 rtw_req_per_cmd(_adapter * adapter); #endif +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT +u8 rtw_tbtx_chk_cmd(_adapter *adapter); +u8 rtw_tbtx_token_dispatch_cmd(_adapter *adapter); +#endif + +#ifdef CONFIG_WRITE_BCN_LEN_TO_FW +u8 rtw_write_bcnlen_to_fw_cmd(_adapter *padapter, u16 bcn_len); +#endif #ifdef CONFIG_CTRL_TXSS_BY_TP struct txss_cmd_parm { @@ -1169,192 +759,44 @@ extern void rtw_survey_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); extern void rtw_disassoc_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); extern void rtw_joinbss_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); void rtw_create_ibss_post_hdl(_adapter *padapter, int status); -extern void rtw_getbbrfreg_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); extern void rtw_readtssi_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); extern void rtw_setstaKey_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); -extern void rtw_setassocsta_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); extern void rtw_getrttbl_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); -extern void rtw_getmacreg_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); - -struct _cmd_callback { - u32 cmd_code; - void (*callback)(_adapter *padapter, struct cmd_obj *cmd); +enum rtw_cmd_id { + CMD_JOINBSS, /*0*/ + CMD_DISCONNECT, /*1*/ + CMD_CREATE_BSS,/*2*/ + CMD_SET_OPMODE, /*3*/ + CMD_SITE_SURVEY, /*4*/ + CMD_SET_AUTH, /*5*/ + CMD_SET_KEY, /*6*/ + CMD_SET_STAKEY, /*7*/ + CMD_ADD_BAREQ, /*8*/ + CMD_SET_CHANNEL, /*9*/ + CMD_TX_BEACON, /*10*/ + CMD_SET_MLME_EVT, /*11*/ + CMD_SET_DRV_EXTRA, /*12*/ + CMD_SET_CHANPLAN, /*13*/ + CMD_LEDBLINK, /*14*/ + CMD_SET_CHANSWITCH, /*15*/ + CMD_TDLS, /*16*/ + CMD_CHK_BMCSLEEPQ, /*17*/ + CMD_RUN_INTHREAD, /*18*/ + CMD_ADD_BARSP, /*19*/ + CMD_RM_POST_EVENT, /*20*/ + CMD_SET_MESH_PLINK_STATE, /* 21 */ + CMD_DO_IQK, /* 22 */ + CMD_GET_CHANPLAN, /*23*/ + CMD_WRITE_BCN_LEN, /*24 */ + CMD_ID_MAX }; -enum rtw_h2c_cmd { - GEN_CMD_CODE(_Read_MACREG) , /*0*/ - GEN_CMD_CODE(_Write_MACREG) , - GEN_CMD_CODE(_Read_BBREG) , - GEN_CMD_CODE(_Write_BBREG) , - GEN_CMD_CODE(_Read_RFREG) , - GEN_CMD_CODE(_Write_RFREG) , /*5*/ - GEN_CMD_CODE(_Read_EEPROM) , - GEN_CMD_CODE(_Write_EEPROM) , - GEN_CMD_CODE(_Read_EFUSE) , - GEN_CMD_CODE(_Write_EFUSE) , - - GEN_CMD_CODE(_Read_CAM) , /*10*/ - GEN_CMD_CODE(_Write_CAM) , - GEN_CMD_CODE(_setBCNITV), - GEN_CMD_CODE(_setMBIDCFG), - GEN_CMD_CODE(_JoinBss), /*14*/ - GEN_CMD_CODE(_DisConnect) , /*15*/ - GEN_CMD_CODE(_CreateBss) , - GEN_CMD_CODE(_SetOpMode) , - GEN_CMD_CODE(_SiteSurvey), /*18*/ - GEN_CMD_CODE(_SetAuth) , - - GEN_CMD_CODE(_SetKey) , /*20*/ - GEN_CMD_CODE(_SetStaKey) , - GEN_CMD_CODE(_SetAssocSta) , - GEN_CMD_CODE(_DelAssocSta) , - GEN_CMD_CODE(_SetStaPwrState) , - GEN_CMD_CODE(_SetBasicRate) , /*25*/ - GEN_CMD_CODE(_GetBasicRate) , - GEN_CMD_CODE(_SetDataRate) , - GEN_CMD_CODE(_GetDataRate) , - GEN_CMD_CODE(_SetPhyInfo) , - - GEN_CMD_CODE(_GetPhyInfo) , /*30*/ - GEN_CMD_CODE(_SetPhy) , - GEN_CMD_CODE(_GetPhy) , - GEN_CMD_CODE(_readRssi) , - GEN_CMD_CODE(_readGain) , - GEN_CMD_CODE(_SetAtim) , /*35*/ - GEN_CMD_CODE(_SetPwrMode) , - GEN_CMD_CODE(_JoinbssRpt), - GEN_CMD_CODE(_SetRaTable) , - GEN_CMD_CODE(_GetRaTable) , - - GEN_CMD_CODE(_GetCCXReport), /*40*/ - GEN_CMD_CODE(_GetDTMReport), - GEN_CMD_CODE(_GetTXRateStatistics), - GEN_CMD_CODE(_SetUsbSuspend), - GEN_CMD_CODE(_SetH2cLbk), - GEN_CMD_CODE(_AddBAReq) , /*45*/ - GEN_CMD_CODE(_SetChannel), /*46*/ - GEN_CMD_CODE(_SetTxPower), - GEN_CMD_CODE(_SwitchAntenna), - GEN_CMD_CODE(_SetCrystalCap), - GEN_CMD_CODE(_SetSingleCarrierTx), /*50*/ - - GEN_CMD_CODE(_SetSingleToneTx),/*51*/ - GEN_CMD_CODE(_SetCarrierSuppressionTx), - GEN_CMD_CODE(_SetContinuousTx), - GEN_CMD_CODE(_SwitchBandwidth), /*54*/ - GEN_CMD_CODE(_TX_Beacon), /*55*/ - - GEN_CMD_CODE(_Set_MLME_EVT), /*56*/ - GEN_CMD_CODE(_Set_Drv_Extra), /*57*/ - GEN_CMD_CODE(_Set_H2C_MSG), /*58*/ - - GEN_CMD_CODE(_SetChannelPlan), /*59*/ - GEN_CMD_CODE(_LedBlink), /*60*/ - - GEN_CMD_CODE(_SetChannelSwitch), /*61*/ - GEN_CMD_CODE(_TDLS), /*62*/ - GEN_CMD_CODE(_ChkBMCSleepq), /*63*/ - - GEN_CMD_CODE(_RunInThreadCMD), /*64*/ - GEN_CMD_CODE(_AddBARsp) , /*65*/ - GEN_CMD_CODE(_RM_POST_EVENT), /*66*/ - - MAX_H2CCMD -}; - -#define _GetMACReg_CMD_ _Read_MACREG_CMD_ -#define _SetMACReg_CMD_ _Write_MACREG_CMD_ -#define _GetBBReg_CMD_ _Read_BBREG_CMD_ -#define _SetBBReg_CMD_ _Write_BBREG_CMD_ -#define _GetRFReg_CMD_ _Read_RFREG_CMD_ -#define _SetRFReg_CMD_ _Write_RFREG_CMD_ - -#ifdef _RTW_CMD_C_ -struct _cmd_callback rtw_cmd_callback[] = { - {GEN_CMD_CODE(_Read_MACREG), &rtw_getmacreg_cmdrsp_callback}, /*0*/ - {GEN_CMD_CODE(_Write_MACREG), NULL}, - {GEN_CMD_CODE(_Read_BBREG), &rtw_getbbrfreg_cmdrsp_callback}, - {GEN_CMD_CODE(_Write_BBREG), NULL}, - {GEN_CMD_CODE(_Read_RFREG), &rtw_getbbrfreg_cmdrsp_callback}, - {GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/ - {GEN_CMD_CODE(_Read_EEPROM), NULL}, - {GEN_CMD_CODE(_Write_EEPROM), NULL}, - {GEN_CMD_CODE(_Read_EFUSE), NULL}, - {GEN_CMD_CODE(_Write_EFUSE), NULL}, - - {GEN_CMD_CODE(_Read_CAM), NULL}, /*10*/ - {GEN_CMD_CODE(_Write_CAM), NULL}, - {GEN_CMD_CODE(_setBCNITV), NULL}, - {GEN_CMD_CODE(_setMBIDCFG), NULL}, - {GEN_CMD_CODE(_JoinBss), &rtw_joinbss_cmd_callback}, /*14*/ - {GEN_CMD_CODE(_DisConnect), &rtw_disassoc_cmd_callback}, /*15*/ - {GEN_CMD_CODE(_CreateBss), NULL}, - {GEN_CMD_CODE(_SetOpMode), NULL}, - {GEN_CMD_CODE(_SiteSurvey), &rtw_survey_cmd_callback}, /*18*/ - {GEN_CMD_CODE(_SetAuth), NULL}, - - {GEN_CMD_CODE(_SetKey), NULL}, /*20*/ - {GEN_CMD_CODE(_SetStaKey), &rtw_setstaKey_cmdrsp_callback}, - {GEN_CMD_CODE(_SetAssocSta), &rtw_setassocsta_cmdrsp_callback}, - {GEN_CMD_CODE(_DelAssocSta), NULL}, - {GEN_CMD_CODE(_SetStaPwrState), NULL}, - {GEN_CMD_CODE(_SetBasicRate), NULL}, /*25*/ - {GEN_CMD_CODE(_GetBasicRate), NULL}, - {GEN_CMD_CODE(_SetDataRate), NULL}, - {GEN_CMD_CODE(_GetDataRate), NULL}, - {GEN_CMD_CODE(_SetPhyInfo), NULL}, - - {GEN_CMD_CODE(_GetPhyInfo), NULL}, /*30*/ - {GEN_CMD_CODE(_SetPhy), NULL}, - {GEN_CMD_CODE(_GetPhy), NULL}, - {GEN_CMD_CODE(_readRssi), NULL}, - {GEN_CMD_CODE(_readGain), NULL}, - {GEN_CMD_CODE(_SetAtim), NULL}, /*35*/ - {GEN_CMD_CODE(_SetPwrMode), NULL}, - {GEN_CMD_CODE(_JoinbssRpt), NULL}, - {GEN_CMD_CODE(_SetRaTable), NULL}, - {GEN_CMD_CODE(_GetRaTable) , NULL}, - - {GEN_CMD_CODE(_GetCCXReport), NULL}, /*40*/ - {GEN_CMD_CODE(_GetDTMReport), NULL}, - {GEN_CMD_CODE(_GetTXRateStatistics), NULL}, - {GEN_CMD_CODE(_SetUsbSuspend), NULL}, - {GEN_CMD_CODE(_SetH2cLbk), NULL}, - {GEN_CMD_CODE(_AddBAReq), NULL}, /*45*/ - {GEN_CMD_CODE(_SetChannel), NULL}, /*46*/ - {GEN_CMD_CODE(_SetTxPower), NULL}, - {GEN_CMD_CODE(_SwitchAntenna), NULL}, - {GEN_CMD_CODE(_SetCrystalCap), NULL}, - {GEN_CMD_CODE(_SetSingleCarrierTx), NULL}, /*50*/ - - {GEN_CMD_CODE(_SetSingleToneTx), NULL}, /*51*/ - {GEN_CMD_CODE(_SetCarrierSuppressionTx), NULL}, - {GEN_CMD_CODE(_SetContinuousTx), NULL}, - {GEN_CMD_CODE(_SwitchBandwidth), NULL}, /*54*/ - {GEN_CMD_CODE(_TX_Beacon), NULL},/*55*/ - - {GEN_CMD_CODE(_Set_MLME_EVT), NULL},/*56*/ - {GEN_CMD_CODE(_Set_Drv_Extra), NULL},/*57*/ - {GEN_CMD_CODE(_Set_H2C_MSG), NULL},/*58*/ - {GEN_CMD_CODE(_SetChannelPlan), NULL},/*59*/ - {GEN_CMD_CODE(_LedBlink), NULL},/*60*/ - - {GEN_CMD_CODE(_SetChannelSwitch), NULL},/*61*/ - {GEN_CMD_CODE(_TDLS), NULL},/*62*/ - {GEN_CMD_CODE(_ChkBMCSleepq), NULL}, /*63*/ - - {GEN_CMD_CODE(_RunInThreadCMD), NULL},/*64*/ - {GEN_CMD_CODE(_AddBARsp), NULL}, /*65*/ - {GEN_CMD_CODE(_RM_POST_EVENT), NULL}, /*66*/ -}; -#endif - #define CMD_FMT "cmd=%d,%d,%d" #define CMD_ARG(cmd) \ (cmd)->cmdcode, \ - (cmd)->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra) ? ((struct drvextra_cmd_parm *)(cmd)->parmbuf)->ec_id : ((cmd)->cmdcode == GEN_CMD_CODE(_Set_MLME_EVT) ? ((struct C2HEvent_Header *)(cmd)->parmbuf)->ID : 0), \ - (cmd)->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra) ? ((struct drvextra_cmd_parm *)(cmd)->parmbuf)->type : 0 + (cmd)->cmdcode == CMD_SET_DRV_EXTRA ? ((struct drvextra_cmd_parm *)(cmd)->parmbuf)->ec_id : ((cmd)->cmdcode == CMD_SET_MLME_EVT ? ((struct rtw_evt_header *)(cmd)->parmbuf)->id : 0), \ + (cmd)->cmdcode == CMD_SET_DRV_EXTRA ? ((struct drvextra_cmd_parm *)(cmd)->parmbuf)->type : 0 #endif /* _CMD_H_ */ diff --git a/include/rtw_debug.h b/include/rtw_debug.h index 81230d6..1ce9af3 100644 --- a/include/rtw_debug.h +++ b/include/rtw_debug.h @@ -131,13 +131,15 @@ extern uint rtw_drv_log_level; #define EX_INFO_ARG "" #endif /* !PLATFORM_LINUX */ +#define DBG_PREFIX EX_INFO_FMT DRIVER_PREFIX +#define DBG_PREFIX_ARG EX_INFO_ARG + /* with driver-defined prefix */ #undef RTW_PRINT #define RTW_PRINT(fmt, arg...) \ do {\ if (_DRV_ALWAYS_ <= rtw_drv_log_level) {\ - _dbgdump(EX_INFO_FMT DRIVER_PREFIX fmt, \ - EX_INFO_ARG, ##arg);\ + _dbgdump(DBG_PREFIX fmt, DBG_PREFIX_ARG, ##arg);\ } \ } while (0) @@ -145,8 +147,8 @@ extern uint rtw_drv_log_level; #define RTW_ERR(fmt, arg...) \ do {\ if (_DRV_ERR_ <= rtw_drv_log_level) {\ - _dbgdump(EX_INFO_FMT DRIVER_PREFIX "ERROR " fmt, \ - EX_INFO_ARG, ##arg);\ + _dbgdump(DBG_PREFIX "ERROR " fmt, \ + DBG_PREFIX_ARG, ##arg);\ } \ } while (0) @@ -155,8 +157,8 @@ extern uint rtw_drv_log_level; #define RTW_WARN(fmt, arg...) \ do {\ if (_DRV_WARNING_ <= rtw_drv_log_level) {\ - _dbgdump(EX_INFO_FMT DRIVER_PREFIX "WARN " fmt, \ - EX_INFO_ARG, ##arg);\ + _dbgdump(DBG_PREFIX "WARN " fmt, \ + DBG_PREFIX_ARG, ##arg);\ } \ } while (0) @@ -164,8 +166,7 @@ extern uint rtw_drv_log_level; #define RTW_INFO(fmt, arg...) \ do {\ if (_DRV_INFO_ <= rtw_drv_log_level) {\ - _dbgdump(EX_INFO_FMT DRIVER_PREFIX fmt, \ - EX_INFO_ARG, ##arg);\ + _dbgdump(DBG_PREFIX fmt, DBG_PREFIX_ARG, ##arg);\ } \ } while (0) @@ -174,8 +175,7 @@ extern uint rtw_drv_log_level; #define RTW_DBG(fmt, arg...) \ do {\ if (_DRV_DEBUG_ <= rtw_drv_log_level) {\ - _dbgdump(EX_INFO_FMT DRIVER_PREFIX fmt, \ - EX_INFO_ARG, ##arg);\ + _dbgdump(DBG_PREFIX fmt, DBG_PREFIX_ARG, ##arg);\ } \ } while (0) @@ -284,7 +284,6 @@ extern uint rtw_drv_log_level; void dump_drv_version(void *sel); void dump_log_level(void *sel); -void dump_drv_cfg(void *sel); #ifdef CONFIG_SDIO_HCI void sd_f0_reg_dump(void *sel, _adapter *adapter); @@ -306,8 +305,10 @@ void dump_tx_rate_bmp(void *sel, struct dvobj_priv *dvobj); void dump_adapters_status(void *sel, struct dvobj_priv *dvobj); struct sec_cam_ent; +#if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG) void dump_sec_cam_ent(void *sel, struct sec_cam_ent *ent, int id); void dump_sec_cam_ent_title(void *sel, u8 has_id); +#endif void dump_sec_cam(void *sel, _adapter *adapter); void dump_sec_cam_cache(void *sel, _adapter *adapter); @@ -327,7 +328,7 @@ u16 rtw_ap_linking_test_force_asoc_fail(void); ssize_t proc_set_write_reg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); int proc_get_read_reg(struct seq_file *m, void *v); ssize_t proc_set_read_reg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); - +void dump_drv_cfg(void *sel); int proc_get_fwstate(struct seq_file *m, void *v); int proc_get_sec_info(struct seq_file *m, void *v); int proc_get_mlmext_state(struct seq_file *m, void *v); @@ -338,10 +339,6 @@ int proc_get_roam_param(struct seq_file *m, void *v); ssize_t proc_set_roam_param(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); ssize_t proc_set_roam_tgt_addr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); #endif /* CONFIG_LAYER2_ROAMING */ -#ifdef CONFIG_RTW_80211R -int proc_get_ft_flags(struct seq_file *m, void *v); -ssize_t proc_set_ft_flags(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); -#endif int proc_get_qos_option(struct seq_file *m, void *v); int proc_get_ht_option(struct seq_file *m, void *v); int proc_get_rf_info(struct seq_file *m, void *v); @@ -443,6 +440,10 @@ ssize_t proc_set_ldpc_cap(struct file *file, const char __user *buffer, size_t c int proc_get_txbf_cap(struct seq_file *m, void *v); ssize_t proc_set_txbf_cap(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); #endif +#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT +int proc_get_tx_aval_th(struct seq_file *m, void *v); +ssize_t proc_set_tx_aval_th(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#endif /*CONFIG_SDIO_TX_ENABLE_AVAL_INT*/ int proc_get_rx_ampdu_factor(struct seq_file *m, void *v); ssize_t proc_set_rx_ampdu_factor(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); @@ -455,6 +456,8 @@ ssize_t proc_set_rx_ampdu_density(struct file *file, const char __user *buffer, int proc_get_tx_ampdu_density(struct seq_file *m, void *v); ssize_t proc_set_tx_ampdu_density(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_tx_quick_addba_req(struct seq_file *m, void *v); +ssize_t proc_set_tx_quick_addba_req(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); #ifdef CONFIG_TX_AMSDU int proc_get_tx_amsdu(struct seq_file *m, void *v); ssize_t proc_set_tx_amsdu(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); @@ -463,6 +466,14 @@ ssize_t proc_set_tx_amsdu_rate(struct file *file, const char __user *buffer, siz #endif #endif /* CONFIG_80211N_HT */ +#ifdef CONFIG_80211AC_VHT +int proc_get_vht_24g_enable(struct seq_file *m, void *v); +ssize_t proc_set_vht_24g_enable(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#endif + +ssize_t proc_set_dyn_rrsr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_dyn_rrsr(struct seq_file *m, void *v); + int proc_get_en_fwps(struct seq_file *m, void *v); ssize_t proc_set_en_fwps(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); @@ -514,6 +525,9 @@ ssize_t proc_set_tx_ring_ext(struct file *file, const char __user *buffer, size_ #endif #ifdef CONFIG_WOWLAN +int proc_get_wow_enable(struct seq_file *m, void *v); +ssize_t proc_set_wow_enable(struct file *file, const char __user *buffer, + size_t count, loff_t *pos, void *data); int proc_get_pattern_info(struct seq_file *m, void *v); ssize_t proc_set_pattern_info(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); @@ -521,8 +535,29 @@ int proc_get_wakeup_event(struct seq_file *m, void *v); ssize_t proc_set_wakeup_event(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); int proc_get_wakeup_reason(struct seq_file *m, void *v); +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +int proc_dump_wow_keep_alive_info(struct seq_file *m, void *v); +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ #endif +#ifdef CONFIG_WAR_OFFLOAD +int proc_get_war_offload_enable(struct seq_file *m, void *v); +ssize_t proc_set_war_offload_enable(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_war_offload_ipv4_addr(struct seq_file *m, void *v); +ssize_t proc_set_war_offload_ipv4_addr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_war_offload_ipv6_addr(struct seq_file *m, void *v); +ssize_t proc_set_war_offload_ipv6_addr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_war_offload_mdns_domain_name(struct seq_file *m, void *v); +ssize_t proc_set_war_offload_mdns_domain_name(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_war_offload_mdns_machine_name(struct seq_file *m, void *v); +ssize_t proc_set_war_offload_mdns_machine_name(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_war_offload_mdns_txt_rsp(struct seq_file *m, void *v); +ssize_t proc_set_war_offload_mdns_txt_rsp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_war_offload_mdns_service_info(struct seq_file *m, void *v); +ssize_t proc_set_war_offload_mdns_service_info(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#endif /* CONFIG_WAR_OFFLOAD */ + + #ifdef CONFIG_GPIO_WAKEUP int proc_get_wowlan_gpio_info(struct seq_file *m, void *v); ssize_t proc_set_wowlan_gpio_info(struct file *file, const char __user *buffer, @@ -554,6 +589,11 @@ int proc_get_tdls_info(struct seq_file *m, void *v); int proc_get_monitor(struct seq_file *m, void *v); ssize_t proc_set_monitor(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#ifdef RTW_SIMPLE_CONFIG +int proc_get_simple_config(struct seq_file *m, void *v); +ssize_t proc_set_simple_config(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#endif + #ifdef DBG_XMIT_BLOCK int proc_get_xmit_block(struct seq_file *m, void *v); ssize_t proc_set_xmit_block(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); @@ -636,6 +676,9 @@ ssize_t proc_set_smps(struct file *file, const char __user *buffer, size_t count int proc_get_smps(struct seq_file *m, void *v); #endif +int proc_get_defs_param(struct seq_file *m, void *v); +ssize_t proc_set_defs_param(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + #define _drv_always_ 1 #define _drv_emerg_ 2 #define _drv_alert_ 3 diff --git a/include/rtw_efuse.h b/include/rtw_efuse.h index f70198d..9a07d27 100644 --- a/include/rtw_efuse.h +++ b/include/rtw_efuse.h @@ -53,17 +53,25 @@ enum _EFUSE_DEF_TYPE { /*RTL8822B 8821C BT EFUSE Define 1 BANK 128 size logical map 1024*/ #ifdef RTW_HALMAC #define BANK_NUM 1 -#define EFUSE_BT_REAL_BANK_CONTENT_LEN 128 +#if defined(CONFIG_RTL8723F) +#define EFUSE_BT_REAL_BANK_CONTENT_LEN 512 +#else +#define EFUSE_BT_REAL_BANK_CONTENT_LEN 128 +#endif + #define EFUSE_BT_REAL_CONTENT_LEN (EFUSE_BT_REAL_BANK_CONTENT_LEN * BANK_NUM) #define EFUSE_BT_MAP_LEN 1024 /* 1k bytes */ #define EFUSE_BT_MAX_SECTION (EFUSE_BT_MAP_LEN / 8) -#ifdef CONFIG_RTL8822C + +#if defined(CONFIG_RTL8822C) #define EFUSE_PROTECT_BYTES_BANK 54 +#elif defined(CONFIG_RTL8723F) +#define EFUSE_PROTECT_BYTES_BANK 40 #else #define EFUSE_PROTECT_BYTES_BANK 16 #endif #define AVAILABLE_EFUSE_ADDR(addr) (addr < EFUSE_BT_REAL_CONTENT_LEN - EFUSE_PROTECT_BYTES_BANK) -#endif +#endif /* #ifdef RTW_HALMAC */ #define EXT_HEADER(header) ((header & 0x1F) == 0x0F) #define ALL_WORDS_DISABLED(wde) ((wde & 0x0F) == 0x0F) @@ -211,7 +219,9 @@ u8 rtw_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); u8 rtw_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); u8 rtw_BT_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); u8 rtw_BT_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); - +#ifdef CONFIG_RTL8822C +void rtw_pre_bt_efuse(PADAPTER padapter); +#endif u16 Efuse_GetCurrentSize(PADAPTER pAdapter, u8 efuseType, BOOLEAN bPseudoTest); u8 Efuse_CalculateWordCnts(u8 word_en); void ReadEFuseByte(PADAPTER Adapter, u16 _offset, u8 *pbuf, BOOLEAN bPseudoTest) ; @@ -264,7 +274,8 @@ extern const u8 _mac_hidden_proto_to_hal_proto_cap[]; u8 mac_hidden_wl_func_to_hal_wl_func(u8 func); #ifdef PLATFORM_LINUX -u8 rtw_efuse_file_read(PADAPTER padapter, u8 *filepatch, u8 *buf, u32 len); +u8 rtw_efuse_file_read(PADAPTER padapter, u8 *filepath, u8 *buf, u32 len); +u8 rtw_efuse_file_store(PADAPTER padapter, u8 *filepath, u8 *buf, u32 len); #ifdef CONFIG_EFUSE_CONFIG_FILE u32 rtw_read_efuse_from_file(const char *path, u8 *buf, int map_size); u32 rtw_read_macaddr_from_file(const char *path, u8 *buf); diff --git a/include/rtw_event.h b/include/rtw_event.h index e63c8d6..13e3f52 100644 --- a/include/rtw_event.h +++ b/include/rtw_event.h @@ -36,6 +36,7 @@ bss_cnt indicates the number of bss that has been reported. */ struct surveydone_event { unsigned int bss_cnt; + u8 activate_ch_cnt; bool acs; /* aim to trigger channel selection */ }; @@ -70,10 +71,6 @@ struct stadel_event { int mac_id; }; -struct addba_event { - unsigned int tid; -}; - struct wmm_event { unsigned char wmm; }; @@ -91,40 +88,8 @@ struct c2hlbk_event { }; #endif/* CONFIG_H2CLBK */ -#define GEN_EVT_CODE(event) event ## _EVT_ - - - -struct fwevent { - u32 parmsize; +struct rtw_event { + u32 parmsize; void (*event_callback)(_adapter *dev, u8 *pbuf); }; - - -#define C2HEVENT_SZ 32 - -struct event_node { - unsigned char *node; - unsigned char evt_code; - unsigned short evt_sz; - volatile int *caller_ff_tail; - int caller_ff_sz; -}; - -struct c2hevent_queue { - volatile int head; - volatile int tail; - struct event_node nodes[C2HEVENT_SZ]; - unsigned char seq; -}; - -#define NETWORK_QUEUE_SZ 4 - -struct network_queue { - volatile int head; - volatile int tail; - WLAN_BSSID_EX networks[NETWORK_QUEUE_SZ]; -}; - - #endif /* _WLANEVENT_H_ */ diff --git a/include/rtw_ft.h b/include/rtw_ft.h new file mode 100644 index 0000000..025f19e --- /dev/null +++ b/include/rtw_ft.h @@ -0,0 +1,183 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#ifndef __RTW_FT_H_ +#define __RTW_FT_H_ + +enum rtw_ieee80211_ft_actioncode { + RTW_WLAN_ACTION_FT_RESV, + RTW_WLAN_ACTION_FT_REQ, + RTW_WLAN_ACTION_FT_RSP, + RTW_WLAN_ACTION_FT_CONF, + RTW_WLAN_ACTION_FT_ACK, + RTW_WLAN_ACTION_FT_MAX, +}; + +enum _rtw_ft_sta_status { + RTW_FT_UNASSOCIATED_STA = 0, + RTW_FT_AUTHENTICATING_STA, + RTW_FT_AUTHENTICATED_STA, + RTW_FT_ASSOCIATING_STA, + RTW_FT_ASSOCIATED_STA, + RTW_FT_REQUESTING_STA, + RTW_FT_REQUESTED_STA, + RTW_FT_CONFIRMED_STA, + RTW_FT_UNSPECIFIED_STA +}; + +#define RTW_FT_ACTION_REQ_LMT 4 + +#define RTW_FT_MAX_IE_SZ 256 + +#define rtw_ft_chk_status(a, s) \ + ((a)->mlmepriv.ft_roam.ft_status == (s)) + +#define rtw_ft_roam_status(a, s) \ + ((rtw_to_roam(a) > 0) && rtw_ft_chk_status(a, s)) + +#define rtw_ft_authed_sta(a) \ + ((rtw_ft_chk_status(a, RTW_FT_AUTHENTICATED_STA)) || \ + (rtw_ft_chk_status(a, RTW_FT_ASSOCIATING_STA)) || \ + (rtw_ft_chk_status(a, RTW_FT_ASSOCIATED_STA))) + +#define rtw_ft_set_status(a, s) \ + do { \ + ((a)->mlmepriv.ft_roam.ft_status = (s)); \ + } while (0) + +#define rtw_ft_lock_set_status(a, s, irq) \ + do { \ + _enter_critical_bh(&(a)->mlmepriv.lock, ((_irqL *)(irq))); \ + ((a)->mlmepriv.ft_roam.ft_status = (s)); \ + _exit_critical_bh(&(a)->mlmepriv.lock, ((_irqL *)(irq))); \ + } while (0) + +#define rtw_ft_reset_status(a) \ + do { \ + ((a)->mlmepriv.ft_roam.ft_status = RTW_FT_UNASSOCIATED_STA); \ + } while (0) + +enum rtw_ft_capability { + RTW_FT_EN = BIT0, + RTW_FT_OTD_EN = BIT1, + RTW_FT_PEER_EN = BIT2, + RTW_FT_PEER_OTD_EN = BIT3, + RTW_FT_BTM_ROAM = BIT4, + RTW_FT_TEST_RSSI_ROAM = BIT7, +}; + +#define rtw_ft_chk_flags(a, f) \ + ((a)->mlmepriv.ft_roam.ft_flags & (f)) + +#define rtw_ft_set_flags(a, f) \ + do { \ + ((a)->mlmepriv.ft_roam.ft_flags |= (f)); \ + } while (0) + +#define rtw_ft_clr_flags(a, f) \ + do { \ + ((a)->mlmepriv.ft_roam.ft_flags &= ~(f)); \ + } while (0) + +#define rtw_ft_roam(a) \ + ((rtw_to_roam(a) > 0) && rtw_ft_chk_flags(a, RTW_FT_PEER_EN)) + +#define rtw_ft_valid_akm(a, t) \ + ((rtw_ft_chk_flags(a, RTW_FT_EN)) && \ + (((t) == 3) || ((t) == 4))) + +#define rtw_ft_roam_expired(a, r) \ + ((rtw_chk_roam_flags(a, RTW_ROAM_ON_EXPIRED)) \ + && (r == WLAN_REASON_ACTIVE_ROAM)) + +#define rtw_ft_otd_roam_en(a) \ + ((rtw_ft_chk_flags(a, RTW_FT_OTD_EN)) \ + && ((a)->mlmepriv.ft_roam.ft_roam_on_expired == _FALSE) \ + && ((a)->mlmepriv.ft_roam.ft_cap & 0x01)) + +#define rtw_ft_otd_roam(a) \ + rtw_ft_chk_flags(a, RTW_FT_PEER_OTD_EN) + +#define rtw_ft_valid_otd_candidate(a, p) \ + ((rtw_ft_chk_flags(a, RTW_FT_OTD_EN)) \ + && ((rtw_ft_chk_flags(a, RTW_FT_PEER_OTD_EN) \ + && ((*((p)+4) & 0x01) == 0)) \ + || ((rtw_ft_chk_flags(a, RTW_FT_PEER_OTD_EN) == 0) \ + && (*((p)+4) & 0x01)))) + +struct ft_roam_info { + u16 mdid; + u8 ft_cap; + /*b0: FT over DS, b1: Resource Req Protocol Cap, b2~b7: Reserved*/ + u8 updated_ft_ies[RTW_FT_MAX_IE_SZ]; + u16 updated_ft_ies_len; + u8 ft_action[RTW_FT_MAX_IE_SZ]; + u16 ft_action_len; + struct cfg80211_ft_event_params ft_event; + u8 ft_roam_on_expired; + u8 ft_flags; + u32 ft_status; + u32 ft_req_retry_cnt; + bool ft_updated_bcn; +}; + +void rtw_ft_info_init(struct ft_roam_info *pft); + +int rtw_ft_proc_flags_get(struct seq_file *m, void *v); + +ssize_t rtw_ft_proc_flags_set(struct file *file, const char __user *buffer, + size_t count, loff_t *pos, void *data); + +u8 rtw_ft_chk_roaming_candidate( + _adapter *padapter, struct wlan_network *competitor); + +void rtw_ft_update_stainfo(_adapter *padapter, WLAN_BSSID_EX *pnetwork); + +void rtw_ft_reassoc_event_callback(_adapter *padapter, u8 *pbuf); + +void rtw_ft_validate_akm_type(_adapter *padapter, + struct wlan_network *pnetwork); + +void rtw_ft_update_bcn(_adapter *padapter, union recv_frame *precv_frame); + +void rtw_ft_start_clnt_join(_adapter *padapter); + +u8 rtw_ft_update_rsnie( + _adapter *padapter, u8 bwrite, + struct pkt_attrib *pattrib, u8 **pframe); + +void rtw_ft_build_auth_req_ies(_adapter *padapter, + struct pkt_attrib *pattrib, u8 **pframe); + +void rtw_ft_build_assoc_req_ies(_adapter *padapter, + u8 is_reassoc, struct pkt_attrib *pattrib, u8 **pframe); + +u8 rtw_ft_update_auth_rsp_ies(_adapter *padapter, u8 *pframe, u32 len); + +void rtw_ft_start_roam(_adapter *padapter, u8 *pTargetAddr); + +void rtw_ft_issue_action_req(_adapter *padapter, u8 *pTargetAddr); + +void rtw_ft_report_evt(_adapter *padapter); + +void rtw_ft_report_reassoc_evt(_adapter *padapter, u8 *pMacAddr); + +void rtw_ft_link_timer_hdl(void *ctx); + +void rtw_ft_roam_timer_hdl(void *ctx); + +void rtw_ft_roam_status_reset(_adapter *padapter); + +#endif /* __RTW_FT_H_ */ diff --git a/include/rtw_mbo.h b/include/rtw_mbo.h new file mode 100644 index 0000000..9524cb6 --- /dev/null +++ b/include/rtw_mbo.h @@ -0,0 +1,114 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#ifndef __RTW_MBO_H_ +#define __RTW_MBO_H_ + +#define rtw_mbo_wifi_logo_test(a) ((a->registrypriv.wifi_spec) == 1) + +#define rtw_mbo_set_ext_cap_internw(_pEleStart, _val) \ + SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart))+3, 7, 1, _val) + +#define rtw_mbo_wnm_notification_req(c, a) \ + (((c) == RTW_WLAN_CATEGORY_WNM) && \ + (((a) == RTW_WLAN_ACTION_WNM_NOTIF_REQ))) + +/* IEEE Std 802.11-2016 Table 9-46 - Status codes */ +#define RTW_ASSOC_DENIED_NO_MORE_STAS 17 +#define RTW_ASSOC_REFUSED_TEMPORARILY 30 + +/* MBO-OCE Information Element */ +#define RTW_MBO_EID WLAN_EID_VENDOR_SPECIFIC +#define RTW_MBO_OUI 0x506F9A +#define RTW_MBO_OUI_TYPE 0x16 + +/* Non-preferred Channel Report */ +#define RTW_MBO_ATTR_NPREF_CH_RPT_ID 0x2 +/* Cellular Data Capabilities */ +#define RTW_MBO_ATTR_CELL_DATA_CAP_ID 0x3 +/* Association Disallowed */ +#define RTW_MBO_ATTR_ASSOC_DISABLED_ID 0x4 +/* Transition Reason Code */ +#define RTW_MBO_ATTR_TRANS_RES_ID 0x6 +/* Transition Rejection Reason Code */ +#define RTW_MBO_ATTR_TRANS_REJ_ID 0x7 +/* Association Retry Delay */ +#define RTW_MBO_ATTR_TASSOC_RETRY_ID 0x8 + +#define RTW_MBO_MAX_CH_LIST_NUM MAX_CHANNEL_NUM + +#define RTW_MBO_MAX_CH_RPT_NUM 32 + +struct npref_ch { + u8 op_class; + u8 chs[RTW_MBO_MAX_CH_LIST_NUM]; + size_t nm_of_ch; + u8 preference; + u8 reason; +}; + +struct npref_ch_rtp { + struct npref_ch ch_rpt[RTW_MBO_MAX_CH_RPT_NUM]; + size_t nm_of_rpt; +}; + +void rtw_mbo_build_cell_data_cap_attr( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib); + +void rtw_mbo_update_ie_data( + _adapter *padapter, u8 *pie, u32 ie_len); + +void rtw_mbo_build_supp_op_class_elem( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib); + +void rtw_mbo_build_npref_ch_rpt_attr( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib); + +void rtw_mbo_build_trans_reject_reason_attr( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib, u8 *pres); + +u8 rtw_mbo_disallowed_network(struct wlan_network *pnetwork); + +void rtw_mbo_build_exented_cap( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib); + +ssize_t rtw_mbo_proc_non_pref_chans_set( + struct file *pfile, const char __user *buffer, + size_t count, loff_t *pos, void *pdata); + +int rtw_mbo_proc_non_pref_chans_get( + struct seq_file *m, void *v); + +ssize_t rtw_mbo_proc_cell_data_set( + struct file *pfile, const char __user *buffer, + size_t count, loff_t *pos, void *pdata); + +int rtw_mbo_proc_cell_data_get( + struct seq_file *m, void *v); + +void rtw_mbo_wnm_notification_parsing( + _adapter *padapter, const u8 *pdata, size_t data_len); + +void rtw_mbo_build_wnm_notification( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib); + +void rtw_mbo_build_probe_req_ies( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib); + +void rtw_mbo_build_assoc_req_ies( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib); + +#endif /* __RTW_MBO_H_ */ + diff --git a/include/rtw_mcc.h b/include/rtw_mcc.h index 11598e9..5d2198b 100644 --- a/include/rtw_mcc.h +++ b/include/rtw_mcc.h @@ -54,7 +54,11 @@ #define MCC_SINGLE_TX_CRITERIA 5 /* Mbps */ #define MAX_MCC_NUM 2 +#ifdef CONFIG_RTL8822C +#define DBG_MCC_REG_NUM 3 +#else #define DBG_MCC_REG_NUM 4 +#endif #define DBG_MCC_RF_REG_NUM 1 #define MCC_STOP(adapter) (adapter->mcc_adapterpriv.mcc_tx_stop) diff --git a/include/rtw_mem.h b/include/rtw_mem.h index 5b61fb1..9e33ed5 100644 --- a/include/rtw_mem.h +++ b/include/rtw_mem.h @@ -19,18 +19,6 @@ #include #include -#ifdef CONFIG_SDIO_HCI -#define MAX_RTKM_RECVBUF_SZ MAX_RECVBUF_SZ -#define MAX_RTKM_NR_PREALLOC_RECV_SKB NR_RECVBUFF -#else /* !CONFIG_SDIO_HCI */ -#ifdef CONFIG_PLATFORM_MSTAR_HIGH - #define MAX_RTKM_RECVBUF_SZ (31744) /* 31k */ -#else - #define MAX_RTKM_RECVBUF_SZ (15360) /* 15k */ -#endif /* CONFIG_PLATFORM_MSTAR_HIGH */ -#define MAX_RTKM_NR_PREALLOC_RECV_SKB 16 -#endif /* !CONFIG_SDIO_HCI */ - u16 rtw_rtkm_get_buff_size(void); u8 rtw_rtkm_get_nr_recv_skb(void); struct u8 *rtw_alloc_revcbuf_premem(void); diff --git a/include/rtw_mi.h b/include/rtw_mi.h index 5f544dc..0eb8b53 100644 --- a/include/rtw_mi.h +++ b/include/rtw_mi.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2017 Realtek Corporation. + * Copyright(c) 2007 - 2019 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -25,29 +25,27 @@ int rtw_mi_get_ch_setting_union_no_self(_adapter *adapter, u8 *ch, u8 *bw, u8 *o struct mi_state { u8 sta_num; /* WIFI_STATION_STATE */ - u8 ld_sta_num; /* WIFI_STATION_STATE && _FW_LINKED */ - u8 lg_sta_num; /* WIFI_STATION_STATE && _FW_UNDER_LINKING */ + u8 ld_sta_num; /* WIFI_STATION_STATE && WIFI_ASOC_STATE */ + u8 lg_sta_num; /* WIFI_STATION_STATE && WIFI_UNDER_LINKING */ #ifdef CONFIG_TDLS u8 ld_tdls_num; /* adapter.tdlsinfo.link_established */ #endif #ifdef CONFIG_AP_MODE - u8 ap_num; /* WIFI_AP_STATE && _FW_LINKED */ + u8 ap_num; /* WIFI_AP_STATE && WIFI_ASOC_STATE */ u8 starting_ap_num; /*WIFI_FW_AP_STATE*/ - u8 ld_ap_num; /* WIFI_AP_STATE && _FW_LINKED && asoc_sta_count > 2 */ + u8 ld_ap_num; /* WIFI_AP_STATE && WIFI_ASOC_STATE && asoc_sta_count > 2 */ #endif - u8 adhoc_num; /* (WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) && _FW_LINKED */ - u8 ld_adhoc_num; /* (WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) && _FW_LINKED && asoc_sta_count > 2 */ + u8 adhoc_num; /* (WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) && WIFI_ASOC_STATE */ + u8 ld_adhoc_num; /* (WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) && WIFI_ASOC_STATE && asoc_sta_count > 2 */ #ifdef CONFIG_RTW_MESH - u8 mesh_num; /* WIFI_MESH_STATE && _FW_LINKED */ - u8 ld_mesh_num; /* WIFI_MESH_STATE && _FW_LINKED && asoc_sta_count > 2 */ + u8 mesh_num; /* WIFI_MESH_STATE && WIFI_ASOC_STATE */ + u8 ld_mesh_num; /* WIFI_MESH_STATE && WIFI_ASOC_STATE && asoc_sta_count > 2 */ #endif - u8 scan_num; /* WIFI_SITE_MONITOR */ - u8 scan_enter_num; /* WIFI_SITE_MONITOR && !SCAN_DISABLE && !SCAN_BACK_OP */ + u8 scan_num; /* WIFI_UNDER_SURVEY */ + u8 scan_enter_num; /* WIFI_UNDER_SURVEY && !SCAN_DISABLE && !SCAN_BACK_OP */ u8 uwps_num; /* WIFI_UNDER_WPS */ #ifdef CONFIG_IOCTL_CFG80211 - #ifdef CONFIG_P2P u8 roch_num; - #endif u8 mgmt_tx_num; #endif #ifdef CONFIG_P2P @@ -55,9 +53,6 @@ struct mi_state { u8 p2p_gc; u8 p2p_go; #endif - u8 union_ch; - u8 union_bw; - u8 union_offset; }; #define MSTATE_STA_NUM(_mstate) ((_mstate)->sta_num) @@ -95,7 +90,7 @@ struct mi_state { #define MSTATE_SCAN_ENTER_NUM(_mstate) ((_mstate)->scan_enter_num) #define MSTATE_WPS_NUM(_mstate) ((_mstate)->uwps_num) -#if defined(CONFIG_IOCTL_CFG80211) && defined(CONFIG_P2P) +#if defined(CONFIG_IOCTL_CFG80211) #define MSTATE_ROCH_NUM(_mstate) ((_mstate)->roch_num) #else #define MSTATE_ROCH_NUM(_mstate) 0 @@ -117,13 +112,9 @@ struct mi_state { #define MSTATE_MGMT_TX_NUM(_mstate) 0 #endif -#define MSTATE_U_CH(_mstate) ((_mstate)->union_ch) -#define MSTATE_U_BW(_mstate) ((_mstate)->union_bw) -#define MSTATE_U_OFFSET(_mstate) ((_mstate)->union_offset) - -#define rtw_mi_get_union_chan(adapter) adapter_to_dvobj(adapter)->iface_state.union_ch -#define rtw_mi_get_union_bw(adapter) adapter_to_dvobj(adapter)->iface_state.union_bw -#define rtw_mi_get_union_offset(adapter) adapter_to_dvobj(adapter)->iface_state.union_offset +#define rtw_mi_get_union_chan(adapter) ((adapter_to_dvobj(adapter)->union_ch) ? (adapter_to_dvobj(adapter)->union_ch) : (adapter_to_dvobj(adapter)->union_ch_bak)) +#define rtw_mi_get_union_bw(adapter) ((adapter_to_dvobj(adapter)->union_ch) ? (adapter_to_dvobj(adapter)->union_bw) : (adapter_to_dvobj(adapter)->union_bw_bak)) +#define rtw_mi_get_union_offset(adapter) ((adapter_to_dvobj(adapter)->union_ch) ? (adapter_to_dvobj(adapter)->union_offset) : (adapter_to_dvobj(adapter)->union_offset_bak)) #define rtw_mi_get_assoced_sta_num(adapter) DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) #define rtw_mi_get_ap_num(adapter) DEV_AP_NUM(adapter_to_dvobj(adapter)) @@ -195,16 +186,18 @@ u8 rtw_mi_buddy_is_scan_deny(_adapter *adapter); void rtw_mi_beacon_update(_adapter *padapter); void rtw_mi_buddy_beacon_update(_adapter *padapter); -void rtw_mi_hal_dump_macaddr(_adapter *padapter); -void rtw_mi_buddy_hal_dump_macaddr(_adapter *padapter); +#ifndef CONFIG_MI_WITH_MBSSID_CAM +void rtw_mi_hal_dump_macaddr(void *sel, _adapter *padapter); +void rtw_mi_buddy_hal_dump_macaddr(void *sel, _adapter *padapter); +#endif #ifdef CONFIG_PCI_HCI void rtw_mi_xmit_tasklet_schedule(_adapter *padapter); void rtw_mi_buddy_xmit_tasklet_schedule(_adapter *padapter); #endif -u8 rtw_mi_busy_traffic_check(_adapter *padapter, bool check_sc_interval); -u8 rtw_mi_buddy_busy_traffic_check(_adapter *padapter, bool check_sc_interval); +u8 rtw_mi_busy_traffic_check(_adapter *padapter); +u8 rtw_mi_buddy_busy_traffic_check(_adapter *padapter); u8 rtw_mi_check_mlmeinfo_state(_adapter *padapter, u32 state); u8 rtw_mi_buddy_check_mlmeinfo_state(_adapter *padapter, u32 state); @@ -246,6 +239,8 @@ u8 rtw_mi_buddy_check_pending_xmitbuf(_adapter *padapter); #include #elif defined(CONFIG_RTL8822C) #include +#elif defined(CONFIG_RTL8723F) + #include #else extern s32 _dequeue_writeport(PADAPTER padapter); #endif @@ -273,15 +268,17 @@ extern void sreset_start_adapter(_adapter *padapter); extern void sreset_stop_adapter(_adapter *padapter); u8 rtw_mi_sreset_adapter_hdl(_adapter *padapter, u8 bstart); u8 rtw_mi_buddy_sreset_adapter_hdl(_adapter *padapter, u8 bstart); + +#ifdef CONFIG_AP_MODE #if defined(DBG_CONFIG_ERROR_RESET) && defined(CONFIG_CONCURRENT_MODE) void rtw_mi_ap_info_restore(_adapter *adapter); #endif - u8 rtw_mi_tx_beacon_hdl(_adapter *padapter); u8 rtw_mi_buddy_tx_beacon_hdl(_adapter *padapter); u8 rtw_mi_set_tx_beacon_cmd(_adapter *padapter); u8 rtw_mi_buddy_set_tx_beacon_cmd(_adapter *padapter); +#endif /* CONFIG_AP_MODE */ #ifdef CONFIG_P2P u8 rtw_mi_p2p_chk_state(_adapter *padapter, enum P2P_STATE p2p_state); diff --git a/include/rtw_mlme.h b/include/rtw_mlme.h index 91b0d7c..e3095a5 100644 --- a/include/rtw_mlme.h +++ b/include/rtw_mlme.h @@ -23,47 +23,46 @@ /* Commented by Albert 20101105 * Increase the scanning timeout because of increasing the SURVEY_TO value. */ - - -#ifdef PALTFORM_OS_WINCE -#define SCANQUEUE_LIFETIME 12000000 /* unit:us */ -#else #define SCANQUEUE_LIFETIME 20000 /* 20sec, unit:msec */ -#endif -#define WIFI_NULL_STATE 0x00000000 -#define WIFI_ASOC_STATE 0x00000001 /* Linked */ -#define WIFI_REASOC_STATE 0x00000002 -#define WIFI_SLEEP_STATE 0x00000004 -#define WIFI_STATION_STATE 0x00000008 -#define WIFI_AP_STATE 0x00000010 -#define WIFI_ADHOC_STATE 0x00000020 -#define WIFI_ADHOC_MASTER_STATE 0x00000040 -#define WIFI_UNDER_LINKING 0x00000080 -#define WIFI_UNDER_WPS 0x00000100 -#define WIFI_MESH_STATE 0x00000200 +#define MAX_UNASSOC_STA_CNT 128 +#define UNASSOC_STA_LIFETIME_MS 60000 + +/*pmlmepriv->fw_state*/ +#define WIFI_NULL_STATE 0x00000000 +#define WIFI_ASOC_STATE 0x00000001 /* Linked */ +#define WIFI_REASOC_STATE 0x00000002 +#define WIFI_SLEEP_STATE 0x00000004 +#define WIFI_STATION_STATE 0x00000008 +#define WIFI_AP_STATE 0x00000010 +#define WIFI_ADHOC_STATE 0x00000020 +#define WIFI_ADHOC_MASTER_STATE 0x00000040 +#define WIFI_UNDER_LINKING 0x00000080 +#define WIFI_UNDER_WPS 0x00000100 +#define WIFI_MESH_STATE 0x00000200 #define WIFI_STA_ALIVE_CHK_STATE 0x00000400 -#define WIFI_SITE_MONITOR 0x00000800 /* under site surveying */ -#define WIFI_WDS 0x00001000 -#define WIFI_WDS_RX_BEACON 0x00002000 /* already rx WDS AP beacon */ -#define WIFI_AUTOCONF 0x00004000 -#define WIFI_AUTOCONF_IND 0x00008000 -#define WIFI_MP_STATE 0x00010000 -#define WIFI_MP_CTX_BACKGROUND 0x00020000 /* in continuous tx background */ -#define WIFI_MP_CTX_ST 0x00040000 /* in continuous tx with single-tone */ -#define WIFI_MP_CTX_BACKGROUND_PENDING 0x00080000 /* pending in continuous tx background due to out of skb */ -#define WIFI_MP_CTX_CCK_HW 0x00100000 /* in continuous tx */ -#define WIFI_MP_CTX_CCK_CS 0x00200000 /* in continuous tx with carrier suppression */ -#define WIFI_MP_LPBK_STATE 0x00400000 +#define WIFI_UNDER_SURVEY 0x00000800 /* under site surveying */ +/*#define WIFI_UNDEFINED_STATE 0x00001000*/ +/*#define WIFI_UNDEFINED_STATE 0x00002000*/ +/*#define WIFI_UNDEFINED_STATE 0x00004000*/ +/*#define WIFI_UNDEFINED_STATE 0x00008000*/ +#define WIFI_MP_STATE 0x00010000 +/*#define WIFI_UNDEFINED_STATE 0x00020000*/ +/*#define WIFI_UNDEFINED_STATE 0x00040000*/ +/*#define WIFI_UNDEFINED_STATE 0x00080000*/ +/*#define WIFI_UNDEFINED_STATE 0x00100000*/ +/*#define WIFI_UNDEFINED_STATE 0x00200000*/ +/*#define WIFI_UNDEFINED_STATE 0x00400000*/ #define WIFI_OP_CH_SWITCHING 0x00800000 -#define WIFI_UNDER_KEY_HANDSHAKE 0x01000000 +#define WIFI_UNDER_KEY_HANDSHAKE 0x01000000 /*#define WIFI_UNDEFINED_STATE 0x02000000*/ /*#define WIFI_UNDEFINED_STATE 0x04000000*/ /*#define WIFI_UNDEFINED_STATE 0x08000000*/ /*#define WIFI_UNDEFINED_STATE 0x10000000*/ /*#define WIFI_UNDEFINED_STATE 0x20000000*/ -/*#define WIFI_UNDEFINED_STATE 0x40000000*/ -#define WIFI_MONITOR_STATE 0x80000000 +#define WIFI_CSA_UPDATE_BEACON 0x40000000 +#define WIFI_MONITOR_STATE 0x80000000 + #define MIRACAST_DISABLED 0 #define MIRACAST_SOURCE BIT0 @@ -101,13 +100,13 @@ void rtw_wfd_st_switch(struct sta_info *sta, bool on); #define MLME_IS_MSRC(adapter) rtw_chk_miracast_mode((adapter), MIRACAST_SOURCE) #define MLME_IS_MSINK(adapter) rtw_chk_miracast_mode((adapter), MIRACAST_SINK) -#define MLME_IS_SCAN(adapter) CHK_MLME_STATE(adapter, WIFI_SITE_MONITOR) +#define MLME_IS_SCAN(adapter) CHK_MLME_STATE(adapter, WIFI_UNDER_SURVEY) #define MLME_IS_LINKING(adapter) CHK_MLME_STATE(adapter, WIFI_UNDER_LINKING) #define MLME_IS_ASOC(adapter) CHK_MLME_STATE(adapter, WIFI_ASOC_STATE) #define MLME_IS_OPCH_SW(adapter) CHK_MLME_STATE(adapter, WIFI_OP_CH_SWITCHING) #define MLME_IS_WPS(adapter) CHK_MLME_STATE(adapter, WIFI_UNDER_WPS) -#if defined(CONFIG_IOCTL_CFG80211) && defined(CONFIG_P2P) +#ifdef CONFIG_IOCTL_CFG80211 #define MLME_IS_ROCH(adapter) (rtw_cfg80211_get_is_roch(adapter) == _TRUE) #else #define MLME_IS_ROCH(adapter) 0 @@ -143,10 +142,10 @@ void rtw_wfd_st_switch(struct sta_info *sta, bool on); enum { MLME_ACTION_UNKNOWN, MLME_ACTION_NONE, - MLME_SCAN_ENABLE, /* WIFI_SITE_MONITOR */ - MLME_SCAN_ENTER, /* WIFI_SITE_MONITOR && !SCAN_DISABLE && !SCAN_BACK_OP */ - MLME_SCAN_DONE, /* WIFI_SITE_MONITOR && (SCAN_DISABLE || SCAN_BACK_OP) */ - MLME_SCAN_DISABLE, /* WIFI_SITE_MONITOR is going to be cleared */ + MLME_SCAN_ENABLE, /* WIFI_UNDER_SURVEY */ + MLME_SCAN_ENTER, /* WIFI_UNDER_SURVEY && !SCAN_DISABLE && !SCAN_BACK_OP */ + MLME_SCAN_DONE, /* WIFI_UNDER_SURVEY && (SCAN_DISABLE || SCAN_BACK_OP) */ + MLME_SCAN_DISABLE, /* WIFI_UNDER_SURVEY is going to be cleared */ MLME_STA_CONNECTING, MLME_STA_CONNECTED, MLME_STA_DISCONNECTED, @@ -160,12 +159,14 @@ enum { MLME_MESH_STOPPED, MLME_OPCH_SWITCH, }; - -#define _FW_UNDER_LINKING WIFI_UNDER_LINKING -#define _FW_LINKED WIFI_ASOC_STATE -#define _FW_UNDER_SURVEY WIFI_SITE_MONITOR - - +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +enum MODE_WOW_KEEP_ALIVE_PATTERN { + wow_keep_alive_pattern_disable = 0, + wow_keep_alive_pattern_tx, + wow_keep_alive_pattern_trx, + wow_keep_alive_pattern_trx_with_ack +}; +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ enum dot11AuthAlgrthmNum { dot11AuthAlgrthm_Open = 0, dot11AuthAlgrthm_Shared, @@ -175,6 +176,39 @@ enum dot11AuthAlgrthmNum { dot11AuthAlgrthm_MaxNum }; +/** + * enum mlme_auth_type - AuthenticationType + * + * @MLME_AUTHTYPE_OPEN_SYSTEM: Open System authentication + * @MLME_AUTHTYPE_SHARED_KEY: Shared Key authentication (WEP only) + * @MLME_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r) + * @MLME_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP) + * @MLME_AUTHTYPE_SAE: Simultaneous authentication of equals + * @MLME_AUTHTYPE_FILS_SK: Fast Initial Link Setup shared key + * @MLME_AUTHTYPE_FILS_SK_PFS: Fast Initial Link Setup shared key with PFS + * @MLME_AUTHTYPE_FILS_PK: Fast Initial Link Setup public key + * @__MLME_AUTHTYPE_NUM: internal + * @MLME_AUTHTYPE_MAX: maximum valid auth algorithm + * @MLME_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by trying + * multiple times); this is invalid in netlink -- leave out the attribute + * for this on CONNECT commands. + */ +enum mlme_auth_type { + MLME_AUTHTYPE_OPEN_SYSTEM, + MLME_AUTHTYPE_SHARED_KEY, + MLME_AUTHTYPE_FT, + MLME_AUTHTYPE_NETWORK_EAP, + MLME_AUTHTYPE_SAE, + MLME_AUTHTYPE_FILS_SK, + MLME_AUTHTYPE_FILS_SK_PFS, + MLME_AUTHTYPE_FILS_PK, + + /* keep last */ + __MLME_AUTHTYPE_NUM, + MLME_AUTHTYPE_MAX = __MLME_AUTHTYPE_NUM - 1, + MLME_AUTHTYPE_AUTOMATIC +}; + /* Scan type including active and passive scan. */ typedef enum _RT_SCAN_TYPE { SCAN_PASSIVE, @@ -320,20 +354,6 @@ struct scan_limit_info { #endif /* CONFIG_P2P_OP_CHK_SOCIAL_CH */ }; -#ifdef CONFIG_IOCTL_CFG80211 -struct cfg80211_wifidirect_info { - _timer remain_on_ch_timer; - u8 restore_channel; - struct ieee80211_channel remain_on_ch_channel; - enum nl80211_channel_type remain_on_ch_type; - ATOMIC_T ro_ch_cookie_gen; - u64 remain_on_ch_cookie; - bool is_ro_ch; - struct wireless_dev *ro_ch_wdev; - systime last_ro_ch_time; /* this will be updated at the beginning and end of ro_ch */ -}; -#endif /* CONFIG_IOCTL_CFG80211 */ - #ifdef CONFIG_P2P_WOWLAN enum P2P_WOWLAN_RECV_FRAME_TYPE { @@ -363,10 +383,7 @@ struct wifidirect_info { _timer pre_tx_scan_timer; _timer reset_ch_sitesurvey; _timer reset_ch_sitesurvey2; /* Just for resetting the scan limit function by using p2p nego */ -#ifdef CONFIG_CONCURRENT_MODE - /* Used to switch the channel between legacy AP and listen state. */ - _timer ap_p2p_switch_timer; -#endif + struct tx_provdisc_req_info tx_prov_disc_info; struct rx_provdisc_req_info rx_prov_disc_info; struct tx_invite_req_info invitereq_info; @@ -475,6 +492,7 @@ struct tdls_ch_switch { u8 addr[ETH_ALEN]; u8 off_ch_num; u8 ch_offset; + u8 bcn_early_reg_bkp; u32 cur_time; u8 delay_switch_back; u8 dump_stack; @@ -526,212 +544,27 @@ enum { RTW_ROAM_ACTIVE = BIT2, }; -#ifdef CONFIG_RTW_80211R -#define RTW_FT_ACTION_REQ_LMT 4 -#define RTW_FT_MAX_IE_SZ 256 +#define UNASOC_STA_SRC_RX_BMC 0 +#define UNASOC_STA_SRC_RX_NMY_UC 1 +#define UNASOC_STA_SRC_NUM 2 -enum _rtw_ft_sta_status { - RTW_FT_UNASSOCIATED_STA = 0, - RTW_FT_AUTHENTICATING_STA, - RTW_FT_AUTHENTICATED_STA, - RTW_FT_ASSOCIATING_STA, - RTW_FT_ASSOCIATED_STA, - RTW_FT_REQUESTING_STA, - RTW_FT_REQUESTED_STA, - RTW_FT_CONFIRMED_STA, - RTW_FT_UNSPECIFIED_STA +#define UNASOC_STA_MODE_DISABLED 0 +#define UNASOC_STA_MODE_INTERESTED 1 +#define UNASOC_STA_MODE_ALL 2 +#define UNASOC_STA_MODE_NUM 3 + +#define UNASOC_STA_DEL_CHK_SKIP 0 +#define UNASOC_STA_DEL_CHK_ALIVE 1 +#define UNASOC_STA_DEL_CHK_DELETED 2 + +#ifdef CONFIG_RTW_MULTI_AP +struct unassoc_sta_info { + _list list; + u8 addr[ETH_ALEN]; + u8 interested; + s8 recv_signal_power; + systime time; }; - -#define rtw_ft_chk_status(a, s) \ - ((a)->mlmepriv.ft_roam.ft_status == (s)) - -#define rtw_ft_roam_status(a, s) \ - ((rtw_to_roam(a) > 0) && rtw_ft_chk_status(a, s)) - -#define rtw_ft_authed_sta(a) \ - ((rtw_ft_chk_status(a, RTW_FT_AUTHENTICATED_STA)) || \ - (rtw_ft_chk_status(a, RTW_FT_ASSOCIATING_STA)) || \ - (rtw_ft_chk_status(a, RTW_FT_ASSOCIATED_STA))) - -#define rtw_ft_set_status(a, s) \ - do { \ - ((a)->mlmepriv.ft_roam.ft_status = (s)); \ - } while (0) - -#define rtw_ft_lock_set_status(a, s, irq) \ - do { \ - _enter_critical_bh(&(a)->mlmepriv.lock, ((_irqL *)(irq))); \ - ((a)->mlmepriv.ft_roam.ft_status = (s)); \ - _exit_critical_bh(&(a)->mlmepriv.lock, ((_irqL *)(irq))); \ - } while (0) - -#define rtw_ft_reset_status(a) \ - do { \ - ((a)->mlmepriv.ft_roam.ft_status = RTW_FT_UNASSOCIATED_STA); \ - } while (0) - -enum rtw_ft_capability { - RTW_FT_EN = BIT0, - RTW_FT_OTD_EN = BIT1, - RTW_FT_PEER_EN = BIT2, - RTW_FT_PEER_OTD_EN = BIT3, - RTW_FT_BTM_ROAM = BIT4, -}; - -#define rtw_ft_chk_flags(a, f) \ - ((a)->mlmepriv.ft_roam.ft_flags & (f)) - -#define rtw_ft_set_flags(a, f) \ - do { \ - ((a)->mlmepriv.ft_roam.ft_flags |= (f)); \ - } while (0) - -#define rtw_ft_clr_flags(a, f) \ - do { \ - ((a)->mlmepriv.ft_roam.ft_flags &= ~(f)); \ - } while (0) - -#define rtw_ft_roam(a) \ - ((rtw_to_roam(a) > 0) && rtw_ft_chk_flags(a, RTW_FT_PEER_EN)) - -#define rtw_ft_valid_akm(a, t) \ - ((rtw_ft_chk_flags(a, RTW_FT_EN)) && \ - (((t) == 3) || ((t) == 4))) - -#define rtw_ft_roam_expired(a, r) \ - ((rtw_chk_roam_flags(a, RTW_ROAM_ON_EXPIRED)) \ - && (r == WLAN_REASON_ACTIVE_ROAM)) - -#define rtw_ft_otd_roam_en(a) \ - ((rtw_ft_chk_flags(a, RTW_FT_OTD_EN)) \ - && ((a)->mlmepriv.ft_roam.ft_roam_on_expired == _FALSE) \ - && ((a)->mlmepriv.ft_roam.ft_cap & 0x01)) - -#define rtw_ft_otd_roam(a) \ - rtw_ft_chk_flags(a, RTW_FT_PEER_OTD_EN) - -#define rtw_ft_valid_otd_candidate(a, p) \ - ((rtw_ft_chk_flags(a, RTW_FT_OTD_EN)) \ - && ((rtw_ft_chk_flags(a, RTW_FT_PEER_OTD_EN) \ - && ((*((p)+4) & 0x01) == 0)) \ - || ((rtw_ft_chk_flags(a, RTW_FT_PEER_OTD_EN) == 0) \ - && (*((p)+4) & 0x01)))) - -struct ft_roam_info { - u16 mdid; - u8 ft_cap; - /*b0: FT over DS, b1: Resource Req Protocol Cap, b2~b7: Reserved*/ - u8 updated_ft_ies[RTW_FT_MAX_IE_SZ]; - u16 updated_ft_ies_len; - u8 ft_action[RTW_FT_MAX_IE_SZ]; - u16 ft_action_len; - struct cfg80211_ft_event_params ft_event; - u8 ft_roam_on_expired; - u8 ft_flags; - u32 ft_status; - u32 ft_req_retry_cnt; - bool ft_updated_bcn; -}; -#endif - -#ifdef CONFIG_LAYER2_ROAMING -#if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) -#define RTW_RRM_NB_RPT_EN BIT(1) -#define RTW_MAX_NB_RPT_NUM 8 - -#define rtw_roam_busy_scan(a, nb) \ - (((a)->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE) && \ - (((a)->mlmepriv.ch_cnt) < ((nb)->nb_rpt_ch_list_num))) - -#define rtw_wnm_btm_preference_cap(a) \ - ((a)->mlmepriv.nb_info.preference_en == _TRUE) - -#define rtw_wnm_btm_diff_bss(a) \ - ((rtw_wnm_btm_preference_cap(a)) && \ - (is_zero_mac_addr((a)->mlmepriv.nb_info.roam_target_addr) == _FALSE) && \ - (_rtw_memcmp((a)->mlmepriv.nb_info.roam_target_addr,\ - (a)->mlmepriv.cur_network.network.MacAddress, ETH_ALEN) == _FALSE)) - -#define rtw_wnm_btm_roam_candidate(a, c) \ - ((rtw_wnm_btm_preference_cap(a)) && \ - (is_zero_mac_addr((a)->mlmepriv.nb_info.roam_target_addr) == _FALSE) && \ - (_rtw_memcmp((a)->mlmepriv.nb_info.roam_target_addr,\ - (c)->network.MacAddress, ETH_ALEN))) - -#define rtw_wnm_set_ext_cap_btm(_pEleStart, _val) \ - SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart))+2, 3, 1, _val) - -#define wnm_btm_bss_term_inc(p) (*((u8 *)((p)+3)) & BSS_TERMINATION_INCLUDED) - -#define wnm_btm_ess_disassoc_im(p) (*((u8 *)((p)+3)) & ESS_DISASSOC_IMMINENT) - -#define wnm_btm_req_mode(p) (*((u8 *)((p)+3))) - -#define wnm_btm_disassoc_timer(p) (*((u16 *)((p)+4))) - -#define wnm_btm_valid_interval(p) (*((u8 *)((p)+6))) - -#define wnm_btm_term_duration_offset(p) ((p)+7) - -/*IEEE Std 80211k Figure 7-95b Neighbor Report element format*/ -struct nb_rpt_hdr { - u8 id; /*0x34: Neighbor Report Element ID*/ - u8 len; - u8 bssid[ETH_ALEN]; - u32 bss_info; - u8 reg_class; - u8 ch_num; - u8 phy_type; -}; - -/*IEEE Std 80211v, Figure 7-95e2¡XBSS Termination Duration subelement field format */ -struct btm_term_duration { - u8 id; - u8 len; - u64 tsf; - u16 duration; -}; - -/*IEEE Std 80211v, Figure 7-101n8¡XBSS Transition Management Request frame body format */ -struct btm_req_hdr { - u8 req_mode; - u16 disassoc_timer; - u8 validity_interval; - struct btm_term_duration term_duration; -}; - -/*IEEE Std 80211v, Table 7-43b Optional Subelement IDs for Neighbor Report*/ -/* BSS Transition Candidate Preference */ -#define WNM_BTM_CAND_PREF_SUBEID 0x03 - -/* BSS Termination Duration */ -#define WNM_BTM_TERM_DUR_SUBEID 0x04 - -struct wnm_btm_cant { - struct nb_rpt_hdr nb_rpt; - u8 preference; /* BSS Transition Candidate Preference */ -}; - -enum rtw_btm_req_mod { - PREFERRED_CANDIDATE_LIST_INCLUDED = BIT0, - ABRIDGED = BIT1, - DISASSOC_IMMINENT = BIT2, - BSS_TERMINATION_INCLUDED = BIT3, - ESS_DISASSOC_IMMINENT = BIT4, -}; - -struct roam_nb_info { - struct nb_rpt_hdr nb_rpt[RTW_MAX_NB_RPT_NUM]; - struct rtw_ieee80211_channel nb_rpt_ch_list[RTW_MAX_NB_RPT_NUM]; - bool nb_rpt_valid; - u8 nb_rpt_ch_list_num; - u8 preference_en; - u8 roam_target_addr[ETH_ALEN]; - u32 last_nb_rpt_entries; - bool nb_rpt_is_same; - _timer roam_scan_timer; -}; -#endif /* defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) */ #endif struct mlme_priv { @@ -753,6 +586,9 @@ struct mlme_priv { bool need_to_roam; #endif + u32 defs_lmt_sta; + u32 defs_lmt_time; + u8 *nic_hdl; u32 max_bss_cnt; /* The size of scan queue */ _list *pscanned; @@ -888,12 +724,14 @@ struct mlme_priv { u8 *auth_rsp; u32 auth_rsp_len; #endif +#endif /* CONFIG_AP_MODE and CONFIG_NATIVEAP_MLME */ + u8 *assoc_req; u32 assoc_req_len; - u8 *assoc_rsp; u32 assoc_rsp_len; +#if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) /* u8 *wps_probe_req_ie; */ /* u32 wps_probe_req_ie_len; */ @@ -957,12 +795,21 @@ struct mlme_priv { u32 wfd_assoc_resp_ie_len; #endif +#ifdef CONFIG_RTW_MBO + u8 *pcell_data_cap_ie; + u32 cell_data_cap_len; +#endif + #ifdef RTK_DMP_PLATFORM /* DMP kobject_hotplug function signal need in passive level */ _workitem Linkup_workitem; _workitem Linkdown_workitem; #endif + +#ifdef RTW_BUSY_DENY_SCAN systime lastscantime; +#endif + #ifdef CONFIG_CONCURRENT_MODE u8 scanning_via_buddy_intf; #endif @@ -972,6 +819,19 @@ struct mlme_priv { u8 vendor_ie[WLAN_MAX_VENDOR_IE_NUM][WLAN_MAX_VENDOR_IE_LEN]; u32 vendor_ielen[WLAN_MAX_VENDOR_IE_NUM]; #endif +#ifdef CONFIG_RTW_MULTI_AP + u8 unassoc_sta_mode_of_stype[UNASOC_STA_SRC_NUM]; + _queue unassoc_sta_queue; + _queue free_unassoc_sta_queue; + u8 *free_unassoc_sta_buf; + u32 interested_unassoc_sta_cnt; + u32 max_unassoc_sta_cnt; +#ifdef CONFIG_PLATFORM_CMAP_INTFS + struct unassoc_sta_info cmap_unassoc_sta[CMAP_UNASSOC_METRICS_STA_MAX]; + u8 cmap_unassoc_sta_cnt; + _timer cmap_unassoc_sta_timer; +#endif +#endif }; #define mlme_set_scan_to_timer(mlme, ms) \ @@ -1010,7 +870,7 @@ extern void hostapd_mode_unload(_adapter *padapter); #endif -extern int rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf, u16 status); +extern void rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf, u16 status); extern void rtw_survey_event_callback(_adapter *adapter, u8 *pbuf); extern void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf); extern void rtw_joinbss_event_callback(_adapter *adapter, u8 *pbuf); @@ -1018,23 +878,10 @@ extern void rtw_stassoc_event_callback(_adapter *adapter, u8 *pbuf); extern void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf); void rtw_sta_mstatus_disc_rpt(_adapter *adapter, u8 mac_id); void rtw_sta_mstatus_report(_adapter *adapter); -extern void rtw_atimdone_event_callback(_adapter *adapter, u8 *pbuf); -extern void rtw_cpwm_event_callback(_adapter *adapter, u8 *pbuf); extern void rtw_wmm_event_callback(PADAPTER padapter, u8 *pbuf); #ifdef CONFIG_IEEE80211W void rtw_sta_timeout_event_callback(_adapter *adapter, u8 *pbuf); #endif /* CONFIG_IEEE80211W */ -#ifdef CONFIG_RTW_80211R -void rtw_ft_info_init(struct ft_roam_info *pft); -u8 rtw_ft_chk_roaming_candidate(_adapter *padapter, - struct wlan_network *competitor); -void rtw_ft_update_stainfo(_adapter *padapter, WLAN_BSSID_EX *pnetwork); -void rtw_ft_reassoc_event_callback(_adapter *padapter, u8 *pbuf); -#endif -#if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) -void rtw_roam_nb_info_init(_adapter *padapter); -#endif - thread_return event_thread(thread_context context); extern void rtw_free_network_queue(_adapter *adapter, u8 isfreeall); @@ -1150,7 +997,7 @@ struct wlan_network *rtw_find_same_network(_queue *scanned_queue, struct wlan_ne extern void rtw_free_assoc_resources(_adapter *adapter, u8 lock_scanned_queue); extern void rtw_indicate_disconnect(_adapter *adapter, u16 reason, u8 locally_generated); -extern int rtw_indicate_connect(_adapter *adapter); +extern void rtw_indicate_connect(_adapter *adapter); void rtw_indicate_scan_done(_adapter *padapter, bool aborted); void rtw_drv_scan_by_self(_adapter *padapter, u8 reason); @@ -1256,7 +1103,7 @@ void rtw_ht_use_default_setting(_adapter *padapter); void rtw_build_wmm_ie_ht(_adapter *padapter, u8 *out_ie, uint *pout_len); unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len, u8 channel); void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel); -void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe); +void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe, u8 issue_when_busy); void rtw_append_exented_cap(_adapter *padapter, u8 *out_ie, uint *pout_len); #endif @@ -1308,6 +1155,19 @@ struct sta_media_status_rpt_cmd_parm { bool connected; }; +#ifdef CONFIG_RTW_MULTI_AP +void rtw_unassoc_sta_set_mode(_adapter *adapter, u8 stype, u8 mode); +bool rtw_unassoc_sta_src_chk(_adapter *adapter, u8 stype); +void dump_unassoc_sta(void *sel, _adapter *adapter); +void rtw_del_unassoc_sta_queue(_adapter *adapter); +void rtw_del_unassoc_sta(_adapter *adapter, u8 *addr); +void rtw_rx_add_unassoc_sta(_adapter *adapter, u8 stype, u8 *addr, s8 recv_signal_power); +void rtw_add_interested_unassoc_sta(_adapter *adapter, u8 *addr); +void rtw_undo_interested_unassoc_sta(_adapter *adapter, u8 *addr); +void rtw_undo_all_interested_unassoc_sta(_adapter *adapter); +u8 rtw_search_unassoc_sta(_adapter *adapter, u8 *addr, struct unassoc_sta_info *ret_sta); +#endif + void rtw_sta_media_status_rpt(_adapter *adapter, struct sta_info *sta, bool connected); u8 rtw_sta_media_status_rpt_cmd(_adapter *adapter, struct sta_info *sta, bool connected); void rtw_sta_media_status_rpt_cmd_hdl(_adapter *adapter, struct sta_media_status_rpt_cmd_parm *parm); diff --git a/include/rtw_mlme_ext.h b/include/rtw_mlme_ext.h index ca6690c..b3bad52 100644 --- a/include/rtw_mlme_ext.h +++ b/include/rtw_mlme_ext.h @@ -28,38 +28,39 @@ /* #define DISCONNECT_TO (3000) */ #define ADDBA_TO (2000) -#ifndef SURVEY_TO_ACTIVE -#define SURVEY_TO_ACTIVE SURVEY_TO -#endif - #define LINKED_TO (1) /* unit:2 sec, 1x2 = 2 sec */ #define REAUTH_LIMIT (4) #define REASSOC_LIMIT (4) #define READDBA_LIMIT (2) -#define DEAUTH_DENY_TO 500 /* unit: ms */ - #ifdef CONFIG_GSPI_HCI #define ROAMING_LIMIT 5 #else #define ROAMING_LIMIT 8 #endif -/* #define IOCMD_REG0 0x10250370 */ -/* #define IOCMD_REG1 0x10250374 */ -/* #define IOCMD_REG2 0x10250378 */ -/* #define FW_DYNAMIC_FUN_SWITCH 0x10250364 */ - -/* #define WRITE_BB_CMD 0xF0000001 */ -/* #define SET_CHANNEL_CMD 0xF3000000 */ -/* #define UPDATE_RA_CMD 0xFD0000A2 */ - -#define _HW_STATE_NOLINK_ 0x00 -#define _HW_STATE_ADHOC_ 0x01 +/*net_type, pmlmeinfo->state*/ +#define _HW_STATE_NOLINK_ 0x00 +#define _HW_STATE_ADHOC_ 0x01 #define _HW_STATE_STATION_ 0x02 -#define _HW_STATE_AP_ 0x03 -#define _HW_STATE_MONITOR_ 0x04 +#define _HW_STATE_AP_ 0x03 +#define _HW_STATE_MONITOR_ 0x04 + +#define WIFI_FW_NULL_STATE _HW_STATE_NOLINK_ +#define WIFI_FW_STATION_STATE _HW_STATE_STATION_ +#define WIFI_FW_AP_STATE _HW_STATE_AP_ +#define WIFI_FW_ADHOC_STATE _HW_STATE_ADHOC_ + +#define WIFI_FW_PRE_LINK 0x00000800 +#define WIFI_FW_AUTH_NULL 0x00000100 +#define WIFI_FW_AUTH_STATE 0x00000200 +#define WIFI_FW_AUTH_SUCCESS 0x00000400 + +#define WIFI_FW_ASSOC_STATE 0x00002000 +#define WIFI_FW_ASSOC_SUCCESS 0x00004000 + +#define WIFI_FW_LINKING_STATE (WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE | WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE) #define _1M_RATE_ 0 @@ -90,6 +91,7 @@ extern unsigned char WMM_OUI[]; extern unsigned char WPS_OUI[]; extern unsigned char WFD_OUI[]; extern unsigned char P2P_OUI[]; +extern unsigned char MULTI_AP_OUI[]; extern unsigned char WMM_INFO_OUI[]; extern unsigned char WMM_PARA_OUI[]; @@ -99,18 +101,6 @@ typedef struct _RT_CHANNEL_PLAN { unsigned char Len; } RT_CHANNEL_PLAN, *PRT_CHANNEL_PLAN; -enum Associated_AP { - atherosAP = 0, - broadcomAP = 1, - ciscoAP = 2, - marvellAP = 3, - ralinkAP = 4, - realtekAP = 5, - airgocapAP = 6, - unknownAP = 7, - maxAP, -}; - typedef enum _HT_IOT_PEER { HT_IOT_PEER_UNKNOWN = 0, HT_IOT_PEER_REALTEK = 1, @@ -201,6 +191,7 @@ struct ss_res { u8 state; u8 next_state; /* will set to state on next cmd hdl */ int bss_cnt; + u8 activate_ch_cnt; int channel_idx; u8 force_ssid_scan; int scan_mode; @@ -240,26 +231,6 @@ struct ss_res { bool acs; /* aim to trigger channel selection when scan done */ }; -/* #define AP_MODE 0x0C */ -/* #define STATION_MODE 0x08 */ -/* #define AD_HOC_MODE 0x04 */ -/* #define NO_LINK_MODE 0x00 */ - -#define WIFI_FW_NULL_STATE _HW_STATE_NOLINK_ -#define WIFI_FW_STATION_STATE _HW_STATE_STATION_ -#define WIFI_FW_AP_STATE _HW_STATE_AP_ -#define WIFI_FW_ADHOC_STATE _HW_STATE_ADHOC_ - -#define WIFI_FW_PRE_LINK 0x00000800 -#define WIFI_FW_AUTH_NULL 0x00000100 -#define WIFI_FW_AUTH_STATE 0x00000200 -#define WIFI_FW_AUTH_SUCCESS 0x00000400 - -#define WIFI_FW_ASSOC_STATE 0x00002000 -#define WIFI_FW_ASSOC_SUCCESS 0x00004000 - -#define WIFI_FW_LINKING_STATE (WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE | WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE) - #ifdef CONFIG_TDLS enum TDLS_option { TDLS_ESTABLISHED = 1, @@ -282,10 +253,6 @@ enum TDLS_option { #endif /* CONFIG_TDLS */ -#if (KERNEL_VERSION(3, 8, 0) > LINUX_VERSION_CODE) -#define NL80211_AUTHTYPE_SAE (__NL80211_AUTHTYPE_NUM + 1) -#endif - /* * Usage: * When one iface acted as AP mode and the other iface is STA mode and scanning, @@ -307,6 +274,9 @@ enum TDLS_option { #if defined(CONFIG_ATMEL_RC_PATCH) #define RTW_SCAN_NUM_OF_CH 2 #define RTW_BACK_OP_CH_MS 200 +#elseif defined(CONFIG_CUSTOMER_EZVIZ_CHIME2) + #define RTW_SCAN_NUM_OF_CH 1 + #define RTW_BACK_OP_CH_MS 200 #else #define RTW_SCAN_NUM_OF_CH 3 #define RTW_BACK_OP_CH_MS 400 @@ -370,13 +340,34 @@ struct mlme_ext_info { NDIS_802_11_RATES_EX SupportedRates_infra_ap; u8 ht_vht_received;/*ht_vht_received used to show debug msg BIT(0):HT BIT(1):VHT */ #endif /* ROKU_PRIVATE */ + +#ifdef CONFIG_WRITE_BCN_LEN_TO_FW + u16 last_bcn_len; +#endif +}; + +enum { + RTW_CHF_NO_IR = BIT0, + RTW_CHF_DFS = BIT1, + RTW_CHF_LONG_CAC = BIT2, + RTW_CHF_NON_OCP = BIT3, + RTW_CHF_NO_HT40U = BIT4, + RTW_CHF_NO_HT40L = BIT5, + RTW_CHF_NO_80MHZ = BIT6, + RTW_CHF_NO_160MHZ = BIT7, }; /* The channel information about this channel including joining, scanning, and power constraints. */ typedef struct _RT_CHANNEL_INFO { u8 ChannelNum; /* The channel number. */ - RT_SCAN_TYPE ScanType; /* Scan type such as passive or active scan. */ - bool dfs; + + /* + * Bitmap and its usage: + * RTW_CHF_NO_IR, RTW_CHF_DFS: is used to check for status + * RTW_CHF_NO_HT40U, RTW_CHF_NO_HT40L, RTW_CHF_NO_80MHZ, RTW_CHF_NO_160MHZ: extra bandwidth limitation (ex: from regulatory) + * RTW_CHF_NON_OCP: is only used to record if event is reported, status check is still done using non_ocp_end_time + */ + u8 flags; /* u16 ScanPeriod; */ /* Listen time in millisecond in this channel. */ /* s32 MaxTxPwrDbm; */ /* Max allowed tx power. */ /* u32 ExInfo; */ /* Extended Information for this channel. */ @@ -389,6 +380,10 @@ typedef struct _RT_CHANNEL_INFO { #endif #endif u8 hidden_bss_cnt; /* per scan count */ + +#ifdef CONFIG_IOCTL_CFG80211 + void *os_chan; +#endif } RT_CHANNEL_INFO, *PRT_CHANNEL_INFO; #define CAC_TIME_MS (60*1000) @@ -398,8 +393,10 @@ typedef struct _RT_CHANNEL_INFO { #if CONFIG_TXPWR_LIMIT void rtw_txpwr_init_regd(struct rf_ctl_t *rfctl); #endif -void rtw_rfctl_init(_adapter *adapter); +int rtw_rfctl_init(_adapter *adapter); void rtw_rfctl_deinit(_adapter *adapter); +void rtw_rfctl_chplan_init(_adapter *adapter); +void rtw_rfctl_update_op_mode(struct rf_ctl_t *rfctl, u8 ifbmp_mod, u8 if_op); u8 rtw_rfctl_get_dfs_domain(struct rf_ctl_t *rfctl); u8 rtw_rfctl_dfs_domain_unknown(struct rf_ctl_t *rfctl); @@ -413,8 +410,9 @@ bool rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl); bool rtw_rfctl_is_tx_blocked_by_ch_waiting(struct rf_ctl_t *rfctl); bool rtw_chset_is_chbw_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset); bool rtw_chset_is_ch_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch); -void rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset); -void rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms); +bool rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset); +bool rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms); +void rtw_chset_chk_non_ocp_finish(struct rf_ctl_t *rfctl); u32 rtw_get_ch_waiting_ms(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, u32 *r_non_ocp_ms, u32 *r_cac_ms); void rtw_reset_cac(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset); u32 rtw_force_stop_cac(struct rf_ctl_t *rfctl, u32 timeout_ms); @@ -425,22 +423,29 @@ u32 rtw_force_stop_cac(struct rf_ctl_t *rfctl, u32 timeout_ms); #define rtw_rfctl_is_tx_blocked_by_ch_waiting(rfctl) _FALSE #endif -enum { - RTW_CHF_2G = BIT0, - RTW_CHF_5G = BIT1, - RTW_CHF_DFS = BIT2, - RTW_CHF_LONG_CAC = BIT3, - RTW_CHF_NON_DFS = BIT4, - RTW_CHF_NON_LONG_CAC = BIT5, - RTW_CHF_NON_OCP = BIT6, -}; - bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw , u8 *dec_ch, u8 *dec_bw, u8 *dec_offset - , u8 d_flags, u8 cur_ch, bool by_int_info, u8 mesh_only); + , u8 e_flags, u8 d_flags, u8 cur_ch, bool by_int_info, u8 mesh_only); -void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set); +struct get_chplan_resp { + enum regd_src_t regd_src; + bool has_country; + struct country_chplan country_ent; + u8 channel_plan; +#if CONFIG_TXPWR_LIMIT + const char *regd_name; +#endif +#ifdef CONFIG_DFS_MASTER + u8 dfs_domain; +#endif + u8 chset_num; + RT_CHANNEL_INFO chset[0]; +}; + +#ifdef CONFIG_PROC_DEBUG +void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set, u8 chset_num); void dump_cur_chset(void *sel, struct rf_ctl_t *rfctl); +#endif int rtw_chset_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch); u8 rtw_chset_is_chbw_valid(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset @@ -516,6 +521,11 @@ struct mlme_ext_priv { #endif struct ss_res sitesurvey_res; +#ifdef CONFIG_RTW_ROAM_QUICKSCAN + u8 quickscan_next; + u8 roam_ch_num; + struct rtw_ieee80211_channel roam_ch[RTW_CHANNEL_SCAN_AMOUNT]; +#endif struct mlme_ext_info mlmext_info;/* for sta/adhoc mode, including current scanning/connecting/connected related info. * for ap mode, network includes ap's cap_info */ _timer survey_timer; @@ -528,6 +538,10 @@ struct mlme_ext_priv { _timer ft_link_timer; _timer ft_roam_timer; #endif +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + _timer tbtx_xmit_timer; + _timer tbtx_token_dispatch_timer; +#endif systime last_scan_time; u8 scan_abort; @@ -536,10 +550,6 @@ struct mlme_ext_priv { u32 retry; /* retry for issue probereq */ - /* Don't handle deauth in DEAUTH_DENY_TO ms after sending deauth */ - /* value 0 means always handle deauth packet */ - systime last_deauth_time; - u64 TSFValue; u32 bcn_cnt; u32 last_bcn_cnt; @@ -590,6 +600,9 @@ struct mlme_ext_priv { bool txss_1ss; u8 txss_momi_type_bk; #endif +#ifdef CONFIG_DFS + _timer csa_timer; +#endif /* CONFIG_DFS */ }; struct support_rate_handler { @@ -698,6 +711,7 @@ void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch); void Set_MSR(_adapter *padapter, u8 type); + void rtw_set_external_auth_status(_adapter *padapter, const void *data, int len); u8 rtw_get_oper_ch(_adapter *adapter); @@ -706,14 +720,13 @@ u8 rtw_get_oper_bw(_adapter *adapter); void rtw_set_oper_bw(_adapter *adapter, u8 bw); u8 rtw_get_oper_choffset(_adapter *adapter); void rtw_set_oper_choffset(_adapter *adapter, u8 offset); -u8 rtw_get_center_ch(u8 channel, u8 chnl_bw, u8 chnl_offset); systime rtw_get_on_oper_ch_time(_adapter *adapter); systime rtw_get_on_cur_ch_time(_adapter *adapter); -u8 rtw_get_offset_by_chbw(u8 ch, u8 bw, u8 *r_offset); - void set_channel_bwmode(_adapter *padapter, unsigned char channel, unsigned char channel_offset, unsigned short bwmode); +void csa_timer_hdl(void *FunctionContext); + unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval); void _clear_cam_entry(_adapter *padapter, u8 entry); @@ -762,6 +775,9 @@ void rtw_process_wfd_ie(_adapter *adapter, u8 *ie, u8 ie_len, const char *tag); void rtw_process_wfd_ies(_adapter *adapter, u8 *ies, u8 ies_len, const char *tag); #endif void WMMOnAssocRsp(_adapter *padapter); +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT +u8 rtw_is_tbtx_capabilty(u8 *p, u8 len); +#endif void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); #ifdef ROKU_PRIVATE @@ -779,7 +795,10 @@ void ERP_IE_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); void VCS_update(_adapter *padapter, struct sta_info *psta); void update_ldpc_stbc_cap(struct sta_info *psta); +#ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT bool rtw_validate_value(u16 EID, u8 *p, u16 len); +#endif /* CONFIG_CHECK_SPECIFIC_IE_CONTENT */ + bool is_hidden_ssid(char *ssid, int len); bool hidden_ssid_ap(WLAN_BSSID_EX *snetwork); void rtw_absorb_ssid_ifneed(_adapter *padapter, WLAN_BSSID_EX *bssid, u8 *pframe); @@ -790,6 +809,7 @@ int rtw_update_bcn_keys_of_network(struct wlan_network *network); int validate_beacon_len(u8 *pframe, uint len); void rtw_dump_bcn_keys(void *sel, struct beacon_keys *recv_beacon); +void rtw_bcn_key_err_fix(struct beacon_keys *cur, struct beacon_keys *recv); bool rtw_bcn_key_compare(struct beacon_keys *cur, struct beacon_keys *recv); int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len); void update_beacon_info(_adapter *padapter, u8 *pframe, uint len, struct sta_info *psta); @@ -820,7 +840,7 @@ unsigned int is_ap_in_tkip(_adapter *padapter); unsigned int is_ap_in_wep(_adapter *padapter); unsigned int should_forbid_n_rate(_adapter *padapter); -void parsing_eapol_packet(_adapter *padapter, u8 *key_payload, struct sta_info *psta, u8 trx_type); +enum eap_type parsing_eapol_packet(_adapter *padapter, u8 *key_payload, struct sta_info *psta, u8 trx_type); bool _rtw_camctl_chk_cap(_adapter *adapter, u8 cap); void _rtw_camctl_set_flags(_adapter *adapter, u32 flags); @@ -831,12 +851,13 @@ bool _rtw_camctl_chk_flags(_adapter *adapter, u32 flags); struct sec_cam_bmp; void dump_sec_cam_map(void *sel, struct sec_cam_bmp *map, u8 max_num); +void rtw_sec_cam_map_set(struct sec_cam_bmp *map, u8 id); void rtw_sec_cam_map_clr_all(struct sec_cam_bmp *map); bool _rtw_camid_is_gk(_adapter *adapter, u8 cam_id); bool rtw_camid_is_gk(_adapter *adapter, u8 cam_id); s16 rtw_camid_search(_adapter *adapter, u8 *addr, s16 kid, s8 gk); -s16 rtw_camid_alloc(_adapter *adapter, struct sta_info *sta, u8 kid, u8 gk, bool *used); +s16 rtw_camid_alloc(_adapter *adapter, struct sta_info *sta, u8 kid, u8 gk, bool ext_sec, bool *used); void rtw_camid_free(_adapter *adapter, u8 cam_id); u8 rtw_get_sec_camid(_adapter *adapter, u8 max_bk_key_num, u8 *sec_key_id); @@ -902,6 +923,9 @@ extern u8 set_tx_beacon_cmd(_adapter *padapter, u8 flags); unsigned int setup_beacon_frame(_adapter *padapter, unsigned char *beacon_frame); void update_mgnt_tx_rate(_adapter *padapter, u8 rate); void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib); +#ifdef CONFIG_RTW_MGMT_QUEUE +void update_mgntframe_subtype(_adapter *padapter, struct xmit_frame *pmgntframe); +#endif void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib); void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe); void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe); @@ -951,8 +975,9 @@ unsigned int send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info unsigned int send_delba_sta_tid_wait_ack(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid, u8 force); unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr); +#ifdef CONFIG_AP_MODE unsigned int send_beacon(_adapter *padapter); - +#endif void start_clnt_assoc(_adapter *padapter); void start_clnt_auth(_adapter *padapter); void start_clnt_join(_adapter *padapter); @@ -1006,35 +1031,15 @@ unsigned int on_action_rm(_adapter *padapter, union recv_frame *precv_frame); unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame); unsigned int OnAction_vht(_adapter *padapter, union recv_frame *precv_frame); unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame); +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT +unsigned int OnAction_tbtx_token(_adapter *padapter, union recv_frame *precv_frame); +#endif -#ifdef CONFIG_RTW_80211R -void rtw_ft_update_bcn(_adapter *padapter, union recv_frame *precv_frame); -void rtw_ft_start_clnt_join(_adapter *padapter); -u8 rtw_ft_update_rsnie(_adapter *padapter, u8 bwrite, - struct pkt_attrib *pattrib, u8 **pframe); -void rtw_ft_build_auth_req_ies(_adapter *padapter, - struct pkt_attrib *pattrib, u8 **pframe); -void rtw_ft_build_assoc_req_ies(_adapter *padapter, - u8 is_reassoc, struct pkt_attrib *pattrib, u8 **pframe); -u8 rtw_ft_update_auth_rsp_ies(_adapter *padapter, u8 *pframe, u32 len); -void rtw_ft_start_roam(_adapter *padapter, u8 *pTargetAddr); -void rtw_ft_issue_action_req(_adapter *padapter, u8 *pTargetAddr); -void rtw_ft_report_evt(_adapter *padapter); -void rtw_ft_report_reassoc_evt(_adapter *padapter, u8 *pMacAddr); -void rtw_ft_link_timer_hdl(void *ctx); -void rtw_ft_roam_timer_hdl(void *ctx); -void rtw_ft_roam_status_reset(_adapter *padapter); -#endif -#ifdef CONFIG_RTW_WNM -void rtw_wnm_roam_scan_hdl(void *ctx); -void rtw_wnm_process_btm_req(_adapter *padapter, u8* pframe, u32 frame_len); -void rtw_wnm_reset_btm_candidate(struct roam_nb_info *pnb); -void rtw_wnm_reset_btm_state(_adapter *padapter); -void rtw_wnm_issue_action(_adapter *padapter, u8 action, u8 reason); -#endif -#if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) -u32 rtw_wnm_btm_candidates_survey(_adapter *padapter, u8* pframe, u32 elem_len, u8 is_preference); +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT +void rtw_issue_action_token_req(_adapter *padapter, struct sta_info *pstat); +void rtw_issue_action_token_rel(_adapter *padapter); #endif + void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res); void mlmeext_sta_del_event_callback(_adapter *padapter); void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta); @@ -1055,6 +1060,10 @@ void rson_timer_hdl(void *ctx); #endif void link_timer_hdl(void *ctx); void addba_timer_hdl(void *ctx); +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT +void rtw_tbtx_xmit_timer_hdl(void *ctx); +void rtw_tbtx_token_dispatch_timer_hdl(void *ctx); +#endif #ifdef CONFIG_IEEE80211W void sa_query_timer_hdl(void *ctx); #endif /* CONFIG_IEEE80211W */ @@ -1098,35 +1107,32 @@ void rtw_join_done_chk_ch(_adapter *padapter, int join_res); int rtw_chk_start_clnt_join(_adapter *padapter, u8 *ch, u8 *bw, u8 *offset); +#ifdef RTW_BUSY_DENY_SCAN +#ifndef BUSY_TRAFFIC_SCAN_DENY_PERIOD +#ifdef CONFIG_RTW_ANDROID #ifdef CONFIG_PLATFORM_ARM_SUN8I #define BUSY_TRAFFIC_SCAN_DENY_PERIOD 8000 #else #define BUSY_TRAFFIC_SCAN_DENY_PERIOD 12000 #endif - -struct cmd_hdl { - uint parmsize; - u8(*h2cfuns)(struct _ADAPTER *padapter, u8 *pbuf); -}; +#else /* !CONFIG_ANDROID */ +#define BUSY_TRAFFIC_SCAN_DENY_PERIOD 16000 +#endif /* !CONFIG_ANDROID */ +#endif /* !BUSY_TRAFFIC_SCAN_DENY_PERIOD */ +#endif /* RTW_BUSY_DENY_SCAN */ void rtw_leave_opch(_adapter *adapter); void rtw_back_opch(_adapter *adapter); -u8 read_macreg_hdl(_adapter *padapter, u8 *pbuf); -u8 write_macreg_hdl(_adapter *padapter, u8 *pbuf); -u8 read_bbreg_hdl(_adapter *padapter, u8 *pbuf); -u8 write_bbreg_hdl(_adapter *padapter, u8 *pbuf); -u8 read_rfreg_hdl(_adapter *padapter, u8 *pbuf); -u8 write_rfreg_hdl(_adapter *padapter, u8 *pbuf); - - -u8 NULL_hdl(_adapter *padapter, u8 *pbuf); u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf); u8 disconnect_hdl(_adapter *padapter, u8 *pbuf); u8 createbss_hdl(_adapter *padapter, u8 *pbuf); #ifdef CONFIG_AP_MODE u8 stop_ap_hdl(_adapter *adapter); #endif +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT +u8 tx_control_hdl(_adapter *adapter); +#endif u8 setopmode_hdl(_adapter *padapter, u8 *pbuf); u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf); u8 setauth_hdl(_adapter *padapter, u8 *pbuf); @@ -1140,202 +1146,105 @@ u8 add_ba_rsp_hdl(_adapter *padapter, unsigned char *pbuf); void rtw_ap_wep_pk_setting(_adapter *adapter, struct sta_info *psta); u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf); -u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf); u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf); u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf); u8 rtw_set_chbw_hdl(_adapter *padapter, u8 *pbuf); -u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf); +u8 rtw_iqk_hdl(_adapter *padapter, unsigned char *pbuf); +u8 rtw_set_chplan_hdl(_adapter *padapter, unsigned char *pbuf); +u8 rtw_get_chplan_hdl(_adapter *padapter, unsigned char *pbuf); u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf); u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf); /* Kurt: Handling DFS channel switch announcement ie. */ u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf); u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf); -u8 rtw_getmacreg_hdl(_adapter *padapter, u8 *pbuf); +u8 rtw_write_bcnlen_hdl(_adapter *padapter, u8 *pbuf); int rtw_sae_preprocess(_adapter *adapter, const u8 *buf, u32 len, u8 tx); -#define GEN_DRV_CMD_HANDLER(size, cmd) {size, &cmd ## _hdl}, -#define GEN_MLME_EXT_HANDLER(size, cmd) {size, cmd}, +u32 rtw_desc_rate_to_bitrate(u8 bw, u8 rate_idx, u8 sgi); + +#ifdef CONFIG_RTW_MULTI_AP +u8 rtw_get_ch_utilization(_adapter *adapter); +void rtw_ch_util_rpt(_adapter *adapter); +#endif + +#define GEN_MLME_EXT_HANDLER(cmd, callback_func) {.cmd_hdl = cmd, .callback = callback_func}, + +struct rtw_cmd { + u8(*cmd_hdl)(_adapter *padapter, u8 *pbuf); + void (*callback)(_adapter *padapter, struct cmd_obj *cmd); +}; #ifdef _RTW_CMD_C_ - -struct cmd_hdl wlancmds[] = { - GEN_DRV_CMD_HANDLER(sizeof(struct readMAC_parm), rtw_getmacreg) /*0*/ - GEN_DRV_CMD_HANDLER(0, NULL) - GEN_DRV_CMD_HANDLER(0, NULL) - GEN_DRV_CMD_HANDLER(0, NULL) - GEN_DRV_CMD_HANDLER(0, NULL) - GEN_DRV_CMD_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) /*10*/ - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(sizeof(struct joinbss_parm), join_cmd_hdl) /*14*/ - GEN_MLME_EXT_HANDLER(sizeof(struct disconnect_parm), disconnect_hdl) - GEN_MLME_EXT_HANDLER(sizeof(struct createbss_parm), createbss_hdl) - GEN_MLME_EXT_HANDLER(sizeof(struct setopmode_parm), setopmode_hdl) - GEN_MLME_EXT_HANDLER(sizeof(struct sitesurvey_parm), sitesurvey_cmd_hdl) /*18*/ - GEN_MLME_EXT_HANDLER(sizeof(struct setauth_parm), setauth_hdl) - GEN_MLME_EXT_HANDLER(sizeof(struct setkey_parm), setkey_hdl) /*20*/ - GEN_MLME_EXT_HANDLER(sizeof(struct set_stakey_parm), set_stakey_hdl) - GEN_MLME_EXT_HANDLER(sizeof(struct set_assocsta_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof(struct del_assocsta_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof(struct setstapwrstate_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof(struct setbasicrate_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof(struct getbasicrate_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof(struct setdatarate_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof(struct getdatarate_parm), NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) /*30*/ - GEN_MLME_EXT_HANDLER(sizeof(struct setphy_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof(struct getphy_parm), NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) /*40*/ - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), add_ba_hdl) - GEN_MLME_EXT_HANDLER(sizeof(struct set_ch_parm), rtw_set_chbw_hdl) /* 46 */ - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) /*50*/ - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(sizeof(struct Tx_Beacon_param), tx_beacon_hdl) /*55*/ - - GEN_MLME_EXT_HANDLER(0, mlme_evt_hdl) /*56*/ - GEN_MLME_EXT_HANDLER(0, rtw_drvextra_cmd_hdl) /*57*/ - - GEN_MLME_EXT_HANDLER(0, h2c_msg_hdl) /*58*/ - GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelPlan_param), set_chplan_hdl) /*59*/ - GEN_MLME_EXT_HANDLER(sizeof(struct LedBlink_param), led_blink_hdl) /*60*/ - - GEN_MLME_EXT_HANDLER(0, set_csa_hdl) /*61*/ - GEN_MLME_EXT_HANDLER(sizeof(struct TDLSoption_param), tdls_hdl) /*62*/ - GEN_MLME_EXT_HANDLER(0, chk_bmc_sleepq_hdl) /*63*/ - GEN_MLME_EXT_HANDLER(sizeof(struct RunInThread_param), run_in_thread_hdl) /*64*/ - GEN_MLME_EXT_HANDLER(sizeof(struct addBaRsp_parm), add_ba_rsp_hdl) /* 65 */ - GEN_MLME_EXT_HANDLER(sizeof(struct rm_event), rm_post_event_hdl) /* 66 */ -}; - -#endif - -struct C2HEvent_Header { - -#ifdef CONFIG_LITTLE_ENDIAN - - unsigned int len:16; - unsigned int ID:8; - unsigned int seq:8; - -#elif defined(CONFIG_BIG_ENDIAN) - - unsigned int seq:8; - unsigned int ID:8; - unsigned int len:16; - +#ifdef CONFIG_RTW_MESH +extern u8 rtw_mesh_set_plink_state_cmd_hdl(_adapter *adapter, u8 *parmbuf); #else - -# error "Must be LITTLE or BIG Endian" - +u8 rtw_mesh_set_plink_state_cmd_hdl(_adapter *adapter, u8 *parmbuf) { return H2C_CMD_FAIL; }; #endif - unsigned int rsvd; +struct rtw_cmd wlancmds[] = { + GEN_MLME_EXT_HANDLER(join_cmd_hdl, rtw_joinbss_cmd_callback) /*CMD_JOINBSS*/ + GEN_MLME_EXT_HANDLER(disconnect_hdl, rtw_disassoc_cmd_callback) /*CMD_DISCONNECT*/ + GEN_MLME_EXT_HANDLER(createbss_hdl, NULL) /*CMD_CREATE_BSS*/ + GEN_MLME_EXT_HANDLER(setopmode_hdl, NULL) /*CMD_SET_OPMODE*/ + GEN_MLME_EXT_HANDLER(sitesurvey_cmd_hdl, rtw_survey_cmd_callback) /*CMD_SITE_SURVEY*/ + GEN_MLME_EXT_HANDLER(setauth_hdl, NULL) /*CMD_SET_AUTH*/ + GEN_MLME_EXT_HANDLER(setkey_hdl, NULL) /*CMD_SET_KEY*/ + GEN_MLME_EXT_HANDLER(set_stakey_hdl, rtw_setstaKey_cmdrsp_callback) /*CMD_SET_STAKEY*/ + GEN_MLME_EXT_HANDLER(add_ba_hdl, NULL) /*CMD_ADD_BAREQ*/ + GEN_MLME_EXT_HANDLER(rtw_set_chbw_hdl, NULL) /*CMD_SET_CHANNEL*/ + GEN_MLME_EXT_HANDLER(tx_beacon_hdl, NULL) /*CMD_TX_BEACON*/ + GEN_MLME_EXT_HANDLER(mlme_evt_hdl, NULL) /*CMD_SET_MLME_EVT*/ + GEN_MLME_EXT_HANDLER(rtw_drvextra_cmd_hdl, NULL) /*CMD_SET_DRV_EXTRA*/ + GEN_MLME_EXT_HANDLER(rtw_set_chplan_hdl, NULL) /*CMD_SET_CHANPLAN*/ + GEN_MLME_EXT_HANDLER(led_blink_hdl, NULL) /*CMD_LEDBLINK*/ + GEN_MLME_EXT_HANDLER(set_csa_hdl, NULL) /*CMD_SET_CHANSWITCH*/ + GEN_MLME_EXT_HANDLER(tdls_hdl, NULL) /*CMD_TDLS*/ + GEN_MLME_EXT_HANDLER(chk_bmc_sleepq_hdl, NULL) /*CMD_CHK_BMCSLEEPQ*/ + GEN_MLME_EXT_HANDLER(run_in_thread_hdl, NULL) /*CMD_RUN_INTHREAD*/ + GEN_MLME_EXT_HANDLER(add_ba_rsp_hdl, NULL) /*CMD_ADD_BARSP*/ + GEN_MLME_EXT_HANDLER(rm_post_event_hdl, NULL) /*CMD_RM_POST_EVENT*/ + GEN_MLME_EXT_HANDLER(rtw_mesh_set_plink_state_cmd_hdl, NULL) /*CMD_SET_MESH_PLINK_STATE*/ + GEN_MLME_EXT_HANDLER(rtw_iqk_hdl, NULL) /*CMD_DO_IQK*/ + GEN_MLME_EXT_HANDLER(rtw_get_chplan_hdl, NULL) /* CMD_GET_CHANPLAN */ + GEN_MLME_EXT_HANDLER(rtw_write_bcnlen_hdl, NULL) /* CMD_WRITE_BCN_LEN */ +}; +#endif +struct rtw_evt_header { + u8 id; + u8 seq; + u16 len; }; -void rtw_dummy_event_callback(_adapter *adapter , u8 *pbuf); -void rtw_fwdbg_event_callback(_adapter *adapter , u8 *pbuf); - -enum rtw_c2h_event { - GEN_EVT_CODE(_Read_MACREG) = 0, /*0*/ - GEN_EVT_CODE(_Read_BBREG), - GEN_EVT_CODE(_Read_RFREG), - GEN_EVT_CODE(_Read_EEPROM), - GEN_EVT_CODE(_Read_EFUSE), - GEN_EVT_CODE(_Read_CAM), /*5*/ - GEN_EVT_CODE(_Get_BasicRate), - GEN_EVT_CODE(_Get_DataRate), - GEN_EVT_CODE(_Survey), /*8*/ - GEN_EVT_CODE(_SurveyDone), /*9*/ - - GEN_EVT_CODE(_JoinBss) , /*10*/ - GEN_EVT_CODE(_AddSTA), - GEN_EVT_CODE(_DelSTA), - GEN_EVT_CODE(_AtimDone) , - GEN_EVT_CODE(_TX_Report), - GEN_EVT_CODE(_CCX_Report), /*15*/ - GEN_EVT_CODE(_DTM_Report), - GEN_EVT_CODE(_TX_Rate_Statistics), - GEN_EVT_CODE(_C2HLBK), - GEN_EVT_CODE(_FWDBG), - GEN_EVT_CODE(_C2HFEEDBACK), /*20*/ - GEN_EVT_CODE(_ADDBA), - GEN_EVT_CODE(_C2HBCN), - GEN_EVT_CODE(_ReportPwrState), /* filen: only for PCIE, USB */ - GEN_EVT_CODE(_CloseRF), /* filen: only for PCIE, work around ASPM */ - GEN_EVT_CODE(_WMM), /*25*/ +enum rtw_event_id { + EVT_SURVEY, /*0*/ + EVT_SURVEY_DONE, /*1*/ + EVT_JOINBSS, /*2*/ + EVT_ADD_STA, /*3*/ + EVT_DEL_STA, /*4*/ + EVT_WMM_UPDATE, /*5*/ #ifdef CONFIG_IEEE80211W - GEN_EVT_CODE(_TimeoutSTA), + EVT_TIMEOUT_STA, /*6*/ #endif /* CONFIG_IEEE80211W */ #ifdef CONFIG_RTW_80211R - GEN_EVT_CODE(_FT_REASSOC), + EVT_FT_REASSOC, /*7*/ #endif - MAX_C2HEVT + EVT_ID_MAX }; - - #ifdef _RTW_MLME_EXT_C_ - -static struct fwevent wlanevents[] = { - {0, rtw_dummy_event_callback}, /*0*/ - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, &rtw_survey_event_callback}, /*8*/ - {sizeof(struct surveydone_event), &rtw_surveydone_event_callback}, /*9*/ - - {0, &rtw_joinbss_event_callback}, /*10*/ - {sizeof(struct stassoc_event), &rtw_stassoc_event_callback}, - {sizeof(struct stadel_event), &rtw_stadel_event_callback}, - {0, &rtw_atimdone_event_callback}, - {0, rtw_dummy_event_callback}, - {0, NULL}, /*15*/ - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, rtw_fwdbg_event_callback}, - {0, NULL}, /*20*/ - {0, NULL}, - {0, NULL}, - {0, &rtw_cpwm_event_callback}, - {0, NULL}, - {0, &rtw_wmm_event_callback}, /*25*/ -#ifdef CONFIG_IEEE80211W - {sizeof(struct stadel_event), &rtw_sta_timeout_event_callback}, -#endif /* CONFIG_IEEE80211W */ -#ifdef CONFIG_RTW_80211R - {sizeof(struct stassoc_event), &rtw_ft_reassoc_event_callback}, -#endif +static struct rtw_event wlanevents[] = { + {sizeof(struct survey_event), &rtw_survey_event_callback}, /*EVT_SURVEY*/ + {sizeof(struct surveydone_event), &rtw_surveydone_event_callback}, /*EVT_SURVEY_DONE*/ + {sizeof(struct joinbss_event), &rtw_joinbss_event_callback}, /*EVT_JOINBSS*/ + {sizeof(struct stassoc_event), &rtw_stassoc_event_callback}, /*EVT_ADD_STA*/ + {sizeof(struct stadel_event), &rtw_stadel_event_callback}, /*EVT_DEL_STA*/ + {sizeof(struct wmm_event), &rtw_wmm_event_callback}, /*EVT_WMM_UPDATE*/ + #ifdef CONFIG_IEEE80211W + {sizeof(struct stadel_event), &rtw_sta_timeout_event_callback}, /*EVT_TIMEOUT_STA*/ + #endif /* CONFIG_IEEE80211W */ + #ifdef CONFIG_RTW_80211R + {sizeof(struct stassoc_event), &rtw_ft_reassoc_event_callback}, /*EVT_FT_REASSOC*/ + #endif }; - #endif/* _RTW_MLME_EXT_C_ */ - #endif diff --git a/include/rtw_mp.h b/include/rtw_mp.h index c3b609f..c2a6ca4 100644 --- a/include/rtw_mp.h +++ b/include/rtw_mp.h @@ -274,6 +274,7 @@ enum { EFUSE_BT_MASK, EFUSE_MASK, EFUSE_FILE, + EFUSE_FILE_STORE, MP_TX, MP_RX, MP_IQK, @@ -289,6 +290,8 @@ enum { MP_LINK, MP_DPK_TRK, MP_DPK, + MP_GET_TSSIDE, + MP_SET_TSSIDE, MP_NULL, #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE VENDOR_IE_SET , @@ -297,6 +300,10 @@ enum { #ifdef CONFIG_WOWLAN MP_WOW_ENABLE, MP_WOW_SET_PATTERN, +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + MP_WOW_SET_KEEP_ALIVE_PATTERN, +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + #endif #ifdef CONFIG_AP_WOWLAN MP_AP_WOW_ENABLE, @@ -385,6 +392,8 @@ struct mp_priv { BOOLEAN mplink_btx; bool tssitrk_on; + bool efuse_update_file; + char efuse_file_path[128]; }; typedef struct _IOCMD_STRUCT_ { @@ -725,17 +734,19 @@ void hal_mpt_SetContinuousTx(PADAPTER pAdapter, u8 bStart); void hal_mpt_SetSingleCarrierTx(PADAPTER pAdapter, u8 bStart); void hal_mpt_SetSingleToneTx(PADAPTER pAdapter, u8 bStart); void hal_mpt_SetCarrierSuppressionTx(PADAPTER pAdapter, u8 bStart); -void mpt_ProSetPMacTx(PADAPTER Adapter); +u8 mpt_ProSetPMacTx(PADAPTER Adapter); void MP_PHY_SetRFPathSwitch(PADAPTER pAdapter , BOOLEAN bMain); void mp_phy_switch_rf_path_set(PADAPTER pAdapter , u8 *pstate); u8 MP_PHY_QueryRFPathSwitch(PADAPTER pAdapter); u32 mpt_ProQueryCalTxPower(PADAPTER pAdapter, u8 RfPath); -void MPT_PwrCtlDM(PADAPTER padapter, u32 bstart); +void MPT_PwrCtlDM(PADAPTER padapter, u32 trk_type); u8 mpt_to_mgnt_rate(u32 MptRateIdx); u8 rtw_mpRateParseFunc(PADAPTER pAdapter, u8 *targetStr); u32 mp_join(PADAPTER padapter, u8 mode); u32 hal_mpt_query_phytxok(PADAPTER pAdapter); u32 mpt_get_tx_power_finalabs_val(PADAPTER padapter, u8 rf_path); +void mpt_trigger_tssi_tracking(PADAPTER pAdapter, u8 rf_path); + void PMAC_Get_Pkt_Param( @@ -897,6 +908,9 @@ int rtw_bt_efuse_mask_file(struct net_device *dev, int rtw_efuse_file_map(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +int rtw_efuse_file_map_store(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); int rtw_bt_efuse_file_map(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); @@ -920,4 +934,10 @@ int rtw_mp_iqk(struct net_device *dev, int rtw_mp_lck(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrqu, char *extra); +int rtw_mp_get_tsside(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_set_tsside(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); #endif /* _RTW_MP_H_ */ diff --git a/include/rtw_odm.h b/include/rtw_odm.h index 2319297..515b958 100644 --- a/include/rtw_odm.h +++ b/include/rtw_odm.h @@ -82,11 +82,15 @@ void rtw_odm_get_perpkt_rssi(void *sel, _adapter *adapter); void rtw_odm_acquirespinlock(_adapter *adapter, enum rt_spinlock_type type); void rtw_odm_releasespinlock(_adapter *adapter, enum rt_spinlock_type type); +struct dm_struct; +s16 rtw_odm_get_tx_power_mbm(struct dm_struct *dm, u8 rfpath, u8 rate, u8 bw, u8 cch); + #ifdef CONFIG_DFS_MASTER void rtw_odm_radar_detect_reset(_adapter *adapter); void rtw_odm_radar_detect_disable(_adapter *adapter); void rtw_odm_radar_detect_enable(_adapter *adapter); BOOLEAN rtw_odm_radar_detect(_adapter *adapter); +void rtw_odm_update_dfs_region(struct dvobj_priv *dvobj); u8 rtw_odm_radar_detect_polling_int_ms(struct dvobj_priv *dvobj); #endif /* CONFIG_DFS_MASTER */ diff --git a/include/rtw_p2p.h b/include/rtw_p2p.h index 1f985ad..8d929ad 100644 --- a/include/rtw_p2p.h +++ b/include/rtw_p2p.h @@ -70,8 +70,6 @@ u8 p2p_ps_wk_cmd(_adapter *padapter, u8 p2p_ps_state, u8 enqueue); #endif /* CONFIG_P2P_PS */ #ifdef CONFIG_IOCTL_CFG80211 -u8 roch_stay_in_cur_chan(_adapter *padapter); -void rtw_init_cfg80211_wifidirect_info(_adapter *padapter); int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx); #endif /* CONFIG_IOCTL_CFG80211 */ diff --git a/include/rtw_pwrctrl.h b/include/rtw_pwrctrl.h index afbdd20..e17c50b 100644 --- a/include/rtw_pwrctrl.h +++ b/include/rtw_pwrctrl.h @@ -38,6 +38,7 @@ #ifdef CONFIG_BT_COEXIST #define BTCOEX_ALIVE BIT(4) #endif /* CONFIG_BT_COEXIST */ +#define LPS_ALIVE BIT(5) #ifdef CONFIG_WOWLAN #ifdef CONFIG_PLATFORM_ANDROID_INTEL_X86 @@ -51,11 +52,12 @@ #ifdef CONFIG_WOW_PATTERN_HW_CAM /* Frame Mask Cam number for pattern match */ #define MAX_WKFM_CAM_NUM 12 #else -#define MAX_WKFM_CAM_NUM 16 +#define MAX_WKFM_CAM_NUM 10 #endif #define MAX_WKFM_SIZE 16 /* (16 bytes for WKFM bit mask, 16*8 = 128 bits) */ #define MAX_WKFM_PATTERN_SIZE 128 +#define MAX_IN_PATTERN_SIZE 512 /* * MAX_WKFM_PATTERN_STR_LEN : the max. length of wow pattern string @@ -233,6 +235,38 @@ typedef enum _PS_DENY_REASON { PS_DENY_OTHERS = 31 } PS_DENY_REASON; +#ifdef CONFIG_WAR_OFFLOAD +/* only support mDNS V4/V6 rsp now */ +enum { + WAR_ARP_RSP_EN = 0x0000001, + WAR_ICMPV6_NS_RSP_EN = 0x00000002, + WAR_ICMPV4_ECHO_RSP_EN = 0x00000004, + WAR_ICMPV6_ECHO_RSP_EN = 0x00000008, + WAR_NETBIOS_RSP_EN = 0x00000010, + WAR_LLMNR_V4_RSP_EN = 0x00000020, + WAR_LLMNR_V6_RSP_EN = 0x00000040, + WAR_SNMP_V4_RSP_EN = 0x00000080, + WAR_SNMP_V6_RSP_EN = 0x00000100, + WAR_SNMP_V4_WAKEUP_EN = 0x00000200, + WAR_SNMP_V6_WAKEUP_EN = 0x00000400, + WAR_SSDP_V4_WAKEUP_EN = 0x00000800, + WAR_SSDP_V6_WAKEUP_EN = 0x00001000, + WAR_WSD_V4_WAKEUP_EN = 0x00002000, + WAR_WSD_V6_WAKEUP_EN = 0x00004000, + WAR_SLP_V4_WAKEUP_EN = 0x00008000, + WAR_SLP_V6_WAKEUP_EN = 0x00010000, + WAR_MDNS_V4_RSP_EN = 0x00020000, + WAR_MDNS_V6_RSP_EN = 0x00040000, + WAR_DESIGNATED_MAC_EN = 0x00080000, + WAR_LLTD_WAKEUP_EN = 0x00100000, + WAR_ARP_WAKEUP_EN = 0x00200000, + WAR_MAGIC_WAKEUP_EN = 0x00400000, + WAR_MDNS_V4_WAKEUP_EN = 0x000800000, + WAR_MDNS_V6_WAKEUP_EN = 0x001000000 +}; + +#endif /* CONFIG_WAR_OFFLOAD */ + #ifdef CONFIG_PNO_SUPPORT typedef struct pno_nlo_info { u32 fast_scan_period; /* Fast scan period */ @@ -308,6 +342,72 @@ struct aoac_report { u8 rxgtk_iv[4][8]; }; +#ifdef CONFIG_WAR_OFFLOAD + +struct war_ipv4_fmt { + u32 ip_addr[4]; + u32 ip_subnet[4]; + u32 ip_gateway[4]; +}; + +struct war_ipv6_fmt { + u8 ipv6_addr[8][16]; +}; + +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) +/* limitation of mDNS parameter : length and number */ +#define MAX_MDNS_SERVICE_NAME_LEN 15 +#define MAX_MDNS_TRANS_LEN 4 /* _tcp or _udp */ +#define MAX_MDNS_DOMAIN_LEN 5 /* local only for mdns */ +#define MAX_MDNS_MACHINE_NAME_LEN (63+1) /* +1 for the length byte used by the DNS format */ +#define MAX_MDNS_TARGET_LEN 63 +#define MAX_MDNS_DOMAIN_NAME_LEN 63 +#define MAX_MDNS_TXT_LEN 1536 +#define MAX_MDNS_TXT_SINGLE_LEN 255 + + +#define MAX_MDNS_SERVICE_NUM 10 +#define MAX_MDNS_TXT_NUM 8 +#define MAX_MDNS_MACHINE_NAME_NUM 3 + +/* for monitor rsvd page using */ +#define MAX_MDNS_PARA_SIZE 1700 // 14*128 = 1792 +#define MAX_MDNS_TXT_TOTAL_SIZE 10*MAX_MDNS_TXT_LEN +#define MAX_MDNS_RSP_PKT_SIZE 760 // 6*128 = 768 + +#define RTW_MDNS_SRV_INFO(sname, sname_len, tname, tname_len, dname, dname_len, port0, port1, ttlv, tar, tar_len, idx) \ + { .service=sname, .service_len=sname_len, .transport=tname, .transport_len=tname_len, \ + .domain=dname , .domain_len=dname_len , .port[0]=port0, .port[1]=port1, .ttl=ttlv, \ + .target=tar, .target_len=tar_len, .txt_rsp_idx=idx } + + +struct war_mdns_service_info { + u8 service[MAX_MDNS_SERVICE_NAME_LEN+1]; + u8 service_len; + u8 transport[MAX_MDNS_TRANS_LEN+1]; + u8 transport_len; + u8 domain[MAX_MDNS_DOMAIN_LEN+1]; + u8 domain_len; + u8 port[2]; + u32 ttl; + u8 target[MAX_MDNS_TARGET_LEN+1]; + u8 target_len; + s8 txt_rsp_idx; +}; + +struct war_mdns_machine_name { + u8 name[MAX_MDNS_MACHINE_NAME_LEN]; + u8 name_len; +}; + +struct war_mdns_txt_rsp { + u8 txt[MAX_MDNS_TXT_LEN]; + u16 txt_len; +}; +#endif +#endif /* CONFIG_WAR_OFFLOAD */ + + struct rsvd_page_cache_t; struct pwrctrl_priv { @@ -383,11 +483,6 @@ struct pwrctrl_priv { systime lps_deny_time; /* will deny LPS when system time is smaller than this */ s32 pnp_current_pwr_state; u8 pnp_bstop_trx; - - #ifdef CONFIG_AUTOSUSPEND - int ps_flag; /* used by autosuspend */ - u8 bInternalAutoSuspend; - #endif u8 bInSuspend; #ifdef CONFIG_BT_COEXIST u8 bAutoResume; @@ -404,6 +499,8 @@ struct pwrctrl_priv { #ifdef CONFIG_GPIO_WAKEUP u8 is_high_active; + u8 wowlan_gpio_index; + u8 wowlan_gpio_output_state; #endif /* CONFIG_GPIO_WAKEUP */ u8 hst2dev_high_active; #ifdef CONFIG_WOWLAN @@ -415,6 +512,9 @@ struct pwrctrl_priv { u8 wowlan_pattern_idx; u64 wowlan_fw_iv; struct rtl_priv_pattern patterns[MAX_WKFM_CAM_NUM]; +#ifdef CONFIG_WOW_PATTERN_IN_TXFIFO + u8 pattern_rsvd_page_loc; +#endif #ifdef CONFIG_PNO_SUPPORT u8 pno_inited; pno_nlo_info_t *pnlo_info; @@ -431,6 +531,45 @@ struct pwrctrl_priv { #ifdef CONFIG_LPS_1T1R u8 wowlan_lps_1t1r; #endif + + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + /*data 0,rsv page location*/ + u8 wowlan_keep_alive_mode; + u8 keep_alive_pattern_loc; + /*data 1 ,cam id, rx udp packet*/ + u8 wowlan_keep_alive_ack_index; + /*data 2 ,cam id, pattern match packet*/ + u8 wowlan_wake_pattern_index; + /*data3,unit: TBTT*/ + u16 wowlan_keep_alive_period; + /*data4,unit: TBTT*/ + u8 wowlan_keep_alive_retry_interval; + /*data5*/ + u8 wowlan_keep_alive_retry_counter; + /*from echo*/ + u8 keep_alive_pattern[WLAN_MAX_KEEP_ALIVE_IE_LEN]; + u32 keep_alive_pattern_len; + #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + +#ifdef CONFIG_WAR_OFFLOAD + u8 wowlan_war_offload_mode; + u32 wowlan_war_offload_ctrl; + struct war_ipv4_fmt wowlan_war_offload_ipv4; + struct war_ipv6_fmt wowlan_war_offload_ipv6; + u8 wowlan_war_offload_mac[6]; +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) + struct war_mdns_machine_name wowlan_war_offload_mdns_mnane[MAX_MDNS_MACHINE_NAME_NUM]; + struct war_mdns_service_info wowlan_war_offload_mdns_service[MAX_MDNS_SERVICE_NUM]; + struct war_mdns_txt_rsp wowlan_war_offload_mdns_txt_rsp[MAX_MDNS_TXT_NUM]; + u8 wowlan_war_offload_mdns_mnane_num; + u8 wowlan_war_offload_mdns_service_info_num; + u8 wowlan_war_offload_mdns_txt_rsp_num; + u8 wowlan_war_offload_mdns_domain_name[MAX_MDNS_DOMAIN_NAME_LEN+1]; + u8 wowlan_war_offload_mdns_domain_name_len; + u32 wowlan_war_offload_mdns_para_cur_size; + u32 wowlan_war_offload_mdns_rsp_cur_size; +#endif /* CONFIG_OFFLOAD_MDNS_V4 || CONFIG_OFFLOAD_MDNS_V6 */ +#endif /* CONFIG_WAR_OFFLOAD */ #endif /* CONFIG_WOWLAN */ _timer pwr_state_check_timer; int pwr_state_check_interval; @@ -480,14 +619,14 @@ struct pwrctrl_priv { #endif u8 current_lps_hw_port_id; -#ifdef CONFIG_RTW_CFGVEDNOR_LLSTATS +#ifdef CONFIG_RTW_CFGVENDOR_LLSTATS systime radio_on_start_time; systime pwr_saving_start_time; u32 pwr_saving_time; u32 on_time; u32 tx_time; u32 rx_time; -#endif /* CONFIG_RTW_CFGVEDNOR_LLSTATS */ +#endif /* CONFIG_RTW_CFGVENDOR_LLSTATS */ #ifdef CONFIG_LPS_ACK struct submit_ctx lps_ack_sctx; @@ -542,9 +681,6 @@ int ips_leave(_adapter *padapter); void rtw_ps_processor(_adapter *padapter); -#ifdef CONFIG_AUTOSUSPEND -int autoresume_enter(_adapter *padapter); -#endif #ifdef SUPPORT_HW_RFOFF_DETECTED rt_rf_power_state RfOnOffDetect(PADAPTER pAdapter); #endif @@ -558,7 +694,8 @@ int rtw_fw_ps_state(PADAPTER padapter); extern const char * const LPS_CTRL_PHYDM; void LPS_Enter(PADAPTER padapter, const char *msg); void LPS_Leave(PADAPTER padapter, const char *msg); -void rtw_leave_lps_and_chk(_adapter *padapter, u8 ps_mode); +void rtw_exec_lps(_adapter *padapter, u8 ps_mode); +void rtw_lps_rfon_ctrl(_adapter *padapter, u8 rfon_ctrl); #ifdef CONFIG_CHECK_LEAVE_LPS #ifdef CONFIG_LPS_CHK_BY_TP void traffic_check_for_leave_lps_by_tp(PADAPTER padapter, u8 tx, struct sta_info *sta); @@ -623,6 +760,15 @@ bool rtw_wowlan_parser_pattern_cmd(u8 *input, char *pattern, void rtw_wow_pattern_sw_reset(_adapter *adapter); u8 rtw_set_default_pattern(_adapter *adapter); void rtw_wow_pattern_sw_dump(_adapter *adapter); +#ifdef CONFIG_WAR_OFFLOAD +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) +void rtw_wow_war_mdns_dump_buf(struct seq_file *m, u8 *title, u8 *buf, u32 len); +void rtw_wow_war_mdns_dump_txt(struct seq_file *m, u8 *title, u8 *buf, u32 len); +bool rtw_wow_war_mdns_parser_pattern(u8 *input, char *target, u32 *target_len, u32 max_len); +void rtw_wow_war_mdns_parms_reset(_adapter *adapter, u8 is_set_default); +#endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */ +#endif /* CONFIG_WAR_OFFLOAD */ + #endif /* CONFIG_WOWLAN */ void rtw_ssmps_enter(_adapter *adapter, struct sta_info *sta); void rtw_ssmps_leave(_adapter *adapter, struct sta_info *sta); diff --git a/include/rtw_recv.h b/include/rtw_recv.h index 9e6da87..a0759e9 100644 --- a/include/rtw_recv.h +++ b/include/rtw_recv.h @@ -172,8 +172,6 @@ struct rx_pkt_attrib { u8 crc_err; u8 icv_err; - u16 eth_type; - u8 dst[ETH_ALEN]; u8 src[ETH_ALEN]; u8 ta[ETH_ALEN]; @@ -197,11 +195,15 @@ struct rx_pkt_attrib { u8 ldpc; u8 sgi; u8 pkt_rpt_type; - u32 tsfl; u32 MacIDValidEntry[2]; /* 64 bits present 64 entry. */ + u8 ampdu; u8 ppdu_cnt; + u8 ampdu_eof; u32 free_cnt; /* free run counter */ struct phydm_phyinfo_struct phy_info; +#ifdef CONFIG_WIFI_MONITOR + u8 moif[16]; +#endif #ifdef CONFIG_TCP_CSUM_OFFLOAD_RX /* checksum offload realted varaiables */ @@ -402,6 +404,15 @@ struct recv_priv { _queue recv_buf_pending_queue; #endif +#if defined(CONFIG_SDIO_HCI) +#ifdef CONFIG_SDIO_RECVBUF_PWAIT + struct rtw_pwait_ctx recvbuf_pwait; +#endif +#ifdef CONFIG_SDIO_RECVBUF_AGGREGATION + bool recvbuf_agg; +#endif +#endif /* CONFIG_SDIO_HCI */ + #ifdef CONFIG_PCI_HCI /* Rx */ struct rtw_rx_ring rx_ring[PCI_MAX_RX_QUEUE]; @@ -438,6 +449,15 @@ struct recv_priv { BOOLEAN store_law_data_flag; }; +#ifdef CONFIG_SDIO_RECVBUF_AGGREGATION +#define recv_buf_agg(recvpriv) recvpriv->recvbuf_agg +#ifndef CONFIG_SDIO_RECVBUF_AGGREGATION_EN +#define CONFIG_SDIO_RECVBUF_AGGREGATION_EN 1 +#endif +#else +#define recv_buf_agg(recvpriv) 0 +#endif + #define RX_BH_STG_UNKNOWN 0 #define RX_BH_STG_HDL_ENTER 1 #define RX_BH_STG_HDL_EXIT 2 @@ -486,10 +506,20 @@ struct sta_recv_priv { }; +#define RBUF_TYPE_PREALLOC 0 +#define RBUF_TYPE_TMP 1 +#define RBUF_TYPE_PWAIT_ADJ 2 + struct recv_buf { _list list; +#ifdef PLATFORM_WINDOWS _lock recvbuf_lock; +#endif + +#ifdef CONFIG_SDIO_RECVBUF_PWAIT_RUNTIME_ADJUST + u8 type; +#endif u32 ref_cnt; @@ -520,6 +550,11 @@ struct recv_buf { #endif }; +#ifdef CONFIG_SDIO_RECVBUF_PWAIT_RUNTIME_ADJUST +#define RBUF_IS_PREALLOC(rbuf) ((rbuf)->type == RBUF_TYPE_PREALLOC) +#else +#define RBUF_IS_PREALLOC(rbuf) 1 +#endif /* head -----> @@ -545,7 +580,7 @@ struct recv_frame_hdr { u8 fragcnt; int frame_tag; - + int keytrack; struct rx_pkt_attrib attrib; uint len; @@ -586,6 +621,12 @@ union recv_frame { }; +enum rtw_rx_llc_hdl { + RTW_RX_LLC_KEEP = 0, + RTW_RX_LLC_REMOVE = 1, + RTW_RX_LLC_VLAN = 2, +}; + bool rtw_rframe_del_wfd_ie(union recv_frame *rframe, u8 ies_offset); typedef enum _RX_PACKET_TYPE { @@ -612,6 +653,9 @@ sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue); sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue); struct recv_buf *rtw_dequeue_recvbuf(_queue *queue); +void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *psta); +void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *psta); + #if defined(CONFIG_80211N_HT) && defined(CONFIG_RECV_REORDERING_CTRL) void rtw_reordering_ctrl_timeout_handler(void *pcontext); #endif @@ -768,7 +812,7 @@ __inline static union recv_frame *rxmem_to_recvframe(u8 *rxmem) __inline static union recv_frame *pkt_to_recvframe(_pkt *pkt) { - u8 *buf_star = NULL; + u8 *buf_star; union recv_frame *precv_frame; precv_frame = rxmem_to_recvframe((unsigned char *)buf_star); diff --git a/include/rtw_rf.h b/include/rtw_rf.h index fb52abb..3a24929 100644 --- a/include/rtw_rf.h +++ b/include/rtw_rf.h @@ -34,6 +34,7 @@ #define MAX_CHANNEL_NUM_2G CENTER_CH_2G_NUM #define MAX_CHANNEL_NUM_5G CENTER_CH_5G_20M_NUM #define MAX_CHANNEL_NUM (MAX_CHANNEL_NUM_2G + MAX_CHANNEL_NUM_5G) +#define MAX_CHANNEL_NUM_OF_BAND rtw_max(MAX_CHANNEL_NUM_2G, MAX_CHANNEL_NUM_5G) extern u8 center_ch_2g[CENTER_CH_2G_NUM]; extern u8 center_ch_2g_40m[CENTER_CH_2G_40M_NUM]; @@ -55,6 +56,9 @@ u8 rtw_get_scch_by_cch_opch(u8 cch, u8 bw, u8 opch); u8 rtw_get_op_chs_by_cch_bw(u8 cch, u8 bw, u8 **op_chs, u8 *op_ch_num); +u8 rtw_get_offset_by_chbw(u8 ch, u8 bw, u8 *r_offset); +u8 rtw_get_center_ch(u8 ch, u8 bw, u8 offset); + u8 rtw_get_ch_group(u8 ch, u8 *group, u8 *cck_group); typedef enum _CAPABILITY { @@ -116,6 +120,60 @@ extern const char *const _ch_width_str[]; extern const u8 _ch_width_to_bw_cap[]; #define ch_width_to_bw_cap(bw) (((bw) < CHANNEL_WIDTH_MAX) ? _ch_width_to_bw_cap[(bw)] : 0) +enum opc_bw { + OPC_BW20 = 0, + OPC_BW40PLUS = 1, + OPC_BW40MINUS = 2, + OPC_BW80 = 3, + OPC_BW160 = 4, + OPC_BW80P80 = 5, + OPC_BW_NUM, +}; + +extern const char *const _opc_bw_str[OPC_BW_NUM]; +#define opc_bw_str(bw) (((bw) < OPC_BW_NUM) ? _opc_bw_str[(bw)] : "N/A") + +extern const u8 _opc_bw_to_ch_width[OPC_BW_NUM]; +#define opc_bw_to_ch_width(bw) (((bw) < OPC_BW_NUM) ? _opc_bw_to_ch_width[(bw)] : CHANNEL_WIDTH_MAX) + +/* global op class APIs */ +bool is_valid_global_op_class_id(u8 gid); +s16 get_sub_op_class(u8 gid, u8 ch); +void dump_global_op_class(void *sel); +u8 rtw_get_op_class_by_chbw(u8 ch, u8 bw, u8 offset); +u8 rtw_get_bw_offset_by_op_class_ch(u8 gid, u8 ch, u8 *bw, u8 *offset); + +struct op_ch_t { + u8 ch; + u8 static_non_op:1; /* not in channel list */ + u8 no_ir:1; + s16 max_txpwr; /* mBm */ +}; + +struct op_class_pref_t { + u8 class_id; + BAND_TYPE band; + enum opc_bw bw; + u8 ch_num; /* number of chs */ + u8 op_ch_num; /* channel number which is not static non operable */ + u8 ir_ch_num; /* channel number which can init radiation */ + struct op_ch_t chs[MAX_CHANNEL_NUM_OF_BAND]; /* zero(ch) terminated array */ +}; + +int op_class_pref_init(_adapter *adapter); +void op_class_pref_deinit(_adapter *adapter); + +#define REG_BEACON_HINT 0 +#define REG_TXPWR_CHANGE 1 +#define REG_CHANGE 2 + +void op_class_pref_apply_regulatory(_adapter *adapter, u8 reason); + +struct rf_ctl_t; +void dump_cap_spt_op_class_ch(void *sel, struct rf_ctl_t *rfctl, bool detail); +void dump_reg_spt_op_class_ch(void *sel, struct rf_ctl_t *rfctl, bool detail); +void dump_cur_spt_op_class_ch(void *sel, struct rf_ctl_t *rfctl, bool detail); + /* * Represent Extention Channel Offset in HT Capabilities * This is available only in 40Mhz mode. @@ -163,6 +221,7 @@ void rf_type_to_default_trx_bmp(enum rf_type rf, enum bb_path *tx, enum bb_path enum rf_type trx_num_to_rf_type(u8 tx_num, u8 rx_num); enum rf_type trx_bmp_to_rf_type(u8 tx_bmp, u8 rx_bmp); bool rf_type_is_a_in_b(enum rf_type a, enum rf_type b); +u8 rtw_restrict_trx_path_bmp_by_trx_num_lmt(u8 trx_path_bmp, u8 tx_num_lmt, u8 rx_num_lmt, u8 *tx_num, u8 *rx_num); u8 rtw_restrict_trx_path_bmp_by_rftype(u8 trx_path_bmp, enum rf_type type, u8 *tx_num, u8 *rx_num); void tx_path_nss_set_default(enum bb_path txpath_nss[], u8 txpath_num_nss[], u8 txpath); void tx_path_nss_set_full_tx(enum bb_path txpath_nss[], u8 txpath_num_nss[], u8 txpath); @@ -180,10 +239,13 @@ typedef enum _REGULATION_TXPWR_LMT { TXPWR_LMT_ETSI = 3, TXPWR_LMT_IC = 4, TXPWR_LMT_KCC = 5, - TXPWR_LMT_ACMA = 6, - TXPWR_LMT_CHILE = 7, - TXPWR_LMT_MEXICO = 8, - TXPWR_LMT_WW = 9, /* smallest of all available limit, keep last */ + TXPWR_LMT_NCC = 6, + TXPWR_LMT_ACMA = 7, + TXPWR_LMT_CHILE = 8, + TXPWR_LMT_UKRAINE = 9, + TXPWR_LMT_MEXICO = 10, + TXPWR_LMT_CN = 11, + TXPWR_LMT_WW, /* smallest of all available limit, keep last */ } REGULATION_TXPWR_LMT; extern const char *const _regd_str[]; diff --git a/include/rtw_rm.h b/include/rtw_rm.h index 9efcf13..8aa2b9d 100644 --- a/include/rtw_rm.h +++ b/include/rtw_rm.h @@ -67,10 +67,18 @@ struct rm_priv { u8 rm_en_cap_def[5]; u8 rm_en_cap_assoc[5]; + u8 meas_token; /* rm debug */ void *prm_sel; }; +#define MAX_CH_NUM_IN_OP_CLASS 11 +typedef struct _RT_OPERATING_CLASS { + int global_op_class; + int Len; + u8 Channel[MAX_CH_NUM_IN_OP_CLASS]; +} RT_OPERATING_CLASS, *PRT_OPERATING_CLASS; + int rtw_init_rm(_adapter *padapter); int rtw_free_rm_priv(_adapter *padapter); @@ -84,5 +92,14 @@ void rm_handler(_adapter *padapter, struct rm_event *pev); u8 rm_add_nb_req(_adapter *padapter, struct sta_info *psta); +/* from ioctl */ +int rm_send_bcn_reqs(_adapter *padapter, u8 *sta_addr, u8 op_class, u8 ch, + u16 measure_duration, u8 measure_mode, u8 *bssid, u8 *ssid, + u8 reporting_detail, + u8 n_ap_ch_rpt, struct _RT_OPERATING_CLASS *rpt, + u8 n_elem_id, u8 *elem_id_list); +void indicate_beacon_report(u8 *sta_addr, + u8 n_measure_rpt, u32 elem_len, u8 *elem); + #endif /*CONFIG_RTW_80211K */ #endif /* __RTW_RM_H_ */ diff --git a/include/rtw_rm_fsm.h b/include/rtw_rm_fsm.h index 503b1ed..bbbb3d9 100644 --- a/include/rtw_rm_fsm.h +++ b/include/rtw_rm_fsm.h @@ -55,13 +55,6 @@ #define RM_GET_AID(rmid) ((rmid&0xffff0000)>>16) #define RM_IS_ID_FOR_ALL(rmid) (rmid&RM_ALL_MEAS) -#define MAX_OP_CHANNEL_SET_NUM 11 -typedef struct _RT_OPERATING_CLASS { - int global_op_class; - int Len; - u16 Channel[MAX_OP_CHANNEL_SET_NUM]; -} RT_OPERATING_CLASS, *PRT_OPERATING_CLASS; - /* IEEE 802.11-2012 Table 8-59 Measurement Type definitions * for measurement request * modify rm_meas_type_req_name() when adding new type @@ -112,7 +105,7 @@ enum bcn_req_opt_sub_id{ bcn_req_rep_info = 1, /* len 2 */ bcn_req_rep_detail = 2, /* len 1 */ bcn_req_req = 10, /* len 0-237 */ - bcn_req_ac_ch_rep = 51 /* len 1-237 */ + bcn_req_ap_ch_rep = 51 /* len 1-237 */ }; /* IEEE 802.11-2012 Table 8-66 Reporting condition of Beacon Report */ @@ -131,16 +124,23 @@ struct opt_rep_info { }; #define BCN_REQ_OPT_MAX_NUM 16 +#define BCN_REQ_REQ_OPT_MAX_NUM 16 +#define BCN_REQ_OPT_AP_CH_RPT_MAX_NUM 12 struct bcn_req_opt { /* all req cmd id */ u8 opt_id[BCN_REQ_OPT_MAX_NUM]; u8 opt_id_num; + u8 req_id_num; + u8 req_id[BCN_REQ_REQ_OPT_MAX_NUM]; u8 rep_detail; NDIS_802_11_SSID ssid; /* bcn report condition */ struct opt_rep_info rep_cond; + u8 ap_ch_rpt_num; + struct _RT_OPERATING_CLASS *ap_ch_rpt[BCN_REQ_OPT_AP_CH_RPT_MAX_NUM]; + /* 0:default(Report to be issued after each measurement) */ u8 *req_start; /*id : 10 request;start */ u8 req_len; /*id : 10 request;length */ @@ -230,7 +230,7 @@ struct rm_meas_req { struct meas_req_opt nhm; }opt; - struct rtw_ieee80211_channel ch_set[MAX_OP_CHANNEL_SET_NUM]; + struct rtw_ieee80211_channel ch_set[RTW_CHANNEL_SCAN_AMOUNT]; u8 ch_set_ch_amount; s8 rx_pwr; /* in dBm */ u8 rx_bw; @@ -284,8 +284,10 @@ struct rm_obj { u64 meas_end_time; int wait_busy; u8 poll_mode; + u8 free_run_counter_valid; /* valid:_SUCCESS/invalid:_FAIL */ struct data_buf buf[MAX_BUF_NUM]; + bool from_ioctl; _list list; }; diff --git a/include/rtw_rm_util.h b/include/rtw_rm_util.h index b4b8867..932cfb9 100644 --- a/include/rtw_rm_util.h +++ b/include/rtw_rm_util.h @@ -28,11 +28,16 @@ u8 rm_get_oper_class_via_ch(u8 ch); u8 rm_get_ch_set( struct rtw_ieee80211_channel *pch_set, u8 op_class, u8 ch_num); +u8 rm_get_ch_set_from_bcn_req_opt( + struct rtw_ieee80211_channel *pch_set, struct bcn_req_opt *opt); u8 rm_get_bcn_rsni(struct rm_obj *prm, struct wlan_network *pnetwork); u8 rm_get_bcn_rcpi(struct rm_obj *prm, struct wlan_network *pnetwork); u8 rm_get_frame_rsni(struct rm_obj *prm, union recv_frame *pframe); u8 translate_percentage_to_rcpi(u32 SignalStrengthIndex); u8 translate_dbm_to_rcpi(s8 SignalPower); +u8 rm_gen_dialog_token(_adapter *padapter); +u8 rm_gen_meas_token(_adapter *padapter); +u32 rm_gen_rmid(_adapter *padapter, struct rm_obj *prm, u8 role); int is_wildcard_bssid(u8 *bssid); int rm_get_path_a_max_tx_power(_adapter *adapter, s8 *path_a); diff --git a/include/rtw_roch.h b/include/rtw_roch.h new file mode 100644 index 0000000..2744f48 --- /dev/null +++ b/include/rtw_roch.h @@ -0,0 +1,61 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2020 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#ifndef __RTW_ROCH_H__ +#define __RTW_ROCH_H__ + +#include + +struct rtw_roch_parm; + +#if (defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)) || defined(CONFIG_IOCTL_CFG80211) +struct roch_info { +#ifdef CONFIG_CONCURRENT_MODE + _timer ap_roch_ch_switch_timer; /* Used to switch the channel between legacy AP and listen state. */ +#ifdef CONFIG_IOCTL_CFG80211 + u32 min_home_dur; /* min duration for traffic, home_time */ + u32 max_away_dur; /* max acceptable away duration, home_away_time */ +#endif +#endif + +#ifdef CONFIG_IOCTL_CFG80211 + _timer remain_on_ch_timer; + u8 restore_channel; + struct ieee80211_channel remain_on_ch_channel; + enum nl80211_channel_type remain_on_ch_type; + ATOMIC_T ro_ch_cookie_gen; + u64 remain_on_ch_cookie; + bool is_ro_ch; + struct wireless_dev *ro_ch_wdev; + systime last_ro_ch_time; /* this will be updated at the beginning and end of ro_ch */ +#endif +}; +#endif + +#ifdef CONFIG_IOCTL_CFG80211 +u8 rtw_roch_stay_in_cur_chan(_adapter *padapter); +#endif + +#if (defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)) || defined(CONFIG_IOCTL_CFG80211) +s32 rtw_roch_wk_hdl(_adapter *padapter, int intCmdType, u8 *buf); +u8 rtw_roch_wk_cmd(_adapter *padapter, int intCmdType, struct rtw_roch_parm *roch_parm, u8 flags); + +#ifdef CONFIG_CONCURRENT_MODE +void rtw_concurrent_handler(_adapter *padapter); +#endif + +void rtw_init_roch_info(_adapter *padapter); +#endif /* (defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)) || defined(CONFIG_IOCTL_CFG80211) */ + +#endif diff --git a/include/rtw_security.h b/include/rtw_security.h index f692220..9cceed6 100644 --- a/include/rtw_security.h +++ b/include/rtw_security.h @@ -15,16 +15,34 @@ #ifndef __RTW_SECURITY_H_ #define __RTW_SECURITY_H_ +enum security_type { + /* TYPE */ + _NO_PRIVACY_ = 0x00, + _WEP40_ = 0x01, + _TKIP_ = 0x02, + _TKIP_WTMIC_ = 0x03, + _AES_ = 0x04, + _WEP104_ = 0x05, + _SMS4_ = 0x06, + _GCMP_ = 0x07, + _SEC_TYPE_MAX_, -#define _NO_PRIVACY_ 0x0 -#define _WEP40_ 0x1 -#define _TKIP_ 0x2 -#define _TKIP_WTMIC_ 0x3 -#define _AES_ 0x4 -#define _WEP104_ 0x5 -#define _SMS4_ 0x06 -#define _WEP_WPA_MIXED_ 0x07 /* WEP + WPA */ -#define _BIP_ 0x8 + /* EXT_SECTYPE=1 */ + _SEC_TYPE_256_ = 0x10, + _CCMP_256_ = (_AES_ | _SEC_TYPE_256_), + _GCMP_256_ = (_GCMP_ | _SEC_TYPE_256_), + +#ifdef CONFIG_IEEE80211W + /* EXT_SECTYPE=0, MGNT=1, GK=0/1, KEYID=00/01 */ + _SEC_TYPE_BIT_ = 0x20, + _BIP_CMAC_128_ = (_SEC_TYPE_BIT_), + _BIP_GMAC_128_ = (_SEC_TYPE_BIT_ + 1), + _BIP_GMAC_256_ = (_SEC_TYPE_BIT_ + 2), + /* EXT_SECTYPE=1, MGNT=1, GK=1, KEYID=00/01 */ + _BIP_CMAC_256_ = (_SEC_TYPE_BIT_ + 3), + _BIP_MAX_, +#endif +}; /* 802.11W use wrong key */ #define IEEE80211W_RIGHT_KEY 0x0 @@ -37,14 +55,13 @@ #define is_wep_enc(alg) (((alg) == _WEP40_) || ((alg) == _WEP104_)) const char *security_type_str(u8 value); +#ifdef CONFIG_IEEE80211W +u32 security_type_bip_to_gmcs(enum security_type type); +#endif #define _WPA_IE_ID_ 0xdd #define _WPA2_IE_ID_ 0x30 -#define SHA256_MAC_LEN 32 -#define AES_BLOCK_SIZE 16 -#define AES_PRIV_SIZE (4 * 44) - #define RTW_KEK_LEN 16 #define RTW_KCK_LEN 16 #define RTW_TKIP_MIC_LEN 8 @@ -105,11 +122,9 @@ struct { }; union Keytype { - u8 skey[16]; - u32 lkey[4]; + u8 skey[32]; }; - typedef struct _RT_PMKID_LIST { u8 bUsed; u8 Bssid[6]; @@ -140,6 +155,7 @@ struct security_priv { union pn48 dot11Grprxpn; /* PN48 used for Grp Key recv. */ u8 iv_seq[4][8]; #ifdef CONFIG_IEEE80211W + enum security_type dot11wCipher; u32 dot11wBIPKeyid; /* key id used for BIP Key ( tx key index) */ union Keytype dot11wBIPKey[6]; /* BIP Key, for index4 and index5 */ union pn48 dot11wBIPtxpn; /* PN48 used for BIP xmit. */ @@ -153,11 +169,10 @@ struct security_priv { unsigned int wpa2_group_cipher; unsigned int wpa_pairwise_cipher; unsigned int wpa2_pairwise_cipher; + unsigned int akmp; /* An authentication and key management protocol */ +#endif u8 mfp_opt; -#endif -#ifdef CONFIG_CONCURRENT_MODE u8 dot118021x_bmc_cam_id; -#endif /*IEEE802.11-2012 Std. Table 8-101 AKM Suite Selectors*/ u32 rsn_akm_suite_type; @@ -242,6 +257,13 @@ struct security_priv { u64 aes_sw_dec_cnt_bc; u64 aes_sw_dec_cnt_mc; u64 aes_sw_dec_cnt_uc; + + u64 gcmp_sw_enc_cnt_bc; + u64 gcmp_sw_enc_cnt_mc; + u64 gcmp_sw_enc_cnt_uc; + u64 gcmp_sw_dec_cnt_bc; + u64 gcmp_sw_dec_cnt_mc; + u64 gcmp_sw_dec_cnt_uc; #endif /* DBG_SW_SEC_CNT */ }; @@ -251,12 +273,6 @@ struct security_priv { #define SEC_IS_BIP_KEY_INSTALLED(sec) _FALSE #endif -struct _sha256_state { - u64 length; - u32 state[8], curlen; - u8 buf[64]; -}; - #define GET_ENCRY_ALGO(psecuritypriv, psta, encry_algo, bmcst)\ do {\ switch (psecuritypriv->dot11AuthAlgrthm) {\ @@ -295,6 +311,15 @@ struct _sha256_state { iv_len = 8;\ icv_len = 8;\ break;\ + case _GCMP_:\ + case _GCMP_256_:\ + iv_len = 8;\ + icv_len = 16;\ + break;\ + case _CCMP_256_:\ + iv_len = 8;\ + icv_len = 16;\ + break;\ case _SMS4_:\ iv_len = 18;\ icv_len = 16;\ @@ -328,132 +353,6 @@ struct mic_data { u32 nBytesInM; /* # bytes in M */ }; -extern const u32 Te0[256]; -extern const u32 Te1[256]; -extern const u32 Te2[256]; -extern const u32 Te3[256]; -extern const u32 Te4[256]; -extern const u32 Td0[256]; -extern const u32 Td1[256]; -extern const u32 Td2[256]; -extern const u32 Td3[256]; -extern const u32 Td4[256]; -extern const u32 rcon[10]; -extern const u8 Td4s[256]; -extern const u8 rcons[10]; - -#define RCON(i) (rcons[(i)] << 24) - -static inline u32 rotr(u32 val, int bits) -{ - return (val >> bits) | (val << (32 - bits)); -} - -#define TE0(i) Te0[((i) >> 24) & 0xff] -#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8) -#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16) -#define TE3(i) rotr(Te0[(i) & 0xff], 24) -#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000) -#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000) -#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00) -#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff) -#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000) -#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000) -#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00) -#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff) -#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff) - -#define TD0(i) Td0[((i) >> 24) & 0xff] -#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8) -#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16) -#define TD3(i) rotr(Td0[(i) & 0xff], 24) -#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24) -#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16) -#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8) -#define TD44(i) (Td4s[(i) & 0xff]) -#define TD0_(i) Td0[(i) & 0xff] -#define TD1_(i) rotr(Td0[(i) & 0xff], 8) -#define TD2_(i) rotr(Td0[(i) & 0xff], 16) -#define TD3_(i) rotr(Td0[(i) & 0xff], 24) - -#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \ - ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) - -#define PUTU32(ct, st) { \ - (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \ - (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } - -#define WPA_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \ - (((u32) (a)[2]) << 8) | ((u32) (a)[3])) - -#define WPA_PUT_LE16(a, val) \ - do { \ - (a)[1] = ((u16) (val)) >> 8; \ - (a)[0] = ((u16) (val)) & 0xff; \ - } while (0) - -#define WPA_PUT_BE32(a, val) \ - do { \ - (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ - (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ - (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ - (a)[3] = (u8) (((u32) (val)) & 0xff); \ - } while (0) - -#define WPA_PUT_BE64(a, val) \ - do { \ - (a)[0] = (u8) (((u64) (val)) >> 56); \ - (a)[1] = (u8) (((u64) (val)) >> 48); \ - (a)[2] = (u8) (((u64) (val)) >> 40); \ - (a)[3] = (u8) (((u64) (val)) >> 32); \ - (a)[4] = (u8) (((u64) (val)) >> 24); \ - (a)[5] = (u8) (((u64) (val)) >> 16); \ - (a)[6] = (u8) (((u64) (val)) >> 8); \ - (a)[7] = (u8) (((u64) (val)) & 0xff); \ - } while (0) - -/* the K array */ -static const unsigned long K[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, - 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, - 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, - 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, - 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, - 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, - 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, - 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, - 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, - 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL -}; - - -/* Various logical functions */ -#define RORc(x, y) \ - (((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \ - ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL) -#define Ch(x, y, z) (z ^ (x & (y ^ z))) -#define Maj(x, y, z) (((x | y) & z) | (x & y)) -#define S(x, n) RORc((x), (n)) -#define R(x, n) (((x) & 0xFFFFFFFFUL)>>(n)) -#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) -#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) -#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) -#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) -#ifndef MIN -#define MIN(x, y) (((x) < (y)) ? (x) : (y)) -#endif -#ifdef CONFIG_IEEE80211W -int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac); -#endif /* CONFIG_IEEE80211W */ -#ifdef CONFIG_RTW_MESH_AEK -int aes_siv_encrypt(const u8 *key, const u8 *pw, size_t pwlen - , size_t num_elem, const u8 *addr[], const size_t *len, u8 *out); -int aes_siv_decrypt(const u8 *key, const u8 *iv_crypt, size_t iv_c_len - , size_t num_elem, const u8 *addr[], const size_t *len, u8 *out); -#endif void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key); void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b); void rtw_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nBytes); @@ -474,9 +373,24 @@ void rtw_wep_encrypt(_adapter *padapter, u8 *pxmitframe); u32 rtw_aes_decrypt(_adapter *padapter, u8 *precvframe); u32 rtw_tkip_decrypt(_adapter *padapter, u8 *precvframe); void rtw_wep_decrypt(_adapter *padapter, u8 *precvframe); + +u32 rtw_gcmp_encrypt(_adapter *padapter, u8 *pxmitframe); +u32 rtw_gcmp_decrypt(_adapter *padapter, u8 *precvframe); + +#ifdef CONFIG_RTW_MESH_AEK +int rtw_aes_siv_encrypt(const u8 *key, size_t key_len, + const u8 *pw, size_t pwlen, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *out); +int rtw_aes_siv_decrypt(const u8 *key, size_t key_len, + const u8 *iv_crypt, size_t iv_c_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *out); +#endif /* CONFIG_RTW_MESH_AEK */ + #ifdef CONFIG_IEEE80211W -u32 rtw_BIP_verify(_adapter *padapter, u8 *whdr_pos, sint flen - , const u8 *key, u16 id, u64* ipn); +u8 rtw_calculate_bip_mic(enum security_type gmcs, u8 *whdr_pos, s32 len, + const u8 *key, const u8 *data, size_t data_len, u8 *mic); +u32 rtw_bip_verify(enum security_type gmcs, u16 pkt_len, + u8 *whdr_pos, sint flen, const u8 *key, u16 keyid, u64 *ipn); #endif #ifdef CONFIG_TDLS void wpa_tdls_generate_tpk(_adapter *padapter, void *sta); @@ -503,3 +417,5 @@ u16 rtw_calc_crc(u8 *pdata, int length); ((a)->securitypriv.auth_type == (s)) #endif /* __RTL871X_SECURITY_H_ */ + +u32 rtw_calc_crc32(u8 *data, size_t len); diff --git a/include/rtw_swcrypto.h b/include/rtw_swcrypto.h new file mode 100644 index 0000000..d35ad7d --- /dev/null +++ b/include/rtw_swcrypto.h @@ -0,0 +1,49 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#ifndef __RTW_SWCRYPTO_H_ +#define __RTW_SWCRYPTO_H_ + +#define NEW_CRYPTO 1 + +int _rtw_ccmp_encrypt(_adapter *padapter, u8 *key, u32 key_len, uint hdrlen, u8 *frame, uint plen); +int _rtw_ccmp_decrypt(_adapter *padapter, u8 *key, u32 key_len, uint hdrlen, u8 *frame, uint plen); + +int _rtw_gcmp_encrypt(_adapter *padapter, u8 *key, u32 key_len, uint hdrlen, u8 *frame, uint plen); +int _rtw_gcmp_decrypt(_adapter *padapter, u8 *key, u32 key_len, uint hdrlen, u8 *frame, uint plen); + +#ifdef CONFIG_RTW_MESH_AEK +int _aes_siv_encrypt(const u8 *key, size_t key_len, + const u8 *pw, size_t pwlen, + size_t num_elem, const u8 *addr[], const size_t *len, u8 *out); +int _aes_siv_decrypt(const u8 *key, size_t key_len, + const u8 *iv_crypt, size_t iv_c_len, + size_t num_elem, const u8 *addr[], const size_t *len, u8 *out); +#endif + +#if defined(CONFIG_IEEE80211W) | defined(CONFIG_TDLS) +u8 _bip_ccmp_protect(const u8 *key, size_t key_len, + const u8 *data, size_t data_len, u8 *mic); +u8 _bip_gcmp_protect(u8 *whdr_pos, size_t len, + const u8 *key, size_t key_len, + const u8 *data, size_t data_len, u8 *mic); +#endif /* CONFIG_IEEE80211W */ + +#ifdef CONFIG_TDLS +void _tdls_generate_tpk(void *sta, const u8 *own_addr, const u8 *bssid); +#endif /* CONFIG_TDLS */ + +#endif /* __RTW_SWCRYPTO_H_ */ + diff --git a/include/rtw_version.h b/include/rtw_version.h index e0dff45..09afbbf 100644 --- a/include/rtw_version.h +++ b/include/rtw_version.h @@ -1,2 +1,2 @@ -#define DRIVERVERSION "v5.8.7.4_37264.20200922_COEX20191120-7777" -#define BTCOEXVERSION "COEX20191120-7777" +#define DRIVERVERSION "v5.13.1-20-gbd7c7eb9d.20210702_COEX20210316-18317b7b" +#define BTCOEXVERSION "COEX20210316-18317b7b" diff --git a/include/rtw_vht.h b/include/rtw_vht.h index 93253b6..f08ac4f 100644 --- a/include/rtw_vht.h +++ b/include/rtw_vht.h @@ -46,7 +46,7 @@ #define SET_VHT_CAPABILITY_ELE_TXOP_PS(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+2, 5, 1, _val) #define SET_VHT_CAPABILITY_ELE_HTC_VHT(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+2, 6, 1, _val) #define SET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(_pEleStart, _val) SET_BITS_TO_LE_2BYTE((_pEleStart)+2, 7, 3, _val) /* B23~B25 */ -#define SET_VHT_CAPABILITY_ELE_LINK_ADAPTION(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+2, 2, 2, _val) +#define SET_VHT_CAPABILITY_ELE_LINK_ADAPTION(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+3, 2, 2, _val) #define SET_VHT_CAPABILITY_ELE_MCS_RX_MAP(_pEleStart, _val) SET_BITS_TO_LE_2BYTE((_pEleStart)+4, 0, 16, _val) /* B0~B15 indicate Rx MCS MAP, we write 0 to indicate MCS0~7. by page */ #define SET_VHT_CAPABILITY_ELE_MCS_RX_HIGHEST_RATE(_pEleStart, _val) SET_BITS_TO_LE_2BYTE((_pEleStart)+6, 0, 13, _val) #define SET_VHT_CAPABILITY_ELE_MCS_TX_MAP(_pEleStart, _val) SET_BITS_TO_LE_2BYTE((_pEleStart)+8, 0, 16, _val) /* B0~B15 indicate Tx MCS MAP, we write 0 to indicate MCS0~7. by page */ @@ -103,10 +103,12 @@ extern const u16 _vht_max_mpdu_len[]; #define VHT_SUP_CH_WIDTH_SET_MAX 3 extern const u8 _vht_sup_ch_width_set_to_bw_cap[]; #define vht_sup_ch_width_set_to_bw_cap(set) (((set) >= VHT_SUP_CH_WIDTH_SET_MAX) ? _vht_sup_ch_width_set_to_bw_cap[VHT_SUP_CH_WIDTH_SET_MAX] : _vht_sup_ch_width_set_to_bw_cap[(set)]) +#define VHT_MAX_AMPDU_LEN(f) ((1 << (13 + f)) - 1) + +#ifdef CONFIG_RTW_DEBUG extern const char *const _vht_sup_ch_width_set_str[]; #define vht_sup_ch_width_set_str(set) (((set) >= VHT_SUP_CH_WIDTH_SET_MAX) ? _vht_sup_ch_width_set_str[VHT_SUP_CH_WIDTH_SET_MAX] : _vht_sup_ch_width_set_str[(set)]) -#define VHT_MAX_AMPDU_LEN(f) ((1 << (13 + f)) - 1) void dump_vht_cap_ie(void *sel, const u8 *ie, u32 ie_len); #define VHT_OP_CH_WIDTH_MAX 4 @@ -114,6 +116,7 @@ extern const char *const _vht_op_ch_width_str[]; #define vht_op_ch_width_str(ch_width) (((ch_width) >= VHT_OP_CH_WIDTH_MAX) ? _vht_op_ch_width_str[VHT_OP_CH_WIDTH_MAX] : _vht_op_ch_width_str[(ch_width)]) void dump_vht_op_ie(void *sel, const u8 *ie, u32 ie_len); +#endif struct vht_bf_cap { u8 is_mu_bfer; diff --git a/include/rtw_wnm.h b/include/rtw_wnm.h new file mode 100644 index 0000000..8d6bcb5 --- /dev/null +++ b/include/rtw_wnm.h @@ -0,0 +1,209 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#ifndef __RTW_WNM_H_ +#define __RTW_WNM_H_ + +#define RTW_RRM_NB_RPT_EN BIT(1) +#define RTW_MAX_NB_RPT_NUM 8 + +#define RTW_WNM_FEATURE_BTM_REQ_EN BIT(0) + +#define rtw_roam_busy_scan(a, nb) \ + (((a)->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE) && \ + (((a)->mlmepriv.ch_cnt) < ((nb)->nb_rpt_ch_list_num))) + +#define rtw_wnm_btm_preference_cap(a) \ + ((a)->mlmepriv.nb_info.preference_en == _TRUE) + +#define rtw_wnm_btm_roam_triggered(a) \ + (((a)->mlmepriv.nb_info.preference_en == _TRUE) \ + && (rtw_ft_chk_flags((a), RTW_FT_BTM_ROAM)) \ + ) + +#define rtw_wnm_btm_diff_bss(a) \ + ((rtw_wnm_btm_preference_cap(a)) && \ + (is_zero_mac_addr((a)->mlmepriv.nb_info.roam_target_addr) == _FALSE) && \ + (_rtw_memcmp((a)->mlmepriv.nb_info.roam_target_addr,\ + (a)->mlmepriv.cur_network.network.MacAddress, ETH_ALEN) == _FALSE)) + +#define rtw_wnm_btm_roam_candidate(a, c) \ + ((rtw_wnm_btm_preference_cap(a)) && \ + (is_zero_mac_addr((a)->mlmepriv.nb_info.roam_target_addr) == _FALSE) && \ + (_rtw_memcmp((a)->mlmepriv.nb_info.roam_target_addr,\ + (c)->network.MacAddress, ETH_ALEN))) + +#define rtw_wnm_set_ext_cap_btm(_pEleStart, _val) \ + SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart))+2, 3, 1, _val) + +#define wnm_btm_bss_term_inc(p) (*((u8 *)((p)+3)) & BSS_TERMINATION_INCLUDED) + +#define wnm_btm_ess_disassoc_im(p) (*((u8 *)((p)+3)) & ESS_DISASSOC_IMMINENT) + +#define wnm_btm_dialog_token(p) (*((u8 *)((p)+2))) + +#define wnm_btm_req_mode(p) (*((u8 *)((p)+3))) + +#define wnm_btm_disassoc_timer(p) (*((u16 *)((p)+4))) + +#define wnm_btm_valid_interval(p) (*((u8 *)((p)+6))) + +#define wnm_btm_term_duration_offset(p) ((p)+7) + +#define wnm_btm_rsp_status(p) (*((u8 *)((p)+3))) + +#define wnm_btm_rsp_term_delay(p) (*((u8 *)((p)+4))) + +#define RTW_WLAN_ACTION_WNM_NB_RPT_ELEM 0x34 + +enum rtw_ieee80211_wnm_actioncode { + RTW_WLAN_ACTION_WNM_BTM_QUERY = 6, + RTW_WLAN_ACTION_WNM_BTM_REQ = 7, + RTW_WLAN_ACTION_WNM_BTM_RSP = 8, + RTW_WLAN_ACTION_WNM_NOTIF_REQ = 26, + RTW_WLAN_ACTION_WNM_NOTIF_RSP = 27, +}; + +/*IEEE Std 80211k Figure 7-95b Neighbor Report element format*/ +struct nb_rpt_hdr { + u8 id; /*0x34: Neighbor Report Element ID*/ + u8 len; + u8 bssid[ETH_ALEN]; + u32 bss_info; + u8 reg_class; + u8 ch_num; + u8 phy_type; +}; + +/*IEEE Std 80211v, Figure 7-9 BSS Termination Duration subelement field format */ +struct btm_term_duration { + u8 id; + u8 len; + u64 tsf; /* value of the TSF counter when BSS termination will occur in the future */ + u16 duration; /* number of minutes for which the BSS is not present*/ +}; + +/*IEEE Std 80211v, Figure 7-10 BSS Transition Management Request frame body format */ +struct btm_req_hdr { + u8 dialog_token; + u8 req_mode; + /* number of TBTTs until the AP sends a Disassociation frame to this STA */ + u16 disassoc_timer; + /* number of TBTTs until the BSS transition candidate list is no longer valid */ + u8 validity_interval; + struct btm_term_duration term_duration; +}; + +struct btm_rsp_hdr { + u8 dialog_token; + u8 status; + /* the number of minutes that + the responding STA requests the BSS to delay termination */ + u8 termination_delay; + u8 bssid[ETH_ALEN]; + u8 *pcandidates; + u32 candidates_num; +}; + +struct btm_rpt_cache { + u8 dialog_token; + u8 req_mode; + u16 disassoc_timer; + u8 validity_interval; + struct btm_term_duration term_duration; + + /* from BTM req */ + u32 validity_time; + u32 disassoc_time; + + systime req_stime; +}; + +/*IEEE Std 80211v, Table 7-43b Optional Subelement IDs for Neighbor Report*/ +/* BSS Transition Candidate Preference */ +#define WNM_BTM_CAND_PREF_SUBEID 0x03 + +/* BSS Termination Duration */ +#define WNM_BTM_TERM_DUR_SUBEID 0x04 + +struct wnm_btm_cant { + struct nb_rpt_hdr nb_rpt; + u8 preference; /* BSS Transition Candidate Preference */ +}; + +enum rtw_btm_req_mod { + PREFERRED_CANDIDATE_LIST_INCLUDED = BIT0, + ABRIDGED = BIT1, + DISASSOC_IMMINENT = BIT2, + BSS_TERMINATION_INCLUDED = BIT3, + ESS_DISASSOC_IMMINENT = BIT4, +}; + +struct roam_nb_info { + struct nb_rpt_hdr nb_rpt[RTW_MAX_NB_RPT_NUM]; + struct rtw_ieee80211_channel nb_rpt_ch_list[RTW_MAX_NB_RPT_NUM]; + struct btm_rpt_cache btm_cache; + bool nb_rpt_valid; + u8 nb_rpt_ch_list_num; + u8 preference_en; + u8 roam_target_addr[ETH_ALEN]; + u32 last_nb_rpt_entries; + u8 nb_rpt_is_same; + s8 disassoc_waiting; + _timer roam_scan_timer; + _timer disassoc_chk_timer; + + u32 features; +}; + +u8 rtw_wnm_btm_reassoc_req(_adapter *padapter); + +void rtw_wnm_roam_scan_hdl(void *ctx); + +void rtw_wnm_disassoc_chk_hdl(void *ctx); + +u8 rtw_wnm_try_btm_roam_imnt(_adapter *padapter); + +void rtw_wnm_process_btm_req(_adapter *padapter, u8* pframe, u32 frame_len); + +void rtw_wnm_reset_btm_candidate(struct roam_nb_info *pnb); + +void rtw_wnm_reset_btm_state(_adapter *padapter); + +u32 rtw_wnm_btm_rsp_candidates_sz_get( + _adapter *padapter, u8* pframe, u32 frame_len); + +void rtw_wnm_process_btm_rsp(_adapter *padapter, + u8* pframe, u32 frame_len, struct btm_rsp_hdr *prsp); + +void rtw_wnm_issue_btm_req(_adapter *padapter, + u8 *pmac, struct btm_req_hdr *phdr, u8 *purl, u32 url_len, + u8 *pcandidates, u8 candidate_cnt); + +void rtw_wnm_reset_btm_cache(_adapter *padapter); + +void rtw_wnm_issue_action(_adapter *padapter, u8 action, u8 reason, u8 dialog); + +void rtw_wnm_update_reassoc_req_ie(_adapter *padapter); + +void rtw_roam_nb_info_init(_adapter *padapter); + +u8 rtw_roam_nb_scan_list_set(_adapter *padapter, + struct sitesurvey_parm *pparm); + +u32 rtw_wnm_btm_candidates_survey(_adapter *padapter, + u8* pframe, u32 elem_len, u8 is_preference); +#endif /* __RTW_WNM_H_ */ + diff --git a/include/rtw_xmit.h b/include/rtw_xmit.h index beed985..2f19c9c 100644 --- a/include/rtw_xmit.h +++ b/include/rtw_xmit.h @@ -24,8 +24,6 @@ #else #define MAX_XMITBUF_SZ (32764) #endif - #elif defined(CONFIG_RTL8822B) - #define MAX_XMITBUF_SZ (31744) /* ~32k */ #else #define MAX_XMITBUF_SZ (20480) /* 20k */ #endif @@ -100,6 +98,8 @@ #define MAX_CMDBUF_SZ (512 * 18) #elif defined(CONFIG_RTL8723D) && defined(CONFIG_LPS_POFF) #define MAX_CMDBUF_SZ (128*70) /*(8960)*/ +#elif defined(CONFIG_RTL8822C) && defined(CONFIG_WAR_OFFLOAD) + #define MAX_CMDBUF_SZ (128*128) /*(16k) */ #else #define MAX_CMDBUF_SZ (5120) /* (4096) */ #endif @@ -119,10 +119,16 @@ #define BK_QUEUE_INX 3 #define BCN_QUEUE_INX 4 #define MGT_QUEUE_INX 5 -#define HIGH_QUEUE_INX 6 -#define TXCMD_QUEUE_INX 7 +#define TXCMD_QUEUE_INX 6 +#define HIGH_QUEUE_INX 7 +/* keep high queue to be the last one, so we can extend HIQ to port 1, 2, ... */ +#ifndef CONFIG_PORT_BASED_HIQ #define HW_QUEUE_ENTRY 8 +#else +#define HI_QUEUE_INX(n) (HIGH_QUEUE_INX + (n)) +#define HW_QUEUE_ENTRY (8 + CONFIG_IFACE_NUMBER - 1) +#endif #ifdef CONFIG_PCI_HCI #ifdef CONFIG_TRX_BD_ARCH @@ -168,6 +174,8 @@ pattrib_iv[7] = dot11txpn._byte_.TSC5;\ } while (0) +#define GCMP_IV(a, b, c) AES_IV(a, b, c) + /* Check if AMPDU Tx is supported or not. If it is supported, * it need to check "amsdu in ampdu" is supported or not. * (ampdu_en, amsdu_ampdu_en) = @@ -181,7 +189,11 @@ #define IS_AMSDU_AMPDU_VALID(pattrib)\ !((pattrib->ampdu_en == _TRUE) && (pattrib->amsdu_ampdu_en == _FALSE)) -#define HWXMIT_ENTRY 4 +#ifdef CONFIG_RTW_MGMT_QUEUE +#define HWXMIT_ENTRY 5 +#else +#define HWXMIT_ENTRY 4 +#endif /* For Buffer Descriptor ring architecture */ #if defined(BUF_DESC_ARCH) || defined(CONFIG_TRX_BD_ARCH) @@ -198,7 +210,8 @@ defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8192E) ||\ defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8703B) ||\ defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) || defined(CONFIG_RTL8723D) ||\ - defined(CONFIG_RTL8710B) || defined(CONFIG_RTL8192F) + defined(CONFIG_RTL8710B) || defined(CONFIG_RTL8192F) ||\ + defined(CONFIG_RTL8723F) #define TXDESC_SIZE 40 #elif defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8822C) #define TXDESC_SIZE 48 /* HALMAC_TX_DESC_SIZE_8822B */ @@ -255,7 +268,7 @@ enum TXDESC_SC { #endif #elif defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8723B) \ || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) || defined(CONFIG_RTL8723D) \ - || defined(CONFIG_RTL8192F) + || defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8723F) #define TXDESC_40_BYTES #endif @@ -320,7 +333,7 @@ union txdesc { #endif #ifdef CONFIG_PCI_HCI -#define PCI_MAX_TX_QUEUE_COUNT 8 /* == HW_QUEUE_ENTRY */ +#define PCI_MAX_TX_QUEUE_COUNT HW_QUEUE_ENTRY struct rtw_tx_ring { unsigned char qid; @@ -364,54 +377,6 @@ struct hw_xmit { int accnt; }; -#if 0 -struct pkt_attrib { - u8 type; - u8 subtype; - u8 bswenc; - u8 dhcp_pkt; - u16 ether_type; - int pktlen; /* the original 802.3 pkt raw_data len (not include ether_hdr data) */ - int pkt_hdrlen; /* the original 802.3 pkt header len */ - int hdrlen; /* the WLAN Header Len */ - int nr_frags; - int last_txcmdsz; - int encrypt; /* when 0 indicate no encrypt. when non-zero, indicate the encrypt algorith */ - u8 iv[8]; - int iv_len; - u8 icv[8]; - int icv_len; - int priority; - int ack_policy; - int mac_id; - int vcs_mode; /* virtual carrier sense method */ - - u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; - u8 ta[ETH_ALEN]; - u8 ra[ETH_ALEN]; - - u8 key_idx; - - u8 qos_en; - u8 ht_en; - u8 raid;/* rate adpative id */ - u8 bwmode; - u8 ch_offset;/* PRIME_CHNL_OFFSET */ - u8 sgi;/* short GI */ - u8 ampdu_en;/* tx ampdu enable */ - u8 mdata;/* more data bit */ - u8 eosp; - - u8 triggered;/* for ap mode handling Power Saving sta */ - - u32 qsel; - u16 seqnum; - - struct sta_info *psta; -}; -#else -/* reduce size */ struct pkt_attrib { u8 type; u8 subtype; @@ -426,9 +391,7 @@ struct pkt_attrib { u32 last_txcmdsz; u8 nr_frags; u8 encrypt; /* when 0 indicate no encrypt. when non-zero, indicate the encrypt algorith */ -#if defined(CONFIG_CONCURRENT_MODE) u8 bmc_camid; -#endif u8 iv_len; u8 icv_len; u8 iv[18]; @@ -441,6 +404,9 @@ struct pkt_attrib { u8 src[ETH_ALEN]; u8 ta[ETH_ALEN]; u8 ra[ETH_ALEN]; +#ifdef CONFIG_RTW_WDS + u8 wds; +#endif #ifdef CONFIG_RTW_MESH u8 mda[ETH_ALEN]; /* mesh da */ u8 msa[ETH_ALEN]; /* mesh sa */ @@ -512,7 +478,15 @@ struct pkt_attrib { u8 bf_pkt_type; #endif +#ifdef CONFIG_RTW_MGMT_QUEUE + u8 ps_dontq; /* 1: this frame can't be queued at PS state */ +#endif }; + +#ifdef CONFIG_RTW_WDS +#define XATTRIB_GET_WDS(xattrib) ((xattrib)->wds) +#else +#define XATTRIB_GET_WDS(xattrib) 0 #endif #ifdef CONFIG_RTW_MESH @@ -651,6 +625,7 @@ struct xmit_frame { struct pkt_attrib attrib; + u16 os_qid; _pkt *pkt; int frame_tag; @@ -700,6 +675,10 @@ struct sta_xmit_priv { struct tx_servq bk_q; /* priority == 1,2 */ struct tx_servq vi_q; /* priority == 4,5 */ struct tx_servq vo_q; /* priority == 6,7 */ +#ifdef CONFIG_RTW_MGMT_QUEUE + struct tx_servq mgmt_q; +#endif + _list legacy_dz; _list apsd; @@ -748,7 +727,7 @@ struct xmit_priv { _queue bk_pending; _queue vi_pending; _queue vo_pending; - _queue bm_pending; + _queue mgmt_pending; /* _queue legacy_dz_queue; */ /* _queue apsd_queue; */ @@ -855,6 +834,9 @@ struct xmit_priv { _mutex ack_tx_mutex; struct submit_ctx ack_tx_ops; u8 seq_no; +#ifdef CONFIG_REMOVE_DUP_TX_STATE + u8 retry_count; +#endif #endif #ifdef CONFIG_TX_AMSDU @@ -881,6 +863,9 @@ struct xmit_priv { #endif #ifdef CONFIG_PCI_TX_POLLING _timer tx_poll_timer; +#endif +#ifdef CONFIG_LAYER2_ROAMING + _queue rpkt_queue; #endif _lock lock_sctx; @@ -945,13 +930,20 @@ extern void rtw_update_protection(_adapter *padapter, u8 *ie, uint ie_len); extern s32 rtw_make_wlanhdr(_adapter *padapter, u8 *hdr, struct pkt_attrib *pattrib); extern s32 rtw_put_snap(u8 *data, u16 h_proto); -extern struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv); +extern struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv, u16 os_qid); struct xmit_frame *rtw_alloc_xmitframe_ext(struct xmit_priv *pxmitpriv); struct xmit_frame *rtw_alloc_xmitframe_once(struct xmit_priv *pxmitpriv); extern s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe); extern void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue); struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, sint up, u8 *ac); extern s32 rtw_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); + +#ifdef CONFIG_RTW_MGMT_QUEUE +void rtw_free_mgmt_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *mgmt_queue); +u8 rtw_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +struct xmit_frame *rtw_dequeue_mgmt_xframe(struct xmit_priv *pxmitpriv); +#endif /* CONFIG_RTW_MGMT_QUEUE */ + extern struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, sint entry); extern s32 rtw_xmit_classifier(_adapter *padapter, struct xmit_frame *pxmitframe); @@ -988,9 +980,12 @@ void rtw_xmit_dequeue_callback(_workitem *work); void rtw_xmit_queue_set(struct sta_info *sta); void rtw_xmit_queue_clear(struct sta_info *sta); s32 rtw_xmit_posthandle(_adapter *padapter, struct xmit_frame *pxmitframe, _pkt *pkt); -s32 rtw_xmit(_adapter *padapter, _pkt **pkt); +s32 rtw_xmit(_adapter *padapter, _pkt **pkt, u16 os_qid); bool xmitframe_hiq_filter(struct xmit_frame *xmitframe); #if defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS) +#ifdef CONFIG_RTW_MGMT_QUEUE +u8 mgmt_xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe); void stop_sta_xmit(_adapter *padapter, struct sta_info *psta); void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta); @@ -1002,8 +997,10 @@ u8 rtw_get_tx_bw_mode(_adapter *adapter, struct sta_info *sta); void rtw_update_tx_rate_bmp(struct dvobj_priv *dvobj); u8 rtw_get_tx_bw_bmp_of_ht_rate(struct dvobj_priv *dvobj, u8 rate, u8 max_bw); u8 rtw_get_tx_bw_bmp_of_vht_rate(struct dvobj_priv *dvobj, u8 rate, u8 max_bw); -s16 rtw_adapter_get_oper_txpwr_max_mbm(_adapter *adapter); -s16 rtw_get_oper_txpwr_max_mbm(struct dvobj_priv *dvobj); +s16 rtw_adapter_get_oper_txpwr_max_mbm(_adapter *adapter, bool eirp); +s16 rtw_rfctl_get_oper_txpwr_max_mbm(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, u8 ifbmp_mod, u8 if_op, bool eirp); +s16 rtw_get_oper_txpwr_max_mbm(struct dvobj_priv *dvobj, bool erip); +s16 rtw_rfctl_get_reg_max_txpwr_mbm(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, bool eirp); u8 query_ra_short_GI(struct sta_info *psta, u8 bw); diff --git a/include/sdio_ops.h b/include/sdio_ops.h index 29f795d..74ddeca 100644 --- a/include/sdio_ops.h +++ b/include/sdio_ops.h @@ -73,7 +73,8 @@ void ClearInterrupt8821AS(PADAPTER padapter); #endif /* CONFIG_RTL8821A */ #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) -#if defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8822C) +#if defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8822C) \ + || defined(CONFIG_RTL8723F) u8 rtw_hal_enable_cpwm2(_adapter *adapter); #endif extern u8 RecvOnePkt(PADAPTER padapter); diff --git a/include/sta_info.h b/include/sta_info.h index 351125d..f3c8f36 100644 --- a/include/sta_info.h +++ b/include/sta_info.h @@ -21,7 +21,11 @@ #define NUM_STA MACID_NUM_SW_LIMIT #ifndef CONFIG_RTW_MACADDR_ACL + #ifdef CONFIG_AP_MODE #define CONFIG_RTW_MACADDR_ACL 1 + #else + #define CONFIG_RTW_MACADDR_ACL 0 + #endif #endif #ifndef CONFIG_RTW_PRE_LINK_STA @@ -278,6 +282,10 @@ struct sta_info { #endif _queue sleep_q; unsigned int sleepq_len; +#ifdef CONFIG_RTW_MGMT_QUEUE + _queue mgmt_sleep_q; + unsigned int mgmt_sleepq_len; +#endif uint state; uint qos_option; @@ -288,6 +296,7 @@ struct sta_info { u8 rm_diag_token; #endif /* CONFIG_RTW_80211K */ + systime resp_nonenc_eapol_key_starttime; uint ieee8021x_blocked; /* 0: allowed, 1:blocked */ uint dot118021XPrivacy; /* aes, tkip... */ union Keytype dot11tkiptxmickey; @@ -295,6 +304,7 @@ struct sta_info { union Keytype dot118021x_UncstKey; union pn48 dot11txpn; /* PN48 used for Unicast xmit */ union pn48 dot11rxpn; /* PN48 used for Unicast recv. */ + ATOMIC_T keytrack; #ifdef CONFIG_RTW_MESH /* peer's GTK, RX only */ u8 group_privacy; @@ -303,6 +313,7 @@ struct sta_info { union pn48 gtk_pn; #ifdef CONFIG_IEEE80211W /* peer's IGTK, RX only */ + enum security_type dot11wCipher; u8 igtk_bmp; u8 igtk_id; union Keytype igtk; @@ -382,6 +393,10 @@ struct sta_info { unsigned int expire_to; + int flags; + + u8 bpairwise_key_installed; + #ifdef CONFIG_AP_MODE _list asoc_list; @@ -392,7 +407,6 @@ struct sta_info { unsigned char chg_txt[128]; u16 capability; - int flags; int dot8021xalg;/* 0:disable, 1:psk, 2:802.1x */ int wpa_psk;/* 0:disable, bit(0): WPA, bit(1):WPA2 */ @@ -403,7 +417,6 @@ struct sta_info { u32 akm_suite_type; - u8 bpairwise_key_installed; #ifdef CONFIG_RTW_80211R u8 ft_pairwise_key_installed; #endif @@ -456,9 +469,9 @@ struct sta_info { u8 op_wfd_mode; #endif -#ifdef CONFIG_TX_MCAST2UNI +#if !defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && defined(CONFIG_80211N_HT) u8 under_exist_checking; -#endif /* CONFIG_TX_MCAST2UNI */ +#endif u8 keep_alive_trycnt; @@ -504,6 +517,11 @@ struct sta_info { bool vendor_8812; #endif +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + u8 tbtx_enable; /* Does this sta_info support & enable TBTX function? */ +// u8 tbtx_timeslot; /* This sta_info belong to which time slot. */ +#endif + /* * Vaiables for queuing TX pkt a short period of time * to wait something ready. @@ -693,7 +711,12 @@ struct sta_priv { #if CONFIG_RTW_PRE_LINK_STA struct pre_link_sta_ctl_t pre_link_sta_ctl; #endif - +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + u8 tbtx_asoc_list_cnt; + struct sta_info *token_holder[NR_MAXSTA_INSLOT]; + struct sta_info *last_token_holder; + ATOMIC_T nr_token_keeper; +#endif #endif /* CONFIG_AP_MODE */ #ifdef CONFIG_ATMEL_RC_PATCH diff --git a/include/wifi.h b/include/wifi.h index def77a4..d07b349 100644 --- a/include/wifi.h +++ b/include/wifi.h @@ -19,6 +19,9 @@ #ifndef BIT #define BIT(x) (1 << (x)) #endif +#ifndef BIT_ULL +#define BIT_ULL(x) (1ULL << (x)) +#endif #define WLAN_ETHHDR_LEN 14 @@ -61,6 +64,10 @@ #endif #endif +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +#define WLAN_MAX_KEEP_ALIVE_IE_LEN 256 +#endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + #define P80211CAPTURE_VERSION 0x80211001 /* This value is tested by WiFi 11n Test Plan 5.2.3. @@ -297,7 +304,7 @@ enum WIFI_REG_DOMAIN { *(unsigned short *)(pbuf) &= (~cpu_to_le16(_FROM_DS_)); \ } while (0) -#define get_tofr_ds(pframe) ((GetToDs(pframe) << 1) | GetFrDs(pframe)) +#define get_tofr_ds(pframe) ((GetFrDs(pframe) << 1) | GetToDs(pframe)) #define SetMFrag(pbuf) \ @@ -473,18 +480,18 @@ __inline static unsigned char *get_ta(unsigned char *pframe) __inline static unsigned char *get_da(unsigned char *pframe) { unsigned char *da; - unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); + unsigned int to_fr_ds = (GetFrDs(pframe) << 1) | GetToDs(pframe); switch (to_fr_ds) { case 0x00: /* ToDs=0, FromDs=0 */ da = GetAddr1Ptr(pframe); break; - case 0x01: /* ToDs=0, FromDs=1 */ - da = GetAddr1Ptr(pframe); - break; - case 0x02: /* ToDs=1, FromDs=0 */ + case 0x01: /* ToDs=1, FromDs=0 */ da = GetAddr3Ptr(pframe); break; + case 0x02: /* ToDs=0, FromDs=1 */ + da = GetAddr1Ptr(pframe); + break; default: /* ToDs=1, FromDs=1 */ da = GetAddr3Ptr(pframe); break; @@ -497,18 +504,18 @@ __inline static unsigned char *get_da(unsigned char *pframe) __inline static unsigned char *get_sa(unsigned char *pframe) { unsigned char *sa; - unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); + unsigned int to_fr_ds = (GetFrDs(pframe) << 1) | GetToDs(pframe); switch (to_fr_ds) { case 0x00: /* ToDs=0, FromDs=0 */ sa = get_addr2_ptr(pframe); break; - case 0x01: /* ToDs=0, FromDs=1 */ - sa = GetAddr3Ptr(pframe); - break; - case 0x02: /* ToDs=1, FromDs=0 */ + case 0x01: /* ToDs=1, FromDs=0 */ sa = get_addr2_ptr(pframe); break; + case 0x02: /* ToDs=0, FromDs=1 */ + sa = GetAddr3Ptr(pframe); + break; default: /* ToDs=1, FromDs=1 */ sa = GetAddr4Ptr(pframe); break; @@ -520,25 +527,25 @@ __inline static unsigned char *get_sa(unsigned char *pframe) /* can't apply to mesh mode */ __inline static unsigned char *get_hdr_bssid(unsigned char *pframe) { - unsigned char *sa = NULL; - unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); + unsigned char *bssid= NULL; + unsigned int to_fr_ds = (GetFrDs(pframe) << 1) | GetToDs(pframe); switch (to_fr_ds) { case 0x00: /* ToDs=0, FromDs=0 */ - sa = GetAddr3Ptr(pframe); + bssid = GetAddr3Ptr(pframe); break; - case 0x01: /* ToDs=0, FromDs=1 */ - sa = get_addr2_ptr(pframe); + case 0x01: /* ToDs=1, FromDs=0 */ + bssid = GetAddr1Ptr(pframe); break; - case 0x02: /* ToDs=1, FromDs=0 */ - sa = GetAddr1Ptr(pframe); + case 0x02: /* ToDs=0, FromDs=1 */ + bssid = get_addr2_ptr(pframe); break; case 0x03: /* ToDs=1, FromDs=1 */ - sa = GetAddr1Ptr(pframe); + bssid = GetAddr1Ptr(pframe); break; } - return sa; + return bssid; } @@ -731,19 +738,24 @@ typedef enum _ELEMENT_ID { #define WLAN_ETHCONV_ENCAP 1 #define WLAN_ETHCONV_RFC1042 2 -#define WLAN_ETHCONV_8021h 3 +#define WLAN_ETHCONV_8021h 3 -#define cap_ESS BIT(0) -#define cap_IBSS BIT(1) -#define cap_CFPollable BIT(2) -#define cap_CFRequest BIT(3) -#define cap_Privacy BIT(4) -#define cap_ShortPremble BIT(5) -#define cap_PBCC BIT(6) -#define cap_ChAgility BIT(7) -#define cap_SpecMgmt BIT(8) -#define cap_QoS BIT(9) -#define cap_ShortSlot BIT(10) +#define cap_ESS BIT(0) +#define cap_IBSS BIT(1) +#define cap_CFPollable BIT(2) +#define cap_CFRequest BIT(3) +#define cap_Privacy BIT(4) +#define cap_ShortPremble BIT(5) +#define cap_PBCC BIT(6) +#define cap_ChAgility BIT(7) +#define cap_SpecMgmt BIT(8) +#define cap_QoS BIT(9) +#define cap_ShortSlot BIT(10) +#define cap_APSD BIT(11) +#define cap_RM BIT(12) +#define cap_DSSSOFDM BIT(13) +#define cap_DelayedBACK BIT(14) +#define cap_ImmediateBACK BIT(15) /*----------------------------------------------------------------------------- Below is the definition for 802.11i / 802.1x @@ -761,7 +773,7 @@ typedef enum _ELEMENT_ID { #define _WEP_WPA_MIXED_PRIVACY_ 6 /* WEP + WPA */ #endif -#define _MME_IE_LENGTH_ 18 +#define _MME_IE_LENGTH_ 26 /*----------------------------------------------------------------------------- Below is the definition for WMM @@ -1271,9 +1283,6 @@ enum P2P_PROTO_WK_ID { P2P_PRE_TX_PROVDISC_PROCESS_WK = 2, P2P_PRE_TX_NEGOREQ_PROCESS_WK = 3, P2P_PRE_TX_INVITEREQ_PROCESS_WK = 4, - P2P_AP_P2P_CH_SWITCH_PROCESS_WK = 5, - P2P_RO_CH_WK = 6, - P2P_CANCEL_RO_CH_WK = 7, }; #ifdef CONFIG_P2P_PS @@ -1316,6 +1325,12 @@ enum P2P_PS_MODE { #define IP_MCAST_MAC(mac) ((mac[0] == 0x01) && (mac[1] == 0x00) && (mac[2] == 0x5e)) #define ICMPV6_MCAST_MAC(mac) ((mac[0] == 0x33) && (mac[1] == 0x33) && (mac[2] != 0xff)) +enum RTW_ROCH_WK_ID{ + ROCH_RO_CH_WK, + ROCH_CANCEL_RO_CH_WK, + ROCH_AP_ROCH_CH_SWITCH_PROCESS_WK, +}; + #ifdef CONFIG_IOCTL_CFG80211 /* Regulatroy Domain */ struct regd_pair_mapping { diff --git a/include/wlan_bssdef.h b/include/wlan_bssdef.h index c8f3229..38de05c 100644 --- a/include/wlan_bssdef.h +++ b/include/wlan_bssdef.h @@ -242,6 +242,9 @@ typedef struct _WLAN_BSSID_EX { WLAN_PHY_INFO PhyInfo; u32 IELength; u8 IEs[MAX_IE_SZ]; /* (timestamp, beacon interval, and capability information) */ +#ifdef CONFIG_LAYER2_ROAMING + u64 tsf; +#endif } __attribute__((packed)) WLAN_BSSID_EX, *PWLAN_BSSID_EX; diff --git a/include/xmit_osdep.h b/include/xmit_osdep.h index f82798f..9bf9c93 100644 --- a/include/xmit_osdep.h +++ b/include/xmit_osdep.h @@ -68,8 +68,7 @@ struct xmit_frame; struct xmit_buf; extern int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev); -extern inline netdev_tx_t rtw_xmit_entry(struct sk_buff *pkt, - struct net_device *pnetdev); +extern int rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev); #endif /* PLATFORM_LINUX */ @@ -88,6 +87,8 @@ extern sint rtw_endofpktfile(struct pkt_file *pfile); extern void rtw_os_pkt_complete(_adapter *padapter, _pkt *pkt); extern void rtw_os_xmit_complete(_adapter *padapter, struct xmit_frame *pxframe); +void rtw_os_check_wakup_queue(_adapter *adapter, u16 os_qid); +bool rtw_os_check_stop_queue(_adapter *adapter, u16 os_qid); void rtw_os_wake_queue_at_free_stainfo(_adapter *padapter, int *qcnt_freed); void dump_os_queue(void *sel, _adapter *padapter); diff --git a/os_dep/linux/ioctl_cfg80211.c b/os_dep/linux/ioctl_cfg80211.c old mode 100755 new mode 100644 index cca3aab..07a4496 --- a/os_dep/linux/ioctl_cfg80211.c +++ b/os_dep/linux/ioctl_cfg80211.c @@ -79,14 +79,18 @@ #endif #endif +#define WIFI_CIPHER_SUITE_GCMP 0x000FAC08 +#define WIFI_CIPHER_SUITE_GCMP_256 0x000FAC09 +#define WIFI_CIPHER_SUITE_CCMP_256 0x000FAC0A +#define WIFI_CIPHER_SUITE_BIP_GMAC_128 0x000FAC0B +#define WIFI_CIPHER_SUITE_BIP_GMAC_256 0x000FAC0C +#define WIFI_CIPHER_SUITE_BIP_CMAC_256 0x000FAC0D + /* - * In the current design of Wi-Fi driver, it will return success to the system (e.g. supplicant) - * when Wi-Fi driver decides to abort the scan request in the scan flow by default. - * Defining this flag makes Wi-Fi driver to return -EBUSY to the system if Wi-Fi driver is too busy to do the scan. + * If customer need, defining this flag will make driver + * always return -EBUSY at the condition of scan deny. */ -#ifndef CONFIG_NOTIFY_SCAN_ABORT_WITH_BUSY - #define CONFIG_NOTIFY_SCAN_ABORT_WITH_BUSY 0 -#endif +/* #define CONFIG_NOTIFY_SCAN_ABORT_WITH_BUSY */ static const u32 rtw_cipher_suites[] = { WLAN_CIPHER_SUITE_WEP40, @@ -98,6 +102,12 @@ static const u32 rtw_cipher_suites[] = { #endif /* CONFIG_WAPI_SUPPORT */ #ifdef CONFIG_IEEE80211W WLAN_CIPHER_SUITE_AES_CMAC, + WIFI_CIPHER_SUITE_GCMP, + WIFI_CIPHER_SUITE_GCMP_256, + WIFI_CIPHER_SUITE_CCMP_256, + WIFI_CIPHER_SUITE_BIP_GMAC_128, + WIFI_CIPHER_SUITE_BIP_GMAC_256, + WIFI_CIPHER_SUITE_BIP_CMAC_256, #endif /* CONFIG_IEEE80211W */ }; @@ -114,7 +124,7 @@ static const u32 rtw_cipher_suites[] = { .hw_value = (_channel), \ .flags = (_flags), \ .max_antenna_gain = 0, \ - .max_power = 30, \ + .max_power = 0, \ } #define CHAN5G(_channel, _flags) { \ @@ -123,7 +133,7 @@ static const u32 rtw_cipher_suites[] = { .hw_value = (_channel), \ .flags = (_flags), \ .max_antenna_gain = 0, \ - .max_power = 30, \ + .max_power = 0, \ } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) @@ -202,6 +212,8 @@ static u8 rtw_chbw_to_cfg80211_chan_def(struct wiphy *wiphy, struct cfg80211_cha struct ieee80211_channel *chan; u8 ret = _FAIL; + _rtw_memset(chdef, 0, sizeof(*chdef)); + freq = rtw_ch2freq(ch); if (!freq) goto exit; @@ -225,6 +237,12 @@ static u8 rtw_chbw_to_cfg80211_chan_def(struct wiphy *wiphy, struct cfg80211_cha chdef->width = NL80211_CHAN_WIDTH_80; else if (bw == CHANNEL_WIDTH_160) chdef->width = NL80211_CHAN_WIDTH_160; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) + else if (bw == CHANNEL_WIDTH_5) + chdef->width = NL80211_CHAN_WIDTH_5; + else if (bw == CHANNEL_WIDTH_10) + chdef->width = NL80211_CHAN_WIDTH_10; +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) */ else { rtw_warn_on(1); goto exit; @@ -232,12 +250,6 @@ static u8 rtw_chbw_to_cfg80211_chan_def(struct wiphy *wiphy, struct cfg80211_cha chdef->chan = chan; chdef->center_freq1 = cfreq; - chdef->center_freq2 = 0; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) - chdef->edmg.bw_config = 0; - chdef->edmg.channels = 0; -#endif ret = _SUCCESS; @@ -434,7 +446,7 @@ u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, u8 ret = _SUCCESS; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) - struct cfg80211_chan_def chdef = {}; + struct cfg80211_chan_def chdef; ret = rtw_chbw_to_cfg80211_chan_def(wiphy, &chdef, ch, bw, offset, ht); if (ret != _SUCCESS) @@ -442,11 +454,20 @@ u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) if (started) { - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)) + + /* --- cfg80211_ch_switch_started_notfiy() --- + * A new parameter, bool quiet, is added from Linux kernel v5.11, + * to see if block-tx was requested by the AP. since currently, + * the API is used for station before connected in rtw_chk_start_clnt_join() + * the quiet is set to false here first. May need to refine it if + * called by others with block-tx. + */ + cfg80211_ch_switch_started_notify(adapter->pnetdev, &chdef, 0, false); - #else +#else cfg80211_ch_switch_started_notify(adapter->pnetdev, &chdef, 0); - #endif +#endif goto exit; } #endif @@ -529,18 +550,7 @@ struct ieee80211_supported_band *rtw_spt_band_alloc(BAND_TYPE band) spt_band->n_channels = n_channels; spt_band->n_bitrates = n_bitrates; - if (band == BAND_ON_2_4G) { - rtw_2g_channels_init(spt_band->channels); - rtw_2g_rates_init(spt_band->bitrates); - } else if (band == BAND_ON_5G) { - rtw_5g_channels_init(spt_band->channels); - rtw_5g_rates_init(spt_band->bitrates); - } - - /* spt_band.ht_cap */ - exit: - return spt_band; } @@ -657,8 +667,10 @@ NDIS_802_11_NETWORK_INFRASTRUCTURE nl80211_iftype_to_rtw_network_type(enum nl802 return Ndis802_11_mesh; #endif +#ifdef CONFIG_WIFI_MONITOR case NL80211_IFTYPE_MONITOR: return Ndis802_11Monitor; +#endif /* CONFIG_WIFI_MONITOR */ default: return Ndis802_11InfrastructureMax; @@ -840,7 +852,7 @@ struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_net notify_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_; /* We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm) */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE && is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) { notify_signal = 100 * translate_percentage_to_dbm(padapter->recvpriv.signal_strength); /* dbm */ } else { @@ -941,35 +953,6 @@ exit: } -/* - * Return _TRUE if netwrok is valid in wdev, otherwise _FALSE for not found. - */ -static int _cfg80211_check_bss(struct _ADAPTER *a) -{ - struct wireless_dev *wdev; - struct _WLAN_BSSID_EX *network; - - - wdev = a->rtw_wdev; - network = &a->mlmeextpriv.mlmext_info.network; - - if ((!wdev->ssid_len) || (wdev->ssid_len != network->Ssid.SsidLength) - || (_rtw_memcmp(wdev->ssid, network->Ssid.Ssid, - network->Ssid.SsidLength) == _FALSE)) { - RTW_PRINT(FUNC_ADPT_FMT ": bssid:"MAC_FMT"\n", - FUNC_ADPT_ARG(a), MAC_ARG(network->MacAddress)); - RTW_PRINT(FUNC_ADPT_FMT ": ssid:[%s] len=%d\n", - FUNC_ADPT_ARG(a), network->Ssid.Ssid, - network->Ssid.SsidLength); - RTW_PRINT(FUNC_ADPT_FMT ": (wdev) ssid:[%s] len=%d\n", - FUNC_ADPT_ARG(a), wdev->ssid, wdev->ssid_len); - - return _FALSE; - } - - return _TRUE; -} - /* Check the given bss is valid by kernel API cfg80211_get_bss() @padapter : the given adapter @@ -1072,7 +1055,7 @@ void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter) #endif } -int rtw_cfg80211_indicate_connect(_adapter *padapter) +void rtw_cfg80211_indicate_connect(_adapter *padapter) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *cur_network = &(pmlmepriv->cur_network); @@ -1092,10 +1075,10 @@ int rtw_cfg80211_indicate_connect(_adapter *padapter) && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT #endif ) - return 0; + return; if (!MLME_IS_STA(padapter)) - return 0; + return; #ifdef CONFIG_P2P if (pwdinfo->driver_interface == DRIVER_CFG80211) { @@ -1139,17 +1122,6 @@ int rtw_cfg80211_indicate_connect(_adapter *padapter) } check_bss: - if (_cfg80211_check_bss(padapter) == _FALSE) { - RTW_ERR(FUNC_ADPT_FMT ": BSS not found!! Skip!\n", - FUNC_ADPT_ARG(padapter)); - - _enter_critical_bh(&pwdev_priv->connect_req_lock, &irqL); - rtw_wdev_free_connect_req(pwdev_priv); - _exit_critical_bh(&pwdev_priv->connect_req_lock, &irqL); - - return -1; - } - if (!rtw_cfg80211_check_bss(padapter)) RTW_PRINT(FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter)); @@ -1213,8 +1185,6 @@ check_bss: rtw_wdev_free_connect_req(pwdev_priv); _exit_critical_bh(&pwdev_priv->connect_req_lock, &irqL); - - return 0; } void rtw_cfg80211_indicate_disconnect(_adapter *padapter, u16 reason, u8 locally_generated) @@ -1406,15 +1376,70 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa psecuritypriv->dot118021XGrpPrivacy = _AES_; _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); + } else if (strcmp(param->u.crypt.alg, "GCMP") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set GCMP TX GTK idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len); + psecuritypriv->dot118021XGrpPrivacy = _GCMP_; + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, + param->u.crypt.key, + (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); + + } else if (strcmp(param->u.crypt.alg, "GCMP_256") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set GCMP_256 TX GTK idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len); + psecuritypriv->dot118021XGrpPrivacy = _GCMP_256_; + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, + param->u.crypt.key, + (param->u.crypt.key_len > 32 ? 32 : param->u.crypt.key_len)); + + } else if (strcmp(param->u.crypt.alg, "CCMP_256") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set CCMP_256 TX GTK idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len); + psecuritypriv->dot118021XGrpPrivacy = _CCMP_256_; + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, + param->u.crypt.key, + (param->u.crypt.key_len > 32 ? 32: param->u.crypt.key_len)); + #ifdef CONFIG_IEEE80211W } else if (strcmp(param->u.crypt.alg, "BIP") == 0) { - RTW_INFO(FUNC_ADPT_FMT" set TX IGTK idx:%u, len:%u\n" + psecuritypriv->dot11wCipher = _BIP_CMAC_128_; + RTW_INFO(FUNC_ADPT_FMT" set TX CMAC-128 IGTK idx:%u, len:%u\n" , FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len); _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx; psecuritypriv->dot11wBIPtxpn.val = RTW_GET_LE64(param->u.crypt.seq); padapter->securitypriv.binstallBIPkey = _TRUE; goto exit; + } else if (strcmp(param->u.crypt.alg, "BIP_GMAC_128") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set TX GMAC-128 IGTK idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len); + psecuritypriv->dot11wCipher = _BIP_GMAC_128_; + _rtw_memcpy(psecuritypriv->dot11wBIPKey[param->u.crypt.idx].skey, + param->u.crypt.key, param->u.crypt.key_len); + psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx; + psecuritypriv->dot11wBIPtxpn.val = RTW_GET_LE64(param->u.crypt.seq); + psecuritypriv->binstallBIPkey = _TRUE; + goto exit; + } else if (strcmp(param->u.crypt.alg, "BIP_GMAC_256") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set TX GMAC-256 IGTK idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len); + psecuritypriv->dot11wCipher = _BIP_GMAC_256_; + _rtw_memcpy(psecuritypriv->dot11wBIPKey[param->u.crypt.idx].skey, + param->u.crypt.key, param->u.crypt.key_len); + padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx; + psecuritypriv->dot11wBIPtxpn.val = RTW_GET_LE64(param->u.crypt.seq); + padapter->securitypriv.binstallBIPkey = _TRUE; + goto exit; + } else if (strcmp(param->u.crypt.alg, "BIP_CMAC_256") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set TX CMAC-256 IGTK idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len); + psecuritypriv->dot11wCipher = _BIP_CMAC_256_; + _rtw_memcpy(psecuritypriv->dot11wBIPKey[param->u.crypt.idx].skey, + param->u.crypt.key, param->u.crypt.key_len); + psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx; + psecuritypriv->dot11wBIPtxpn.val = RTW_GET_LE64(param->u.crypt.seq); + psecuritypriv->binstallBIPkey = _TRUE; + goto exit; #endif /* CONFIG_IEEE80211W */ } else if (strcmp(param->u.crypt.alg, "none") == 0) { @@ -1447,7 +1472,14 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x */ if (param->u.crypt.set_tx == 1) { /* pairwise key */ - _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); + if (param->u.crypt.key_len == 32) + _rtw_memcpy(psta->dot118021x_UncstKey.skey, + param->u.crypt.key, + (param->u.crypt.key_len > 32 ? 32 : param->u.crypt.key_len)); + else + _rtw_memcpy(psta->dot118021x_UncstKey.skey, + param->u.crypt.key, + (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); if (strcmp(param->u.crypt.alg, "WEP") == 0) { RTW_INFO(FUNC_ADPT_FMT" set WEP PTK of "MAC_FMT" idx:%u, len:%u\n" @@ -1473,6 +1505,24 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa , param->u.crypt.idx, param->u.crypt.key_len); psta->dot118021XPrivacy = _AES_; + } else if (strcmp(param->u.crypt.alg, "GCMP") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set GCMP PTK of "MAC_FMT" idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr) + , param->u.crypt.idx, param->u.crypt.key_len); + psta->dot118021XPrivacy = _GCMP_; + + } else if (strcmp(param->u.crypt.alg, "GCMP_256") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set GCMP_256 PTK of "MAC_FMT" idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr) + , param->u.crypt.idx, param->u.crypt.key_len); + psta->dot118021XPrivacy = _GCMP_256_; + + } else if (strcmp(param->u.crypt.alg, "CCMP_256") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set CCMP_256 PTK of "MAC_FMT" idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr) + , param->u.crypt.idx, param->u.crypt.key_len); + psta->dot118021XPrivacy = _CCMP_256_; + } else if (strcmp(param->u.crypt.alg, "none") == 0) { RTW_INFO(FUNC_ADPT_FMT" clear pairwise key of "MAC_FMT" idx:%u\n" , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr) @@ -1509,16 +1559,77 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa psta->gtk_bmp |= BIT(param->u.crypt.idx); psta->gtk_pn.val = RTW_GET_LE64(param->u.crypt.seq); - #ifdef CONFIG_IEEE80211W - } else if (strcmp(param->u.crypt.alg, "BIP") == 0) { - RTW_INFO(FUNC_ADPT_FMT" set IGTK of "MAC_FMT", idx:%u, len:%u\n" + } else if (strcmp(param->u.crypt.alg, "GCMP") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set GCMP GTK of "MAC_FMT", idx:%u, len:%u\n" , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr) , param->u.crypt.idx, param->u.crypt.key_len); + psta->group_privacy = _GCMP_; + _rtw_memcpy(psta->gtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); + psta->gtk_bmp |= BIT(param->u.crypt.idx); + psta->gtk_pn.val = RTW_GET_LE64(param->u.crypt.seq); + + } else if (strcmp(param->u.crypt.alg, "CCMP_256") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set CCMP_256 GTK of "MAC_FMT", idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr) + , param->u.crypt.idx, param->u.crypt.key_len); + psta->group_privacy = _CCMP_256_; + _rtw_memcpy(psta->gtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 32 ? 32 : param->u.crypt.key_len)); + psta->gtk_bmp |= BIT(param->u.crypt.idx); + psta->gtk_pn.val = RTW_GET_LE64(param->u.crypt.seq); + + } else if (strcmp(param->u.crypt.alg, "GCMP_256") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set GCMP_256 GTK of "MAC_FMT", idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr) + , param->u.crypt.idx, param->u.crypt.key_len); + psta->group_privacy = _GCMP_256_; + _rtw_memcpy(psta->gtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 32 ? 32 : param->u.crypt.key_len)); + psta->gtk_bmp |= BIT(param->u.crypt.idx); + psta->gtk_pn.val = RTW_GET_LE64(param->u.crypt.seq); + + #ifdef CONFIG_IEEE80211W + } else if (strcmp(param->u.crypt.alg, "BIP") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set CMAC-128 IGTK of "MAC_FMT", idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr) + , param->u.crypt.idx, param->u.crypt.key_len); + psta->dot11wCipher = _BIP_CMAC_128_; _rtw_memcpy(psta->igtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); psta->igtk_bmp |= BIT(param->u.crypt.idx); psta->igtk_id = param->u.crypt.idx; psta->igtk_pn.val = RTW_GET_LE64(param->u.crypt.seq); goto exit; + + } else if (strcmp(param->u.crypt.alg, "BIP_GMAC_128") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set GMAC-128 IGTK of "MAC_FMT", idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr) + , param->u.crypt.idx, param->u.crypt.key_len); + psta->dot11wCipher = _BIP_GMAC_128_; + _rtw_memcpy(psta->igtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); + psta->igtk_bmp |= BIT(param->u.crypt.idx); + psta->igtk_id = param->u.crypt.idx; + psta->igtk_pn.val = RTW_GET_LE64(param->u.crypt.seq); + goto exit; + + } else if (strcmp(param->u.crypt.alg, "BIP_CMAC_256") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set CMAC-256 IGTK of "MAC_FMT", idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr) + , param->u.crypt.idx, param->u.crypt.key_len); + psta->dot11wCipher = _BIP_CMAC_256_; + _rtw_memcpy(psta->igtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 32 ? 32 : param->u.crypt.key_len)); + psta->igtk_bmp |= BIT(param->u.crypt.idx); + psta->igtk_id = param->u.crypt.idx; + psta->igtk_pn.val = RTW_GET_LE64(param->u.crypt.seq); + goto exit; + + } else if (strcmp(param->u.crypt.alg, "BIP_GMAC_256") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set GMAC-256 IGTK of "MAC_FMT", idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr) + , param->u.crypt.idx, param->u.crypt.key_len); + psta->dot11wCipher = _BIP_GMAC_256_; + _rtw_memcpy(psta->igtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 32 ? 32 : param->u.crypt.key_len)); + psta->igtk_bmp |= BIT(param->u.crypt.idx); + psta->igtk_id = param->u.crypt.idx; + psta->igtk_pn.val = RTW_GET_LE64(param->u.crypt.seq); + goto exit; #endif /* CONFIG_IEEE80211W */ } else if (strcmp(param->u.crypt.alg, "none") == 0) { @@ -1648,7 +1759,19 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param if (param->u.crypt.set_tx == 1) { /* pairwise key */ RTW_INFO(FUNC_ADPT_FMT" set %s PTK idx:%u, len:%u\n" , FUNC_ADPT_ARG(padapter), param->u.crypt.alg, param->u.crypt.idx, param->u.crypt.key_len); - _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); + + if (strcmp(param->u.crypt.alg, "GCMP_256") == 0 + || strcmp(param->u.crypt.alg, "CCMP_256") == 0) { + _rtw_memcpy(psta->dot118021x_UncstKey.skey, + param->u.crypt.key, + ((param->u.crypt.key_len > 32) ? + 32 : param->u.crypt.key_len)); + } else + _rtw_memcpy(psta->dot118021x_UncstKey.skey, + param->u.crypt.key, + (param->u.crypt.key_len > 16 ? + 16 : param->u.crypt.key_len)); + if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */ _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8); _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8); @@ -1663,10 +1786,13 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _TRUE); } else { /* group key */ - if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) { + if (strcmp(param->u.crypt.alg, "TKIP") == 0 + || strcmp(param->u.crypt.alg, "CCMP") == 0 + || strcmp(param->u.crypt.alg, "GCMP") == 0) { RTW_INFO(FUNC_ADPT_FMT" set %s GTK idx:%u, len:%u\n" , FUNC_ADPT_ARG(padapter), param->u.crypt.alg, param->u.crypt.idx, param->u.crypt.key_len); - _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, + _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, + param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8); _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8); @@ -1675,16 +1801,57 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param _rtw_memcpy(padapter->securitypriv.iv_seq[param->u.crypt.idx], param->u.crypt.seq, 8); padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx; rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, _TRUE); - + } else if (strcmp(param->u.crypt.alg, "GCMP_256") == 0 + || strcmp(param->u.crypt.alg, "CCMP_256") == 0) { + RTW_INFO(FUNC_ADPT_FMT" set %s GTK idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), param->u.crypt.alg, param->u.crypt.idx, param->u.crypt.key_len); + _rtw_memcpy( + padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, + param->u.crypt.key, + (param->u.crypt.key_len > 32 ? 32 : param->u.crypt.key_len)); + padapter->securitypriv.binstallGrpkey = _TRUE; + padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx; + rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, _TRUE); #ifdef CONFIG_IEEE80211W } else if (strcmp(param->u.crypt.alg, "BIP") == 0) { - RTW_INFO(FUNC_ADPT_FMT" set IGTK idx:%u, len:%u\n" + psecuritypriv->dot11wCipher = _BIP_CMAC_128_; + RTW_INFO(FUNC_ADPT_FMT" set CMAC-128 IGTK idx:%u, len:%u\n" , FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len); - _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key, + _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, + param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx; psecuritypriv->dot11wBIPrxpn.val = RTW_GET_LE64(param->u.crypt.seq); psecuritypriv->binstallBIPkey = _TRUE; + } else if (strcmp(param->u.crypt.alg, "BIP_GMAC_128") == 0) { + psecuritypriv->dot11wCipher = _BIP_GMAC_128_; + RTW_INFO(FUNC_ADPT_FMT" set GMAC-128 IGTK idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len); + _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, + param->u.crypt.key, + (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); + psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx; + psecuritypriv->dot11wBIPrxpn.val = RTW_GET_LE64(param->u.crypt.seq); + psecuritypriv->binstallBIPkey = _TRUE; + } else if (strcmp(param->u.crypt.alg, "BIP_GMAC_256") == 0) { + psecuritypriv->dot11wCipher = _BIP_GMAC_256_; + RTW_INFO(FUNC_ADPT_FMT" set GMAC-256 IGTK idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len); + _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, + param->u.crypt.key, + (param->u.crypt.key_len > 32 ? 32 : param->u.crypt.key_len)); + psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx; + psecuritypriv->dot11wBIPrxpn.val = RTW_GET_LE64(param->u.crypt.seq); + psecuritypriv->binstallBIPkey = _TRUE; + } else if (strcmp(param->u.crypt.alg, "BIP_CMAC_256") == 0) { + psecuritypriv->dot11wCipher = _BIP_CMAC_256_; + RTW_INFO(FUNC_ADPT_FMT" set CMAC-256 IGTK idx:%u, len:%u\n" + , FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len); + _rtw_memcpy(psecuritypriv->dot11wBIPKey[param->u.crypt.idx].skey, + param->u.crypt.key, param->u.crypt.key_len); + psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx; + psecuritypriv->dot11wBIPrxpn.val = RTW_GET_LE64(param->u.crypt.seq); + psecuritypriv->binstallBIPkey = _TRUE; #endif /* CONFIG_IEEE80211W */ } @@ -1788,10 +1955,28 @@ static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev case WLAN_CIPHER_SUITE_CCMP: alg_name = "CCMP"; break; + case WIFI_CIPHER_SUITE_GCMP: + alg_name = "GCMP"; + break; + case WIFI_CIPHER_SUITE_GCMP_256: + alg_name = "GCMP_256"; + break; + case WIFI_CIPHER_SUITE_CCMP_256: + alg_name = "CCMP_256"; + break; #ifdef CONFIG_IEEE80211W case WLAN_CIPHER_SUITE_AES_CMAC: alg_name = "BIP"; break; + case WIFI_CIPHER_SUITE_BIP_GMAC_128: + alg_name = "BIP_GMAC_128"; + break; + case WIFI_CIPHER_SUITE_BIP_GMAC_256: + alg_name = "BIP_GMAC_256"; + break; + case WIFI_CIPHER_SUITE_BIP_CMAC_256: + alg_name = "BIP_CMAC_256"; + break; #endif /* CONFIG_IEEE80211W */ #ifdef CONFIG_WAPI_SUPPORT case WLAN_CIPHER_SUITE_SMS4: @@ -1942,7 +2127,7 @@ static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev } else if (keyid <= BIP_MAX_KEYID) { if (SEC_IS_BIP_KEY_INSTALLED(sec) != _TRUE) goto exit; - cipher = _BIP_; + cipher = sec->dot11wCipher; key = &sec->dot11wBIPKey[keyid]; pn = &sec->dot11wBIPtxpn.val; #endif @@ -1969,7 +2154,7 @@ static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev } else if (keyid <= BIP_MAX_KEYID && !pairwise) { if (!(sta->igtk_bmp & BIT(keyid))) goto exit; - cipher = _BIP_; + cipher = sta->dot11wCipher; key = &sta->igtk; pn = &sta->igtk_pn.val; #endif @@ -1986,16 +2171,39 @@ static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev } else if (cipher == _WEP104_) { cipher = WLAN_CIPHER_SUITE_WEP104; key_len = sec->dot11DefKeylen[keyid]; - } else if (cipher == _TKIP_) { + } else if (cipher == _TKIP_ || cipher == _TKIP_WTMIC_) { cipher = WLAN_CIPHER_SUITE_TKIP; key_len = 16; } else if (cipher == _AES_) { cipher = WLAN_CIPHER_SUITE_CCMP; key_len = 16; +#ifdef CONFIG_WAPI_SUPPORT + } else if (cipher == _SMS4_) { + cipher = WLAN_CIPHER_SUITE_SMS4; + key_len = 16; +#endif + } else if (cipher == _GCMP_) { + cipher = WIFI_CIPHER_SUITE_GCMP; + key_len = 16; + } else if (cipher == _CCMP_256_) { + cipher = WIFI_CIPHER_SUITE_CCMP_256; + key_len = 32; + } else if (cipher == _GCMP_256_) { + cipher = WIFI_CIPHER_SUITE_GCMP_256; + key_len = 32; #ifdef CONFIG_IEEE80211W - } else if (cipher == _BIP_) { + } else if (cipher == _BIP_CMAC_128_) { cipher = WLAN_CIPHER_SUITE_AES_CMAC; key_len = 16; + } else if (cipher == _BIP_GMAC_128_) { + cipher = WIFI_CIPHER_SUITE_BIP_GMAC_128; + key_len = 16; + } else if (cipher == _BIP_GMAC_256_) { + cipher = WIFI_CIPHER_SUITE_BIP_GMAC_256; + key_len = 32; + } else if (cipher == _BIP_CMAC_256_) { + cipher = WIFI_CIPHER_SUITE_BIP_CMAC_256; + key_len = 32; #endif } else { RTW_WARN(FUNC_NDEV_FMT" unknown cipher:%u\n", FUNC_NDEV_ARG(ndev), cipher); @@ -2307,7 +2515,7 @@ static int cfg80211_rtw_get_station(struct wiphy *wiphy, /* for infra./P2PClient mode */ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) - && check_fwstate(pmlmepriv, _FW_LINKED) + && check_fwstate(pmlmepriv, WIFI_ASOC_STATE) ) { struct wlan_network *cur_network = &(pmlmepriv->cur_network); @@ -2326,7 +2534,7 @@ static int cfg80211_rtw_get_station(struct wiphy *wiphy, if (psta) { if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE - || check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE + || check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE ) { sinfo->filled |= STATION_INFO_SIGNAL; sinfo->signal = translate_percentage_to_dbm(psta->cmn.rssi_stat.rssi); @@ -2501,13 +2709,17 @@ static int cfg80211_rtw_change_iface(struct wiphy *wiphy, break; #endif +#ifdef CONFIG_WIFI_MONITOR case NL80211_IFTYPE_MONITOR: networkType = Ndis802_11Monitor; -#if 0 + +#ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL ndev->type = ARPHRD_IEEE80211; /* IEEE 802.11 : 801 */ -#endif +#else ndev->type = ARPHRD_IEEE80211_RADIOTAP; /* IEEE 802.11 + radiotap header : 803 */ +#endif break; +#endif /* CONFIG_WIFI_MONITOR */ default: ret = -EOPNOTSUPP; goto exit; @@ -2526,6 +2738,15 @@ static int cfg80211_rtw_change_iface(struct wiphy *wiphy, if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE) rtw_indicate_connect(padapter); #endif + + #if defined(CONFIG_RTW_WDS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) + if (params->use_4addr != -1) { + RTW_INFO(FUNC_NDEV_FMT" use_4addr=%d\n" + , FUNC_NDEV_ARG(ndev), params->use_4addr); + adapter_set_use_wds(padapter, params->use_4addr); + } + #endif + exit: RTW_INFO(FUNC_NDEV_FMT" ret:%d\n", FUNC_NDEV_ARG(ndev), ret); @@ -2537,7 +2758,7 @@ void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted) struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); _irqL irqL; -#if (KERNEL_VERSION(4, 7, 0) <= LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE) struct cfg80211_scan_info info; memset(&info, 0, sizeof(info)); @@ -2554,7 +2775,7 @@ void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted) if (pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy) RTW_INFO("error wiphy compare\n"); else -#if (KERNEL_VERSION(4, 7, 0) <= LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE) cfg80211_scan_done(pwdev_priv->scan_request, &info); #else cfg80211_scan_done(pwdev_priv->scan_request, aborted); @@ -2815,6 +3036,10 @@ static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, in return -EINVAL; } #endif /* CONFIG_WFD */ + + #ifdef CONFIG_RTW_MBO + rtw_mbo_update_ie_data(padapter, buf, len); + #endif } return ret; @@ -2847,7 +3072,7 @@ u8 rtw_cfg80211_scan_via_buddy(_adapter *padapter, struct cfg80211_scan_request continue; buddy_mlmepriv = &iface->mlmepriv; - if (!check_fwstate(buddy_mlmepriv, _FW_UNDER_SURVEY)) + if (!check_fwstate(buddy_mlmepriv, WIFI_UNDER_SURVEY)) continue; buddy_wdev_priv = adapter_wdev_data(iface); @@ -2856,7 +3081,7 @@ u8 rtw_cfg80211_scan_via_buddy(_adapter *padapter, struct cfg80211_scan_request if (buddy_wdev_priv->scan_request) { pmlmepriv->scanning_via_buddy_intf = _TRUE; _enter_critical_bh(&pmlmepriv->lock, &irqL); - set_fwstate(pmlmepriv, _FW_UNDER_SURVEY); + set_fwstate(pmlmepriv, WIFI_UNDER_SURVEY); _exit_critical_bh(&pmlmepriv->lock, &irqL); pwdev_priv->scan_request = request; ret = _TRUE; @@ -2896,7 +3121,7 @@ void rtw_cfg80211_indicate_scan_done_for_buddy(_adapter *padapter, bool bscan_ab _enter_critical_bh(&wdev_priv->scan_req_lock, &irqL); if (mlmepriv->scanning_via_buddy_intf == _TRUE) { mlmepriv->scanning_via_buddy_intf = _FALSE; - clr_fwstate(mlmepriv, _FW_UNDER_SURVEY); + clr_fwstate(mlmepriv, WIFI_UNDER_SURVEY); if (wdev_priv->scan_request) indicate_buddy_scan = _TRUE; } @@ -2969,6 +3194,21 @@ static int cfg80211_rtw_scan(struct wiphy *wiphy RTW_INFO(FUNC_ADPT_FMT"%s\n", FUNC_ADPT_ARG(padapter) , wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : ""); +#ifdef CONFIG_RTW_SCAN_RAND +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) + if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { + get_random_mask_addr(pwdev_priv->pno_mac_addr, request->mac_addr, + request->mac_addr_mask); + print_hex_dump(KERN_DEBUG, "random mac_addr: ", + DUMP_PREFIX_OFFSET, 16, 1, pwdev_priv->pno_mac_addr, ETH_ALEN, 1); + } + else + memset(pwdev_priv->pno_mac_addr, 0xFF, ETH_ALEN); + +#endif +#endif + + #if 1 ssc_chk = rtw_sitesurvey_condition_check(padapter, _TRUE); @@ -3041,7 +3281,7 @@ bypass_p2p_chk: goto check_need_indicate_scan_done; case SS_DENY_BY_DRV : - #if CONFIG_NOTIFY_SCAN_ABORT_WITH_BUSY + #ifdef CONFIG_NOTIFY_SCAN_ABORT_WITH_BUSY ret = -EBUSY; goto exit; #else @@ -3142,7 +3382,7 @@ bypass_p2p_chk: if (rtw_is_scan_deny(padapter)) { RTW_INFO(FUNC_ADPT_FMT ": scan deny\n", FUNC_ADPT_ARG(padapter)); -#if CONFIG_NOTIFY_SCAN_ABORT_WITH_BUSY +#ifdef CONFIG_NOTIFY_SCAN_ABORT_WITH_BUSY ret = -EBUSY; goto exit; #else @@ -3158,7 +3398,7 @@ bypass_p2p_chk: RTW_INFO(FUNC_ADPT_FMT" under WIFI_AP_STATE\n", FUNC_ADPT_ARG(padapter)); #endif - if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS | _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS | WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING) == _TRUE) { RTW_INFO("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state); if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) @@ -3169,23 +3409,23 @@ bypass_p2p_chk: } } - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE) { RTW_INFO("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state); need_indicate_scan_done = _TRUE; goto check_need_indicate_scan_done; - } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { + } else if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE) { RTW_INFO("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state); ret = -EBUSY; goto check_need_indicate_scan_done; } #ifdef CONFIG_CONCURRENT_MODE - if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING | WIFI_UNDER_WPS)) { + if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING | WIFI_UNDER_WPS)) { RTW_INFO("%s exit due to buddy_intf's mlme state under linking or wps\n", __func__); need_indicate_scan_done = _TRUE; goto check_need_indicate_scan_done; - } else if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_SURVEY)) { + } else if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_SURVEY)) { bool scan_via_buddy = rtw_cfg80211_scan_via_buddy(padapter, request); if (scan_via_buddy == _FALSE) @@ -3195,11 +3435,24 @@ bypass_p2p_chk: } #endif /* CONFIG_CONCURRENT_MODE */ - /* busy traffic check*/ - if (rtw_mi_busy_traffic_check(padapter, _TRUE)) { - need_indicate_scan_done = _TRUE; +#ifdef RTW_BUSY_DENY_SCAN + /* + * busy traffic check + * Rules: + * 1. If (scan interval <= BUSY_TRAFFIC_SCAN_DENY_PERIOD) always allow + * scan, otherwise goto rule 2. + * 2. Deny scan if any interface is busy, otherwise allow scan. + */ + if (pmlmepriv->lastscantime + && (rtw_get_passing_time_ms(pmlmepriv->lastscantime) > + registry_par->scan_interval_thr) + && rtw_mi_busy_traffic_check(padapter)) { + RTW_WARN(FUNC_ADPT_FMT ": scan abort!! BusyTraffic\n", + FUNC_ADPT_ARG(padapter)); + need_indicate_scan_done = _TRUE; goto check_need_indicate_scan_done; } +#endif /* RTW_BUSY_DENY_SCAN */ #endif #ifdef CONFIG_P2P @@ -3262,15 +3515,17 @@ bypass_p2p_chk: check_need_indicate_scan_done: if (_TRUE == need_indicate_scan_done) { -#if (KERNEL_VERSION(4, 7, 0) <= LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE) struct cfg80211_scan_info info; memset(&info, 0, sizeof(info)); info.aborted = 0; #endif + /* the process time of scan results must be over at least 1ms in the newly Android */ + rtw_msleep_os(1); _rtw_cfg80211_surveydone_event_callback(padapter, request); -#if (KERNEL_VERSION(4, 7, 0) <= LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE) cfg80211_scan_done(request, &info); #else cfg80211_scan_done(request, 0); @@ -3281,12 +3536,30 @@ check_need_indicate_scan_done: rtw_ps_deny_cancel(padapter, PS_DENY_SCAN); exit: +#ifdef RTW_BUSY_DENY_SCAN if (pmlmepriv) pmlmepriv->lastscantime = rtw_get_current_time(); +#endif return ret; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) && \ + defined(CONFIG_RTW_ABORT_SCAN) +static void cfg80211_rtw_abort_scan(struct wiphy *wiphy, + struct wireless_dev *wdev) +{ + _adapter *padapter = wiphy_to_adapter(wiphy); + + RTW_INFO("=>"FUNC_ADPT_FMT" - Abort Scan\n", FUNC_ADPT_ARG(padapter)); + if (wdev->iftype != NL80211_IFTYPE_STATION) { + RTW_ERR("abort scan ignored, iftype(%d)\n", wdev->iftype); + return; + } + rtw_scan_abort(padapter); +} +#endif + static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed) { #if 0 @@ -3356,13 +3629,22 @@ static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv, { RTW_INFO("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type); - psecuritypriv->auth_type = sme_auth_type; - - if (sme_auth_type == NL80211_AUTHTYPE_SAE) { + if (NL80211_AUTHTYPE_MAX <= (int)MLME_AUTHTYPE_SAE) { + if (MLME_AUTHTYPE_SAE == psecuritypriv->auth_type) { + /* This case pre handle in + * rtw_check_connect_sae_compat() + */ + psecuritypriv->auth_alg = WLAN_AUTH_SAE; + return 0; + } + } else if (sme_auth_type == (int)MLME_AUTHTYPE_SAE) { + psecuritypriv->auth_type = MLME_AUTHTYPE_SAE; psecuritypriv->auth_alg = WLAN_AUTH_SAE; return 0; } + psecuritypriv->auth_type = sme_auth_type; + switch (sme_auth_type) { case NL80211_AUTHTYPE_AUTOMATIC: @@ -3440,6 +3722,18 @@ static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 ciph *profile_cipher = _AES_; ndisencryptstatus = Ndis802_11Encryption3Enabled; break; + case WIFI_CIPHER_SUITE_GCMP: + *profile_cipher = _GCMP_; + ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + case WIFI_CIPHER_SUITE_GCMP_256: + *profile_cipher = _GCMP_256_; + ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + case WIFI_CIPHER_SUITE_CCMP_256: + *profile_cipher = _CCMP_256_; + ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; #ifdef CONFIG_WAPI_SUPPORT case WLAN_CIPHER_SUITE_SMS4: *profile_cipher = _SMS4_; @@ -3488,7 +3782,9 @@ static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key psecuritypriv->rsn_akm_suite_type = 4; } #endif - else { + else if (key_mgt == WLAN_AKM_SUITE_SAE) { + psecuritypriv->rsn_akm_suite_type = 8; + } else { RTW_INFO("Invalid key mgt: 0x%x\n", key_mgt); /* return -EINVAL; */ } @@ -3548,7 +3844,7 @@ static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen) pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen); if (pwpa2 && wpa2_ielen > 0) { - if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen + 2, &group_cipher, &pairwise_cipher, NULL, &mfp_opt) == _SUCCESS) { + if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen + 2, &group_cipher, &pairwise_cipher, NULL, NULL, &mfp_opt, NULL) == _SUCCESS) { padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen + 2); @@ -3579,6 +3875,18 @@ static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen) padapter->securitypriv.dot118021XGrpPrivacy = _AES_; padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; break; + case WPA_CIPHER_GCMP: + padapter->securitypriv.dot118021XGrpPrivacy = _GCMP_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + case WPA_CIPHER_GCMP_256: + padapter->securitypriv.dot118021XGrpPrivacy = _GCMP_256_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + case WPA_CIPHER_CCMP_256: + padapter->securitypriv.dot118021XGrpPrivacy = _CCMP_256_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; case WPA_CIPHER_WEP104: padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_; padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; @@ -3602,6 +3910,18 @@ static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen) padapter->securitypriv.dot11PrivacyAlgrthm = _AES_; padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; break; + case WPA_CIPHER_GCMP: + padapter->securitypriv.dot11PrivacyAlgrthm = _GCMP_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + case WPA_CIPHER_GCMP_256: + padapter->securitypriv.dot11PrivacyAlgrthm = _GCMP_256_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + case WPA_CIPHER_CCMP_256: + padapter->securitypriv.dot11PrivacyAlgrthm = _CCMP_256_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; case WPA_CIPHER_WEP104: padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_; padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; @@ -3689,10 +4009,19 @@ static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen) } #endif /* CONFIG_WFD */ + #ifdef CONFIG_RTW_MULTI_AP + padapter->multi_ap = rtw_get_multi_ap_ie_ext(buf, ielen) & MULTI_AP_BACKHAUL_STA; + if (padapter->multi_ap) + adapter_set_use_wds(padapter, 1); + #endif + /* TKIP and AES disallow multicast packets until installing group key */ if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_ || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_ - || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_) + || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_ + || padapter->securitypriv.dot11PrivacyAlgrthm == _GCMP_ + || padapter->securitypriv.dot11PrivacyAlgrthm == _GCMP_256_ + || padapter->securitypriv.dot11PrivacyAlgrthm == _CCMP_256_) /* WPS open need to enable multicast */ /* || check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE) */ rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr); @@ -3744,7 +4073,7 @@ static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev, } #ifdef CONFIG_CONCURRENT_MODE - if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING)) { + if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING)) { RTW_INFO("%s, but buddy_intf is under linking\n", __FUNCTION__); ret = -EINVAL; goto cancel_ps_deny; @@ -3799,7 +4128,7 @@ static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) rtw_set_to_roam(padapter, 0); - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { + if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) { rtw_scan_abort(padapter); LeaveAllPowerSaveMode(padapter); @@ -3839,9 +4168,7 @@ static int _rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev) _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); - rtw_set_to_roam(padapter, 0); - - /* if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)) */ + /* if(check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) */ { rtw_scan_abort(padapter); rtw_join_abort_timeout(padapter, 300); @@ -3850,9 +4177,10 @@ static int _rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev) #ifdef CONFIG_RTW_REPEATER_SON rtw_rson_do_disconnect(padapter); #endif + RTW_INFO("%s...call rtw_indicate_disconnect\n", __func__); + rtw_free_assoc_resources_cmd(padapter, _TRUE, RTW_CMDF_WAIT_ACK); - RTW_INFO("%s...call rtw_indicate_disconnect\n", __func__); /* indicate locally_generated = 0 when suspend */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) rtw_indicate_disconnect(padapter, 0, wiphy->dev.power.is_prepared ? _FALSE : _TRUE); @@ -3870,7 +4198,8 @@ static int _rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev) return 0; } -#if (KERNEL_VERSION(4, 17, 0) > LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 17, 0) > LINUX_VERSION_CODE) \ + && !defined(CONFIG_KERNEL_PATCH_EXTERNAL_AUTH) static bool rtw_check_connect_sae_compat(struct cfg80211_connect_params *sme) { struct rtw_ieee802_11_elems elems; @@ -3878,7 +4207,7 @@ static bool rtw_check_connect_sae_compat(struct cfg80211_connect_params *sme) u8 AKM_SUITE_SAE[] = { 0x00, 0x0f, 0xac, 8 }; int i; - if (sme->auth_type != 1) + if (sme->auth_type != (int)MLME_AUTHTYPE_SHARED_KEY) return false; if (rtw_ieee802_11_parse_elems((u8 *)sme->ie, sme->ie_len, &elems, 0) @@ -3902,70 +4231,6 @@ static bool rtw_check_connect_sae_compat(struct cfg80211_connect_params *sme) #define rtw_check_connect_sae_compat(sme) false #endif -static u8 compare_connect_params(struct _ADAPTER *a, - struct cfg80211_connect_params *org, - struct cfg80211_connect_params *req) -{ - struct rtw_wdev_priv *pwdev_priv; - struct mlme_priv *mlme; - _irqL irqL; - u8 ret = _TRUE; - u8 *ssid = NULL, *bssid = NULL; - u8 ssid_len; - - - pwdev_priv = adapter_wdev_data(a); - mlme = &a->mlmepriv; - - _enter_critical_bh(&pwdev_priv->connect_req_lock, &irqL); - /* check ssid & ssid_len */ - ssid_len = mlme->assoc_ssid.SsidLength; - ssid = mlme->assoc_ssid.Ssid; - if (ssid_len != req->ssid_len) { - ret = _FALSE; - goto exit; - } - if (_rtw_memcmp(ssid, req->ssid, ssid_len) == _FALSE) { - ret = _FALSE; - goto exit; - } - - /* check bssid */ - if (mlme->assoc_by_bssid == _TRUE) - bssid = mlme->assoc_bssid; - if (bssid) { - if (!req->bssid) { - RTW_PRINT(FUNC_ADPT_FMT ": bssid not the same," - "only org:" MAC_FMT "\n", - FUNC_ADPT_ARG(a), MAC_ARG(bssid)); - ret = _FALSE; - goto exit; - } - if (_rtw_memcmp(bssid, req->bssid, ETH_ALEN) == _FALSE) { - RTW_PRINT(FUNC_ADPT_FMT ": bssid not the same," - "org:" MAC_FMT " new:" MAC_FMT "\n", - FUNC_ADPT_ARG(a), - MAC_ARG(bssid), MAC_ARG(req->bssid)); - ret = _FALSE; - goto exit; - } - } else if (req->bssid) { - RTW_PRINT(FUNC_ADPT_FMT ": bssid not the same," - "only new:" MAC_FMT "\n", - FUNC_ADPT_ARG(a), MAC_ARG(req->bssid)); - ret = _FALSE; - goto exit; - } - - /* update new req */ - _rtw_memcpy(org, req, sizeof(*org)); - -exit: - _exit_critical_bh(&pwdev_priv->connect_req_lock, &irqL); - - return ret; -} - static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme) { @@ -3985,19 +4250,14 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, #endif RTW_INFO("=>"FUNC_NDEV_FMT" - Start to Connection\n", FUNC_NDEV_ARG(ndev)); - RTW_INFO(FUNC_NDEV_FMT ": privacy=%d, key=%p, key_len=%d, " - "key_idx=%d, auth_type=%d\n", - FUNC_NDEV_ARG(ndev), sme->privacy, sme->key, sme->key_len, - sme->key_idx, sme->auth_type); - if (sme->channel) - RTW_INFO(FUNC_NDEV_FMT ": ch=%u freq=%u MHz flags=0x%x\n", - FUNC_NDEV_ARG(ndev), sme->channel->hw_value, - sme->channel->center_freq, sme->channel->flags); + RTW_INFO("privacy=%d, key=%p, key_len=%d, key_idx=%d, auth_type=%d\n", + sme->privacy, sme->key, sme->key_len, sme->key_idx, sme->auth_type); if (rtw_check_connect_sae_compat(sme)) { - sme->auth_type = NL80211_AUTHTYPE_SAE; - RTW_INFO("%s set sme->auth_type=%d for SAE compat\n", __FUNCTION__, - NL80211_AUTHTYPE_SAE); + sme->auth_type = (int)MLME_AUTHTYPE_SAE; + psecuritypriv->auth_type = MLME_AUTHTYPE_SAE; + psecuritypriv->auth_alg = WLAN_AUTH_SAE; + RTW_INFO("%s set sme->auth_type for SAE compat\n", __FUNCTION__); } if (pwdev_priv->block == _TRUE) { @@ -4006,43 +4266,13 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, goto exit; } - _enter_critical_bh(&pmlmepriv->lock, &irqL); - - if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) - || pwdev_priv->connect_req) { - RTW_WARN(FUNC_NDEV_FMT ": new request when linking!" - "fw_state=0x%x, to_join is %s\n", - FUNC_NDEV_ARG(ndev), get_fwstate(pmlmepriv), - (pmlmepriv->to_join == _TRUE)?"true":"false"); - if (!pwdev_priv->connect_req) { - RTW_ERR(FUNC_NDEV_FMT ": no connect_req when under linking?!\n", - FUNC_NDEV_ARG(ndev)); - } else if (compare_connect_params(padapter, pwdev_priv->connect_req, sme) == _TRUE) { - RTW_WARN(FUNC_NDEV_FMT ": skip the same request!\n", - FUNC_NDEV_ARG(ndev)); - - _exit_critical_bh(&pmlmepriv->lock, &irqL); - - goto exit; - } - - _exit_critical_bh(&pmlmepriv->lock, &irqL); - } else if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { - RTW_WARN(FUNC_NDEV_FMT ": run disconnect first! fw_state=0x%x\n", - FUNC_NDEV_ARG(ndev), get_fwstate(pmlmepriv)); - - _exit_critical_bh(&pmlmepriv->lock, &irqL); + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_UNDER_LINKING) == _TRUE) { _rtw_disconnect(wiphy, ndev); - } else { - RTW_INFO(FUNC_NDEV_FMT": fw_state=0x%x\n", - FUNC_NDEV_ARG(ndev), get_fwstate(pmlmepriv)); - - _exit_critical_bh(&pmlmepriv->lock, &irqL); + RTW_INFO("%s disconnect before connecting! fw_state=0x%x\n", + __FUNCTION__, pmlmepriv->fw_state); } - /* make sure everyone already call _exit_critical_bh() before here */ - #ifdef CONFIG_PLATFORM_MSTAR_SCAN_BEFORE_CONNECT printk("MStar Android!\n"); if (pwdev_priv->bandroid_scan == _FALSE) { @@ -4074,42 +4304,11 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, goto cancel_ps_deny; } - /* Abort previous connect */ - if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) - || pwdev_priv->connect_req) { - padapter->mlmeextpriv.join_abort = 1; - RTW_PRINT(FUNC_ADPT_FMT": to_join is %s\n", - FUNC_ADPT_ARG(padapter), - (pmlmepriv->to_join == _TRUE)?"true":"false"); - RTW_PRINT(FUNC_ADPT_FMT": fw_state=0x%08x\n", - FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv)); - RTW_PRINT(FUNC_ADPT_FMT": under linking is %s\n", - FUNC_ADPT_ARG(padapter), - (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)?"true":"false"); - RTW_PRINT(FUNC_ADPT_FMT": linked is %s\n", - FUNC_ADPT_ARG(padapter), - (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)?"true":"false"); - if (pmlmepriv->to_join == _TRUE) { - pmlmepriv->to_join = _FALSE; - RTW_PRINT(FUNC_ADPT_FMT": change to_join to false\n", - FUNC_ADPT_ARG(padapter)); - } - - _enter_critical_bh(&pwdev_priv->connect_req_lock, &irqL); - if (pwdev_priv->connect_req) { - RTW_PRINT(FUNC_ADPT_FMT": connect_req exist!!\n", - FUNC_ADPT_ARG(padapter)); - rtw_mfree((u8*)pwdev_priv->connect_req, sizeof(*pwdev_priv->connect_req)); - pwdev_priv->connect_req = NULL; - } - _exit_critical_bh(&pwdev_priv->connect_req_lock, &irqL); - } - rtw_mi_scan_abort(padapter, _TRUE); rtw_join_abort_timeout(padapter, 300); #ifdef CONFIG_CONCURRENT_MODE - if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING)) { + if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING)) { ret = -EINVAL; goto cancel_ps_deny; } @@ -4254,6 +4453,10 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, /* rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */ +#ifdef CONFIG_RTW_MBO + rtw_mbo_update_ie_data(padapter, (u8 *)sme->ie, sme->ie_len); +#endif + if (rtw_set_802_11_connect(padapter, (u8 *)sme->bssid, &ndis_ssid, \ sme->channel ? sme->channel->hw_value : 0) == _FALSE) { ret = -1; @@ -4306,7 +4509,12 @@ static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev, rtw_wdev_set_not_indic_disco(adapter_wdev_data(padapter), 1); #endif - _rtw_disconnect(wiphy, ndev); + rtw_set_to_roam(padapter, 0); + + /* if(check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) */ + { + _rtw_disconnect(wiphy, ndev); + } #if (RTW_CFG80211_BLOCK_STA_DISCON_EVENT & RTW_CFG80211_BLOCK_DISCON_WHEN_DISCONNECT) rtw_wdev_set_not_indic_disco(adapter_wdev_data(padapter), 0); @@ -4317,6 +4525,7 @@ static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev, } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) +#ifdef CONFIG_RTW_DEBUG static const char *nl80211_tx_power_setting_str(int type) { switch (type) { @@ -4330,6 +4539,7 @@ static const char *nl80211_tx_power_setting_str(int type) return "UNKNOWN"; }; } +#endif /* CONFIG_RTW_DEBUG */ static int cfg80211_rtw_set_txpower(struct wiphy *wiphy, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) @@ -4405,12 +4615,12 @@ static int cfg80211_rtw_get_txpower(struct wiphy *wiphy, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) if (wdev && wdev_to_ndev(wdev)) { _adapter *adapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev)); - mbm = rtw_adapter_get_oper_txpwr_max_mbm(adapter); + mbm = rtw_adapter_get_oper_txpwr_max_mbm(adapter, 1); RTW_INFO(FUNC_ADPT_FMT" total max: %d mbm\n", FUNC_ADPT_ARG(adapter), mbm); } else #endif { - mbm = rtw_get_oper_txpwr_max_mbm(dvobj); + mbm = rtw_get_oper_txpwr_max_mbm(dvobj, 1); RTW_INFO(FUNC_WIPHY_FMT" total max: %d mbm\n", FUNC_WIPHY_ARG(wiphy), mbm); } @@ -4423,7 +4633,9 @@ static int cfg80211_rtw_get_txpower(struct wiphy *wiphy, inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter) { struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(adapter); - return rtw_wdev_priv->power_mgmt; + struct wireless_dev *wdev = rtw_wdev_priv->rtw_wdev; + + return wdev->ps; } static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy, @@ -4431,13 +4643,10 @@ static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy, bool enabled, int timeout) { _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); - struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(padapter); RTW_INFO(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev), enabled, timeout); - rtw_wdev_priv->power_mgmt = enabled; - #ifdef CONFIG_LPS if (!enabled) rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE_CFG80211_PWRMGMT, 0); @@ -4461,7 +4670,6 @@ static void _rtw_set_pmksa(struct net_device *ndev, _rtw_memcpy(psecuritypriv->PMKIDList[index].PMKID, pmkid, WLAN_PMKID_LEN); psecuritypriv->PMKIDList[index].bUsed = _TRUE; - psecuritypriv->PMKIDIndex = index + 1; blInserted = _TRUE; break; } @@ -4491,7 +4699,7 @@ static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy, struct mlme_priv *mlme = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; u8 strZeroMacAddress[ETH_ALEN] = { 0x00 }; - bool sae_auth = rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE); + bool sae_auth = rtw_sec_chk_auth_type(padapter, MLME_AUTHTYPE_SAE); RTW_INFO(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev) , MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid)); @@ -4499,11 +4707,6 @@ static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy, if (_rtw_memcmp((u8 *)pmksa->bssid, strZeroMacAddress, ETH_ALEN) == _TRUE) return -EINVAL; - if (check_fwstate(mlme, _FW_LINKED) == _FALSE && !sae_auth) { - RTW_INFO(FUNC_NDEV_FMT" not set pmksa cause not in linked state\n", FUNC_NDEV_ARG(ndev)); - return -EINVAL; - } - _rtw_set_pmksa(ndev, (u8 *)pmksa->bssid, (u8 *)pmksa->pmkid); if (sae_auth && @@ -4561,114 +4764,6 @@ static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy, return 0; } -#ifdef CONFIG_AP_MODE -void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len) -{ -#if !defined(RTW_USE_CFG80211_STA_EVENT) && !defined(COMPAT_KERNEL_RELEASE) - s32 freq; - int channel; - struct wireless_dev *pwdev = padapter->rtw_wdev; - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); -#endif - struct net_device *ndev = padapter->pnetdev; - - RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); - -#if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE) - { - struct station_info sinfo; - u8 ie_offset; - if (get_frame_sub_type(pmgmt_frame) == WIFI_ASSOCREQ) - ie_offset = _ASOCREQ_IE_OFFSET_; - else /* WIFI_REASSOCREQ */ - ie_offset = _REASOCREQ_IE_OFFSET_; - - memset(&sinfo, 0, sizeof(sinfo)); - sinfo.filled = STATION_INFO_ASSOC_REQ_IES; - sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset; - sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset; - cfg80211_new_sta(ndev, get_addr2_ptr(pmgmt_frame), &sinfo, GFP_ATOMIC); - } -#else /* defined(RTW_USE_CFG80211_STA_EVENT) */ - channel = pmlmeext->cur_channel; - freq = rtw_ch2freq(channel); - - #ifdef COMPAT_KERNEL_RELEASE - rtw_cfg80211_rx_mgmt(pwdev, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC); - #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) - rtw_cfg80211_rx_mgmt(pwdev, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC); - #else /* COMPAT_KERNEL_RELEASE */ - { - /* to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc() */ - #ifndef CONFIG_PLATFORM_MSTAR - pwdev->iftype = NL80211_IFTYPE_STATION; - #endif /* CONFIG_PLATFORM_MSTAR */ - RTW_INFO("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype); - rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len); - RTW_INFO("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype); - pwdev->iftype = NL80211_IFTYPE_AP; - /* cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC); */ - } - #endif /* COMPAT_KERNEL_RELEASE */ -#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ - -} - -void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, const u8 *da, unsigned short reason) -{ -#if !defined(RTW_USE_CFG80211_STA_EVENT) && !defined(COMPAT_KERNEL_RELEASE) - s32 freq; - int channel; - u8 *pmgmt_frame; - uint frame_len; - struct rtw_ieee80211_hdr *pwlanhdr; - unsigned short *fctrl; - u8 mgmt_buf[128] = {0}; - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct wireless_dev *wdev = padapter->rtw_wdev; -#endif - struct net_device *ndev = padapter->pnetdev; - - RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); - -#if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE) - cfg80211_del_sta(ndev, da, GFP_ATOMIC); -#else /* defined(RTW_USE_CFG80211_STA_EVENT) */ - channel = pmlmeext->cur_channel; - freq = rtw_ch2freq(channel); - - pmgmt_frame = mgmt_buf; - pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame; - - fctrl = &(pwlanhdr->frame_ctl); - *(fctrl) = 0; - - _rtw_memcpy(pwlanhdr->addr1, adapter_mac_addr(padapter), ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); - - SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); - pmlmeext->mgnt_seq++; - set_frame_sub_type(pmgmt_frame, WIFI_DEAUTH); - - pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr); - frame_len = sizeof(struct rtw_ieee80211_hdr_3addr); - - reason = cpu_to_le16(reason); - pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len); - - #ifdef COMPAT_KERNEL_RELEASE - rtw_cfg80211_rx_mgmt(wdev, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC); - #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) - rtw_cfg80211_rx_mgmt(wdev, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC); - #else /* COMPAT_KERNEL_RELEASE */ - cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len); - /* cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC); */ - #endif /* COMPAT_KERNEL_RELEASE */ -#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ -} - static int rtw_cfg80211_monitor_if_open(struct net_device *ndev) { int ret = 0; @@ -4830,7 +4925,6 @@ dump: pattrib->seqnum = pmlmeext->mgnt_seq; pmlmeext->mgnt_seq++; - pattrib->last_txcmdsz = pattrib->pktlen; dump_mgntframe(padapter, pmgntframe); @@ -4958,167 +5052,112 @@ out: return ret; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) -static struct wireless_dev * -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE) -static struct net_device * -#else -static int -#endif - cfg80211_rtw_add_virtual_intf( - struct wiphy *wiphy, - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)) - const char *name, - #else - char *name, - #endif - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) - unsigned char name_assign_type, - #endif - enum nl80211_iftype type, - #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) - u32 *flags, - #endif - struct vif_params *params) +#ifdef CONFIG_AP_MODE +void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len) { - int ret = 0; - struct wireless_dev *wdev = NULL; - struct net_device *ndev = NULL; - _adapter *padapter; - struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy); - - rtw_set_rtnl_lock_holder(dvobj, current); - - RTW_INFO(FUNC_WIPHY_FMT" name:%s, type:%d\n", FUNC_WIPHY_ARG(wiphy), name, type); - - switch (type) { - case NL80211_IFTYPE_MONITOR: - padapter = wiphy_to_adapter(wiphy); /* TODO: get ap iface ? */ - ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev); - if (ret == 0) - wdev = ndev->ieee80211_ptr; - break; - -#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)) - case NL80211_IFTYPE_P2P_CLIENT: - case NL80211_IFTYPE_P2P_GO: +#if !defined(RTW_USE_CFG80211_STA_EVENT) && !defined(COMPAT_KERNEL_RELEASE) + s32 freq; + int channel; + struct wireless_dev *pwdev = padapter->rtw_wdev; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); #endif - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_AP: -#ifdef CONFIG_RTW_MESH - case NL80211_IFTYPE_MESH_POINT: -#endif - padapter = dvobj_get_unregisterd_adapter(dvobj); - if (!padapter) { - RTW_WARN("adapter pool empty!\n"); - ret = -ENODEV; - break; - } + struct net_device *ndev = padapter->pnetdev; - #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P) - #if defined(CONFIG_P2P) && ((KERNEL_VERSION(2, 6, 37) <= LINUX_VERSION_CODE) || defined(COMPAT_KERNEL_RELEASE)) - if ((type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO) && (padapter->iface_id != padapter->registrypriv.sel_p2p_iface)) { - RTW_ERR("%s, iface_id:%d is not P2P interface!\n", __func__, padapter->iface_id); - ret = -EOPNOTSUPP; - break; - } - #endif - #endif + RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); - if (rtw_os_ndev_init(padapter, name) != _SUCCESS) { - RTW_WARN("ndev init fail!\n"); - ret = -ENODEV; - break; - } - #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)) - if (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO) - rtw_p2p_enable(padapter, P2P_ROLE_DEVICE); - #endif - ndev = padapter->pnetdev; - wdev = ndev->ieee80211_ptr; - break; +#if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE) + { + struct station_info sinfo; + u8 ie_offset; + if (get_frame_sub_type(pmgmt_frame) == WIFI_ASSOCREQ) + ie_offset = _ASOCREQ_IE_OFFSET_; + else /* WIFI_REASSOCREQ */ + ie_offset = _REASOCREQ_IE_OFFSET_; -#if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE) - case NL80211_IFTYPE_P2P_DEVICE: - ret = rtw_pd_iface_alloc(wiphy, name, &wdev); - break; -#endif - - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_AP_VLAN: - case NL80211_IFTYPE_WDS: - default: - ret = -ENODEV; - RTW_INFO("Unsupported interface type\n"); - break; + memset(&sinfo, 0, sizeof(sinfo)); + sinfo.filled = STATION_INFO_ASSOC_REQ_IES; + sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset; + sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset; + cfg80211_new_sta(ndev, get_addr2_ptr(pmgmt_frame), &sinfo, GFP_ATOMIC); } +#else /* defined(RTW_USE_CFG80211_STA_EVENT) */ + channel = pmlmeext->cur_channel; + freq = rtw_ch2freq(channel); - if (ndev) - RTW_INFO(FUNC_WIPHY_FMT" ndev:%p, ret:%d\n", FUNC_WIPHY_ARG(wiphy), ndev, ret); - else - RTW_INFO(FUNC_WIPHY_FMT" wdev:%p, ret:%d\n", FUNC_WIPHY_ARG(wiphy), wdev, ret); + #ifdef COMPAT_KERNEL_RELEASE + rtw_cfg80211_rx_mgmt(pwdev, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC); + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + rtw_cfg80211_rx_mgmt(pwdev, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC); + #else /* COMPAT_KERNEL_RELEASE */ + { + /* to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc() */ + #ifndef CONFIG_PLATFORM_MSTAR + pwdev->iftype = NL80211_IFTYPE_STATION; + #endif /* CONFIG_PLATFORM_MSTAR */ + RTW_INFO("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype); + rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len); + RTW_INFO("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype); + pwdev->iftype = NL80211_IFTYPE_AP; + /* cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC); */ + } + #endif /* COMPAT_KERNEL_RELEASE */ +#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ - rtw_set_rtnl_lock_holder(dvobj, NULL); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) - return wdev ? wdev : ERR_PTR(ret); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE) - return ndev ? ndev : ERR_PTR(ret); -#else - return ret; -#endif } -static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) - struct wireless_dev *wdev -#else - struct net_device *ndev -#endif -) +void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, const u8 *da, unsigned short reason) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) - struct net_device *ndev = wdev_to_ndev(wdev); +#if !defined(RTW_USE_CFG80211_STA_EVENT) && !defined(COMPAT_KERNEL_RELEASE) + s32 freq; + int channel; + u8 *pmgmt_frame; + uint frame_len; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + u8 mgmt_buf[128] = {0}; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct wireless_dev *wdev = padapter->rtw_wdev; #endif - int ret = 0; - struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy); - _adapter *adapter; - struct rtw_wdev_priv *pwdev_priv; + struct net_device *ndev = padapter->pnetdev; - rtw_set_rtnl_lock_holder(dvobj, current); + RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); - if (ndev) { - adapter = (_adapter *)rtw_netdev_priv(ndev); - pwdev_priv = adapter_wdev_data(adapter); +#if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE) + cfg80211_del_sta(ndev, da, GFP_ATOMIC); +#else /* defined(RTW_USE_CFG80211_STA_EVENT) */ + channel = pmlmeext->cur_channel; + freq = rtw_ch2freq(channel); - if (ndev == pwdev_priv->pmon_ndev) { - unregister_netdevice(ndev); - pwdev_priv->pmon_ndev = NULL; - pwdev_priv->ifname_mon[0] = '\0'; - RTW_INFO(FUNC_NDEV_FMT" remove monitor ndev\n", FUNC_NDEV_ARG(ndev)); - } else { - RTW_INFO(FUNC_NDEV_FMT" unregister ndev\n", FUNC_NDEV_ARG(ndev)); - rtw_os_ndev_unregister(adapter); - } - } else -#if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE) - if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) { - if (wdev == wiphy_to_pd_wdev(wiphy)) - rtw_pd_iface_free(wiphy); - else { - RTW_ERR(FUNC_WIPHY_FMT" unknown P2P Device wdev:%p\n", FUNC_WIPHY_ARG(wiphy), wdev); - rtw_warn_on(1); - } - } else -#endif - { - ret = -EINVAL; - goto exit; - } + pmgmt_frame = mgmt_buf; + pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame; -exit: - rtw_set_rtnl_lock_holder(dvobj, NULL); - return ret; + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + _rtw_memcpy(pwlanhdr->addr1, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + set_frame_sub_type(pmgmt_frame, WIFI_DEAUTH); + + pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr); + frame_len = sizeof(struct rtw_ieee80211_hdr_3addr); + + reason = cpu_to_le16(reason); + pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len); + + #ifdef COMPAT_KERNEL_RELEASE + rtw_cfg80211_rx_mgmt(wdev, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC); + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + rtw_cfg80211_rx_mgmt(wdev, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC); + #else /* COMPAT_KERNEL_RELEASE */ + cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len); + /* cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC); */ + #endif /* COMPAT_KERNEL_RELEASE */ +#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ } static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len) @@ -5284,12 +5323,13 @@ static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev, goto exit; } - /* - Kernel < v5.1, the auth_type set as NL80211_AUTHTYPE_AUTOMATIC. - if the AKM SAE in the RSN IE, we have to update the auth_type for SAE - in rtw_check_beacon_data(). - */ - rtw_cfg80211_set_auth_type(&adapter->securitypriv, settings->auth_type); + /* Kernel < v5.x, the auth_type set as NL80211_AUTHTYPE_AUTOMATIC. if + * the AKM SAE in the RSN IE, we have to update the auth_type for SAE in + * rtw_check_beacon_data(). + * + * we only update auth_type when rtw_check_beacon_data() + */ + /* rtw_cfg80211_set_auth_type(&adapter->securitypriv, settings->auth_type); */ rtw_mi_scan_abort(adapter, _TRUE); rtw_mi_buddy_set_scan_deny(adapter, 300); @@ -5655,7 +5695,7 @@ static int cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev goto release_plink_ctl; } - if (!rtw_bss_is_candidate_mesh_peer(&padapter->mlmepriv.cur_network.network, &scanned->network, 1, 1)) { + if (!rtw_bss_is_candidate_mesh_peer(padapter, &scanned->network, 1, 1)) { RTW_WARN(FUNC_NDEV_FMT" corresponding network is not candidate with same ch\n" , FUNC_NDEV_ARG(ndev)); ret = -EINVAL; @@ -5756,7 +5796,7 @@ static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev RTW_INFO("+"FUNC_NDEV_FMT" mac=%pM\n", FUNC_NDEV_ARG(ndev), target_mac); - if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE | WIFI_MESH_STATE)) != _TRUE) { + if (check_fwstate(pmlmepriv, (WIFI_ASOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE)) != _TRUE) { RTW_INFO("%s, fw_state != FW_LINKED|WIFI_AP_STATE|WIFI_MESH_STATE\n", __func__); return -EINVAL; } @@ -5794,13 +5834,33 @@ static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev plist = get_next(plist); if (_rtw_memcmp((u8 *)target_mac, psta->cmn.mac_addr, ETH_ALEN)) { - if (psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE) + if (psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE) { RTW_INFO("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__); - else { + + #ifdef CONFIG_AP_MODE + if (MLME_IS_AP(padapter)) { + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + #ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (psta->tbtx_enable) + pstapriv->tbtx_asoc_list_cnt--; + #endif + STA_SET_MESH_PLINK(psta, NULL); + + ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_IEEE_802_1X_AUTH_FAILED, _TRUE); + psta = NULL; + break; + } + #endif + } else { RTW_INFO("free psta=%p, aid=%d\n", psta, psta->cmn.aid); rtw_list_delete(&psta->asoc_list); pstapriv->asoc_list_cnt--; + #ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (psta->tbtx_enable) + pstapriv->tbtx_asoc_list_cnt--; + #endif STA_SET_MESH_PLINK(psta, NULL); /* _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); */ @@ -5842,26 +5902,17 @@ static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *n #endif struct station_parameters *params) { -#ifdef CONFIG_RTW_MESH _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev); - struct sta_priv *stapriv = &adapter->stapriv; - struct sta_info *sta = NULL; - _irqL irqL; -#endif int ret = 0; - RTW_INFO(FUNC_NDEV_FMT" mac:"MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac)); + RTW_INFO(FUNC_ADPT_FMT" mac:"MAC_FMT"\n", FUNC_ADPT_ARG(adapter), MAC_ARG(mac)); dump_station_parameters(RTW_DBGDUMP, wiphy, params); #ifdef CONFIG_RTW_MESH if (MLME_IS_MESH(adapter)) { enum cfg80211_station_type sta_type = CFG80211_STA_MESH_PEER_USER; - struct rtw_mesh_info *minfo = &adapter->mesh_info; - struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl; - struct mesh_plink_ent *plink = NULL; - _irqL irqL2; - struct sta_info *del_sta = NULL; + u8 plink_state = nl80211_plink_state_to_rtw_plink_state(params->plink_state); ret = cfg80211_check_station_change(wiphy, params, sta_type); if (ret) { @@ -5869,100 +5920,20 @@ static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *n goto exit; } - _enter_critical_bh(&(plink_ctl->lock), &irqL2); - - plink = _rtw_mesh_plink_get(adapter, mac); - if (!plink) { - ret = -ENOENT; - goto release_plink_ctl; - } - - plink->plink_state = nl80211_plink_state_to_rtw_plink_state(params->plink_state); - - #if CONFIG_RTW_MESH_ACNODE_PREVENT - if (params->plink_state == NL80211_PLINK_OPN_SNT - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) - && (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) - #endif - ) { - if (rtw_mesh_scanned_is_acnode_confirmed(adapter, plink->scanned) - && rtw_mesh_acnode_prevent_allow_sacrifice(adapter) - ) { - struct sta_info *sac = rtw_mesh_acnode_prevent_pick_sacrifice(adapter); - - if (sac) { - del_sta = sac; - _enter_critical_bh(&stapriv->asoc_list_lock, &irqL); - if (!rtw_is_list_empty(&del_sta->asoc_list)) { - rtw_list_delete(&del_sta->asoc_list); - stapriv->asoc_list_cnt--; - STA_SET_MESH_PLINK(del_sta, NULL); - } - _exit_critical_bh(&stapriv->asoc_list_lock, &irqL); - RTW_INFO(FUNC_ADPT_FMT" sacrifice "MAC_FMT" for acnode\n" - , FUNC_ADPT_ARG(adapter), MAC_ARG(del_sta->cmn.mac_addr)); - } - } - } else + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) + if (!(params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)) + goto exit; #endif - if ((params->plink_state == NL80211_PLINK_OPN_RCVD - || params->plink_state == NL80211_PLINK_CNF_RCVD - || params->plink_state == NL80211_PLINK_ESTAB) - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) - && (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) - #endif - ) { - sta = rtw_get_stainfo(stapriv, mac); - if (!sta) { - sta = rtw_alloc_stainfo(stapriv, mac); - if (!sta) - goto release_plink_ctl; - } - if (params->plink_state == NL80211_PLINK_ESTAB) { - if (rtw_mesh_peer_establish(adapter, plink, sta) != _SUCCESS) { - rtw_free_stainfo(adapter, sta); - ret = -ENOENT; - goto release_plink_ctl; - } - } - } - else if (params->plink_state == NL80211_PLINK_HOLDING - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) - && (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) - #endif - ) { - del_sta = rtw_get_stainfo(stapriv, mac); - if (!del_sta) - goto release_plink_ctl; - - _enter_critical_bh(&stapriv->asoc_list_lock, &irqL); - if (!rtw_is_list_empty(&del_sta->asoc_list)) { - rtw_list_delete(&del_sta->asoc_list); - stapriv->asoc_list_cnt--; - STA_SET_MESH_PLINK(del_sta, NULL); - } - _exit_critical_bh(&stapriv->asoc_list_lock, &irqL); - } - -release_plink_ctl: - _exit_critical_bh(&(plink_ctl->lock), &irqL2); - - if (del_sta) { - u8 sta_addr[ETH_ALEN]; - u8 updated = _FALSE; - - _rtw_memcpy(sta_addr, del_sta->cmn.mac_addr, ETH_ALEN); - updated = ap_free_sta(adapter, del_sta, 0, 0, 1); - rtw_mesh_expire_peer(stapriv->padapter, sta_addr); - - associated_clients_update(adapter, updated, STA_INFO_UPDATE_ALL); - } + if (rtw_mesh_set_plink_state_cmd(adapter, mac, plink_state) != _SUCCESS) + ret = -ENOENT; } exit: #endif /* CONFIG_RTW_MESH */ + if (ret) + RTW_INFO(FUNC_ADPT_FMT" mac:"MAC_FMT" ret:%d\n", FUNC_ADPT_ARG(adapter), MAC_ARG(mac), ret); return ret; } @@ -6241,105 +6212,6 @@ static int cfg80211_rtw_set_channel(struct wiphy *wiphy } #endif /*#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))*/ -static int cfg80211_rtw_set_monitor_channel(struct wiphy *wiphy -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) - , struct cfg80211_chan_def *chandef -#else - , struct ieee80211_channel *chan - , enum nl80211_channel_type channel_type -#endif -) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) - struct ieee80211_channel *chan = chandef->chan; -#endif - - _adapter *padapter = wiphy_to_adapter(wiphy); - int target_channal = chan->hw_value; - int target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - int target_width = CHANNEL_WIDTH_20; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) -#ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("center_freq %u Mhz ch %u width %u freq1 %u freq2 %u\n" - , chan->center_freq - , chan->hw_value - , chandef->width - , chandef->center_freq1 - , chandef->center_freq2); -#endif /* CONFIG_DEBUG_CFG80211 */ - - switch (chandef->width) { - case NL80211_CHAN_WIDTH_20_NOHT: - /* fall through */ - case NL80211_CHAN_WIDTH_20: - target_width = CHANNEL_WIDTH_20; - target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - break; - case NL80211_CHAN_WIDTH_40: - target_width = CHANNEL_WIDTH_40; - if (chandef->center_freq1 > chan->center_freq) - target_offset = HAL_PRIME_CHNL_OFFSET_LOWER; - else - target_offset = HAL_PRIME_CHNL_OFFSET_UPPER; - break; - case NL80211_CHAN_WIDTH_80: - target_width = CHANNEL_WIDTH_80; - target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - break; - case NL80211_CHAN_WIDTH_80P80: - target_width = CHANNEL_WIDTH_80_80; - target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - break; - case NL80211_CHAN_WIDTH_160: - target_width = CHANNEL_WIDTH_160; - target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - break; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) - case NL80211_CHAN_WIDTH_5: - case NL80211_CHAN_WIDTH_10: -#endif - default: - target_width = CHANNEL_WIDTH_20; - target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - break; - } -#else -#ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("center_freq %u Mhz ch %u channel_type %u\n" - , chan->center_freq - , chan->hw_value - , channel_type); -#endif /* CONFIG_DEBUG_CFG80211 */ - - switch (channel_type) { - case NL80211_CHAN_NO_HT: - case NL80211_CHAN_HT20: - target_width = CHANNEL_WIDTH_20; - target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - break; - case NL80211_CHAN_HT40MINUS: - target_width = CHANNEL_WIDTH_40; - target_offset = HAL_PRIME_CHNL_OFFSET_UPPER; - break; - case NL80211_CHAN_HT40PLUS: - target_width = CHANNEL_WIDTH_40; - target_offset = HAL_PRIME_CHNL_OFFSET_LOWER; - break; - default: - target_width = CHANNEL_WIDTH_20; - target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - break; - } -#endif - RTW_INFO(FUNC_ADPT_FMT" ch:%d bw:%d, offset:%d\n" - , FUNC_ADPT_ARG(padapter), target_channal, target_width, target_offset); - - rtw_set_chbw_cmd(padapter, target_channal, target_width, target_offset, RTW_CMDF_WAIT_ACK); - - return 0; -} /* static int cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_auth_request *req) @@ -6357,8 +6229,661 @@ static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev, return 0; } */ + +static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len) +{ + int ret = 0; + uint wps_ielen = 0; + u8 *wps_ie; + u32 p2p_ielen = 0; + u8 wps_oui[8] = {0x0, 0x50, 0xf2, 0x04}; + u8 *p2p_ie; + u32 wfd_ielen = 0; + u8 *wfd_ie; + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + + RTW_INFO(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len); + + if (len > 0) { + wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen); + if (wps_ie) { + #ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("bcn_wps_ielen=%d\n", wps_ielen); + #endif + + if (pmlmepriv->wps_beacon_ie) { + u32 free_len = pmlmepriv->wps_beacon_ie_len; + pmlmepriv->wps_beacon_ie_len = 0; + rtw_mfree(pmlmepriv->wps_beacon_ie, free_len); + pmlmepriv->wps_beacon_ie = NULL; + } + + pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen); + if (pmlmepriv->wps_beacon_ie == NULL) { + RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + + _rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen); + pmlmepriv->wps_beacon_ie_len = wps_ielen; + + update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE, RTW_CMDF_WAIT_ACK); + + } + + /* buf += wps_ielen; */ + /* len -= wps_ielen; */ + + #ifdef CONFIG_P2P + p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen); + if (p2p_ie) { + #ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("bcn_p2p_ielen=%d\n", p2p_ielen); + #endif + + if (pmlmepriv->p2p_beacon_ie) { + u32 free_len = pmlmepriv->p2p_beacon_ie_len; + pmlmepriv->p2p_beacon_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len); + pmlmepriv->p2p_beacon_ie = NULL; + } + + pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen); + if (pmlmepriv->p2p_beacon_ie == NULL) { + RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + + _rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen); + pmlmepriv->p2p_beacon_ie_len = p2p_ielen; + + } + #endif /* CONFIG_P2P */ + + + #ifdef CONFIG_WFD + wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen); + if (wfd_ie) { + #ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("bcn_wfd_ielen=%d\n", wfd_ielen); + #endif + + if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_BEACON_IE, wfd_ie, wfd_ielen) != _SUCCESS) + return -EINVAL; + } + #endif /* CONFIG_WFD */ + + pmlmeext->bstart_bss = _TRUE; + + } + + return ret; + +} + +static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len) +{ + int ret = 0; + uint wps_ielen = 0; + u8 *wps_ie; + u32 p2p_ielen = 0; + u8 *p2p_ie; + u32 wfd_ielen = 0; + u8 *wfd_ie; + _adapter *padapter = (_adapter *)rtw_netdev_priv(net); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + +#ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("%s, ielen=%d\n", __func__, len); +#endif + + if (len > 0) { + wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen); + if (wps_ie) { + uint attr_contentlen = 0; + u16 uconfig_method, *puconfig_method = NULL; + + #ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("probe_resp_wps_ielen=%d\n", wps_ielen); + #endif + + if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) { + u8 sr = 0; + rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL); + + if (sr != 0) + RTW_INFO("%s, got sr\n", __func__); + else { + RTW_INFO("GO mode process WPS under site-survey, sr no set\n"); + return ret; + } + } + + if (pmlmepriv->wps_probe_resp_ie) { + u32 free_len = pmlmepriv->wps_probe_resp_ie_len; + pmlmepriv->wps_probe_resp_ie_len = 0; + rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len); + pmlmepriv->wps_probe_resp_ie = NULL; + } + + pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen); + if (pmlmepriv->wps_probe_resp_ie == NULL) { + RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + + /* add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode */ + puconfig_method = (u16 *)rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen); + if (puconfig_method != NULL) { + /* struct registry_priv *pregistrypriv = &padapter->registrypriv; */ + struct wireless_dev *wdev = padapter->rtw_wdev; + + #ifdef CONFIG_DEBUG_CFG80211 + /* printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method)); */ + #endif + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE) + /* for WIFI-DIRECT LOGO 4.2.2, AUTO GO can't set PUSH_BUTTON flags */ + if (wdev->iftype == NL80211_IFTYPE_P2P_GO) { + uconfig_method = WPS_CM_PUSH_BUTTON; + uconfig_method = cpu_to_be16(uconfig_method); + + *puconfig_method &= ~uconfig_method; + } + #endif + } + + _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen); + pmlmepriv->wps_probe_resp_ie_len = wps_ielen; + + } + + /* buf += wps_ielen; */ + /* len -= wps_ielen; */ + + #ifdef CONFIG_P2P + p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen); + if (p2p_ie) { + u8 is_GO = _FALSE; + u32 attr_contentlen = 0; + u16 cap_attr = 0; + + #ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("probe_resp_p2p_ielen=%d\n", p2p_ielen); + #endif + + /* Check P2P Capability ATTR */ + if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8 *)&cap_attr, (uint *) &attr_contentlen)) { + u8 grp_cap = 0; + /* RTW_INFO( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ ); */ + cap_attr = le16_to_cpu(cap_attr); + grp_cap = (u8)((cap_attr >> 8) & 0xff); + + is_GO = (grp_cap & BIT(0)) ? _TRUE : _FALSE; + + if (is_GO) + RTW_INFO("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap); + } + + + if (is_GO == _FALSE) { + if (pmlmepriv->p2p_probe_resp_ie) { + u32 free_len = pmlmepriv->p2p_probe_resp_ie_len; + pmlmepriv->p2p_probe_resp_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len); + pmlmepriv->p2p_probe_resp_ie = NULL; + } + + pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen); + if (pmlmepriv->p2p_probe_resp_ie == NULL) { + RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + _rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen); + pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen; + } else { + if (pmlmepriv->p2p_go_probe_resp_ie) { + u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len; + pmlmepriv->p2p_go_probe_resp_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len); + pmlmepriv->p2p_go_probe_resp_ie = NULL; + } + + pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen); + if (pmlmepriv->p2p_go_probe_resp_ie == NULL) { + RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + _rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen); + pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen; + } + + } + #endif /* CONFIG_P2P */ + + + #ifdef CONFIG_WFD + wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen); + #ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("probe_resp_wfd_ielen=%d\n", wfd_ielen); + #endif + + if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_PROBE_RESP_IE, wfd_ie, wfd_ielen) != _SUCCESS) + return -EINVAL; + #endif /* CONFIG_WFD */ + + } + + return ret; + +} + +static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len) +{ + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(net); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 *ie; + u32 ie_len; + + RTW_INFO("%s, ielen=%d\n", __func__, len); + + if (len <= 0) + goto exit; + + ie = rtw_get_wps_ie(buf, len, NULL, &ie_len); + if (ie && ie_len) { + if (pmlmepriv->wps_assoc_resp_ie) { + u32 free_len = pmlmepriv->wps_assoc_resp_ie_len; + + pmlmepriv->wps_assoc_resp_ie_len = 0; + rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len); + pmlmepriv->wps_assoc_resp_ie = NULL; + } + + pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len); + if (pmlmepriv->wps_assoc_resp_ie == NULL) { + RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, ie, ie_len); + pmlmepriv->wps_assoc_resp_ie_len = ie_len; + } +#ifdef CONFIG_P2P + ie = rtw_get_p2p_ie(buf, len, NULL, &ie_len); + if (ie && ie_len) { + if (pmlmepriv->p2p_assoc_resp_ie) { + u32 free_len = pmlmepriv->p2p_assoc_resp_ie_len; + + pmlmepriv->p2p_assoc_resp_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_assoc_resp_ie, free_len); + pmlmepriv->p2p_assoc_resp_ie = NULL; + } + + pmlmepriv->p2p_assoc_resp_ie = rtw_malloc(ie_len); + if (pmlmepriv->p2p_assoc_resp_ie == NULL) { + RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + _rtw_memcpy(pmlmepriv->p2p_assoc_resp_ie, ie, ie_len); + pmlmepriv->p2p_assoc_resp_ie_len = ie_len; + } +#endif +#ifdef CONFIG_WFD + ie = rtw_get_wfd_ie(buf, len, NULL, &ie_len); + if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_ASSOC_RESP_IE, ie, ie_len) != _SUCCESS) + return -EINVAL; +#endif + +exit: + return ret; +} + +int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len, + int type) +{ + int ret = 0; + uint wps_ielen = 0; + u32 p2p_ielen = 0; + +#ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("%s, ielen=%d\n", __func__, len); +#endif + + if ((rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen > 0)) + #ifdef CONFIG_P2P + || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen > 0)) + #endif + ) { + if (net != NULL) { + switch (type) { + case 0x1: /* BEACON */ + ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len); + break; + case 0x2: /* PROBE_RESP */ + ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len); + #ifdef CONFIG_P2P + if (ret == 0) + adapter_wdev_data((_adapter *)rtw_netdev_priv(net))->probe_resp_ie_update_time = rtw_get_current_time(); + #endif + break; + case 0x4: /* ASSOC_RESP */ + ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len); + break; + } + } + } + + return ret; + +} #endif /* CONFIG_AP_MODE */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) +static struct wireless_dev * +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE) +static struct net_device * +#else +static int +#endif + cfg80211_rtw_add_virtual_intf( + struct wiphy *wiphy, + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)) + const char *name, + #else + char *name, + #endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) + unsigned char name_assign_type, + #endif + enum nl80211_iftype type, + #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) + u32 *flags, + #endif + struct vif_params *params) +{ + int ret = 0; + struct wireless_dev *wdev = NULL; + struct net_device *ndev = NULL; + _adapter *padapter; + struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy); + + rtw_set_rtnl_lock_holder(dvobj, current); + + RTW_INFO(FUNC_WIPHY_FMT" name:%s, type:%d\n", FUNC_WIPHY_ARG(wiphy), name, type); + + switch (type) { + case NL80211_IFTYPE_MONITOR: + padapter = wiphy_to_adapter(wiphy); /* TODO: get ap iface ? */ + ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev); + if (ret == 0) + wdev = ndev->ieee80211_ptr; + break; + +#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)) + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_P2P_GO: +#endif + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_AP: +#ifdef CONFIG_RTW_MESH + case NL80211_IFTYPE_MESH_POINT: +#endif + padapter = dvobj_get_unregisterd_adapter(dvobj); + if (!padapter) { + RTW_WARN("adapter pool empty!\n"); + ret = -ENODEV; + break; + } + + #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P) + #if defined(CONFIG_P2P) && ((KERNEL_VERSION(2, 6, 37) <= LINUX_VERSION_CODE) || defined(COMPAT_KERNEL_RELEASE)) + if ((type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO) && (padapter->iface_id != padapter->registrypriv.sel_p2p_iface)) { + RTW_ERR("%s, iface_id:%d is not P2P interface!\n", __func__, padapter->iface_id); + ret = -EOPNOTSUPP; + break; + } + #endif + #endif + + if (rtw_os_ndev_init(padapter, name) != _SUCCESS) { + RTW_WARN("ndev init fail!\n"); + ret = -ENODEV; + break; + } + #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)) + if (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO) + rtw_p2p_enable(padapter, P2P_ROLE_DEVICE); + #endif + ndev = padapter->pnetdev; + wdev = ndev->ieee80211_ptr; + break; + +#if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE) + case NL80211_IFTYPE_P2P_DEVICE: + ret = rtw_pd_iface_alloc(wiphy, name, &wdev); + break; +#endif + + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_WDS: + default: + ret = -ENODEV; + RTW_INFO("Unsupported interface type\n"); + break; + } + + if (ndev) + RTW_INFO(FUNC_WIPHY_FMT" ndev:%p, ret:%d\n", FUNC_WIPHY_ARG(wiphy), ndev, ret); + else + RTW_INFO(FUNC_WIPHY_FMT" wdev:%p, ret:%d\n", FUNC_WIPHY_ARG(wiphy), wdev, ret); + + rtw_set_rtnl_lock_holder(dvobj, NULL); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + return wdev ? wdev : ERR_PTR(ret); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE) + return ndev ? ndev : ERR_PTR(ret); +#else + return ret; +#endif +} + +static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + struct wireless_dev *wdev +#else + struct net_device *ndev +#endif +) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + struct net_device *ndev = wdev_to_ndev(wdev); +#endif + int ret = 0; + struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy); + _adapter *adapter; + struct rtw_wdev_priv *pwdev_priv; + + rtw_set_rtnl_lock_holder(dvobj, current); + + if (ndev) { + adapter = (_adapter *)rtw_netdev_priv(ndev); + pwdev_priv = adapter_wdev_data(adapter); + + if (ndev == pwdev_priv->pmon_ndev) { + unregister_netdevice(ndev); + pwdev_priv->pmon_ndev = NULL; + pwdev_priv->ifname_mon[0] = '\0'; + RTW_INFO(FUNC_NDEV_FMT" remove monitor ndev\n", FUNC_NDEV_ARG(ndev)); + } else { + RTW_INFO(FUNC_NDEV_FMT" unregister ndev\n", FUNC_NDEV_ARG(ndev)); + rtw_os_ndev_unregister(adapter); + } + } else +#if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE) + if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) { + if (wdev == wiphy_to_pd_wdev(wiphy)) + rtw_pd_iface_free(wiphy); + else { + RTW_ERR(FUNC_WIPHY_FMT" unknown P2P Device wdev:%p\n", FUNC_WIPHY_ARG(wiphy), wdev); + rtw_warn_on(1); + } + } else +#endif + { + ret = -EINVAL; + goto exit; + } + +exit: + rtw_set_rtnl_lock_holder(dvobj, NULL); + return ret; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) +static int cfg80211_rtw_get_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct cfg80211_chan_def *chandef) +{ + _adapter *padapter = wiphy_to_adapter(wiphy); + struct mlme_ext_priv *mlmeext = &(padapter->mlmeextpriv); + u8 ht_option = 0; + u8 report = 0; + int retval = 1; + + if (MLME_IS_ASOC(padapter)) { +#ifdef CONFIG_80211N_HT + ht_option = padapter->mlmepriv.htpriv.ht_option; +#endif /* CONFIG_80211N_HT */ + report = 1; + } else if (MLME_IS_MONITOR(padapter)) { + /* monitor mode always set to HT + we don't support sniffer No HT */ + ht_option = 1; + report = 1; + } + + if (report) { + rtw_chbw_to_cfg80211_chan_def(wiphy, chandef, + mlmeext->cur_channel, mlmeext->cur_bwmode, + mlmeext->cur_ch_offset, ht_option); + retval = 0; + } + + return retval; +} + +static void rtw_get_chbwoff_from_cfg80211_chan_def( + struct cfg80211_chan_def *chandef, + u8 *ht, u8 *ch, u8 *bw, u8 *offset) +{ + struct ieee80211_channel *chan = chandef->chan; + + *ch = chan->hw_value; + *ht = 1; + + switch (chandef->width) { + case NL80211_CHAN_WIDTH_20_NOHT: + *ht = 0; + /* fall through */ + case NL80211_CHAN_WIDTH_20: + *bw = CHANNEL_WIDTH_20; + *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case NL80211_CHAN_WIDTH_40: + *bw = CHANNEL_WIDTH_40; + *offset = (chandef->center_freq1 > chan->center_freq) ? + HAL_PRIME_CHNL_OFFSET_LOWER : HAL_PRIME_CHNL_OFFSET_UPPER; + break; + case NL80211_CHAN_WIDTH_80: + *bw = CHANNEL_WIDTH_80; + *offset = (chandef->center_freq1 > chan->center_freq) ? + HAL_PRIME_CHNL_OFFSET_LOWER : HAL_PRIME_CHNL_OFFSET_UPPER; + break; + case NL80211_CHAN_WIDTH_160: + *bw = CHANNEL_WIDTH_160; + *offset = (chandef->center_freq1 > chan->center_freq) ? + HAL_PRIME_CHNL_OFFSET_LOWER : HAL_PRIME_CHNL_OFFSET_UPPER; + break; + case NL80211_CHAN_WIDTH_80P80: + *bw = CHANNEL_WIDTH_80_80; + *offset = (chandef->center_freq1 > chan->center_freq) ? + HAL_PRIME_CHNL_OFFSET_LOWER : HAL_PRIME_CHNL_OFFSET_UPPER; + break; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) + case NL80211_CHAN_WIDTH_5: + *bw = CHANNEL_WIDTH_5; + *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case NL80211_CHAN_WIDTH_10: + *bw = CHANNEL_WIDTH_10; + *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; +#endif + default: + *ht = 0; + *bw = CHANNEL_WIDTH_20; + *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + RTW_INFO("unsupported cwidth:%u\n", chandef->width); + rtw_warn_on(1); + }; +} +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) */ + +static int cfg80211_rtw_set_monitor_channel(struct wiphy *wiphy +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) + , struct cfg80211_chan_def *chandef +#else + , struct ieee80211_channel *chan + , enum nl80211_channel_type channel_type +#endif + ) +{ + _adapter *padapter = wiphy_to_adapter(wiphy); + u8 target_channal, target_offset, target_width, ht_option; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) +#ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("center_freq %u Mhz ch %u width %u freq1 %u freq2 %u\n" + , chandef->chan->center_freq + , chandef->chan->hw_value + , chandef->width + , chandef->center_freq1 + , chandef->center_freq2); +#endif /* CONFIG_DEBUG_CFG80211 */ + + rtw_get_chbwoff_from_cfg80211_chan_def(chandef, + &ht_option, &target_channal, &target_width, &target_offset); +#else +#ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("center_freq %u Mhz ch %u channel_type %u\n" + , chan->center_freq + , chan->hw_value + , channel_type); +#endif /* CONFIG_DEBUG_CFG80211 */ + + rtw_get_chbw_from_nl80211_channel_type(chan, channel_type, + &ht_option, &target_channal, &target_width, &target_offset); +#endif + RTW_INFO(FUNC_ADPT_FMT" ch:%d bw:%d, offset:%d\n", + FUNC_ADPT_ARG(padapter), target_channal, + target_width, target_offset); + + rtw_set_chbw_cmd(padapter, target_channal, target_width, + target_offset, RTW_CMDF_WAIT_ACK); + + return 0; +} + void rtw_cfg80211_external_auth_request(_adapter *padapter, union recv_frame *rframe) { struct rtw_external_auth_params params; @@ -6375,11 +6900,8 @@ void rtw_cfg80211_external_auth_request(_adapter *padapter, union recv_frame *rf freq = rtw_ch2freq(pmlmeext->cur_channel); -#ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO(FUNC_ADPT_FMT": freq(%d, %d)\n", FUNC_ADPT_ARG(padapter), freq); -#endif - -#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) \ + || defined(CONFIG_KERNEL_PATCH_EXTERNAL_AUTH) params.action = EXTERNAL_AUTH_START; _rtw_memcpy(params.bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); params.ssid.ssid_len = pmlmeinfo->network.Ssid.SsidLength; @@ -6396,12 +6918,13 @@ void rtw_cfg80211_external_auth_request(_adapter *padapter, union recv_frame *rf _rtw_memcpy(frame + 10, adapter_mac_addr(padapter), ETH_ALEN); _rtw_memcpy(frame + 16, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); RTW_PUT_LE32((frame + 18), 0x8ac0f00); + RTW_PUT_LE32((frame + 24), 0x0003); if (pmlmeinfo->network.Ssid.SsidLength) { - *(frame + 23) = pmlmeinfo->network.Ssid.SsidLength; - _rtw_memcpy(frame + 24, pmlmeinfo->network.Ssid.Ssid, + *(frame + 26) = pmlmeinfo->network.Ssid.SsidLength; + _rtw_memcpy(frame + 27, pmlmeinfo->network.Ssid.Ssid, pmlmeinfo->network.Ssid.SsidLength); - frame_len = 24 + pmlmeinfo->network.Ssid.SsidLength; + frame_len = 27 + pmlmeinfo->network.Ssid.SsidLength; } rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC); #endif @@ -6892,34 +7415,35 @@ static s32 cfg80211_rtw_update_ft_ies(struct wiphy *wiphy, return 0; } #endif +#endif /* CONFIG_P2P */ inline void rtw_cfg80211_set_is_roch(_adapter *adapter, bool val) { - adapter->cfg80211_wdinfo.is_ro_ch = val; + adapter->rochinfo.is_ro_ch = val; rtw_mi_update_iface_status(&(adapter->mlmepriv), 0); } inline bool rtw_cfg80211_get_is_roch(_adapter *adapter) { - return adapter->cfg80211_wdinfo.is_ro_ch; + return adapter->rochinfo.is_ro_ch; } inline bool rtw_cfg80211_is_ro_ch_once(_adapter *adapter) { - return adapter->cfg80211_wdinfo.last_ro_ch_time ? 1 : 0; + return adapter->rochinfo.last_ro_ch_time ? 1 : 0; } inline void rtw_cfg80211_set_last_ro_ch_time(_adapter *adapter) { - adapter->cfg80211_wdinfo.last_ro_ch_time = rtw_get_current_time(); + adapter->rochinfo.last_ro_ch_time = rtw_get_current_time(); - if (!adapter->cfg80211_wdinfo.last_ro_ch_time) - adapter->cfg80211_wdinfo.last_ro_ch_time++; + if (!adapter->rochinfo.last_ro_ch_time) + adapter->rochinfo.last_ro_ch_time++; } inline s32 rtw_cfg80211_get_last_ro_ch_passing_ms(_adapter *adapter) { - return rtw_get_passing_time_ms(adapter->cfg80211_wdinfo.last_ro_ch_time); + return rtw_get_passing_time_ms(adapter->rochinfo.last_ro_ch_time); } static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, @@ -6938,11 +7462,13 @@ static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq); _adapter *padapter = NULL; struct rtw_wdev_priv *pwdev_priv; + struct roch_info *prochinfo; +#ifdef CONFIG_P2P struct wifidirect_info *pwdinfo; - struct cfg80211_wifidirect_info *pcfg80211_wdinfo; #ifdef CONFIG_CONCURRENT_MODE u8 is_p2p_find = _FALSE; #endif +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) #if defined(RTW_DEDICATED_P2P_DEVICE) @@ -6968,13 +7494,15 @@ static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, #endif pwdev_priv = adapter_wdev_data(padapter); + prochinfo = &padapter->rochinfo; +#ifdef CONFIG_P2P pwdinfo = &padapter->wdinfo; - pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; #ifdef CONFIG_CONCURRENT_MODE is_p2p_find = (duration < (pwdinfo->ext_listen_interval)) ? _TRUE : _FALSE; +#endif #endif - *cookie = ATOMIC_INC_RETURN(&pcfg80211_wdinfo->ro_ch_cookie_gen); + *cookie = ATOMIC_INC_RETURN(&prochinfo->ro_ch_cookie_gen); RTW_INFO(FUNC_ADPT_FMT"%s ch:%u duration:%d, cookie:0x%llx\n" , FUNC_ADPT_ARG(padapter), wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : "" @@ -7000,17 +7528,18 @@ static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, } rtw_scan_abort(padapter); -#ifdef CONFIG_CONCURRENT_MODE +#if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P) /*don't scan_abort during p2p_listen.*/ if (is_p2p_find) rtw_mi_buddy_scan_abort(padapter, _TRUE); -#endif /*CONFIG_CONCURRENT_MODE*/ +#endif /* defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P) */ if (rtw_cfg80211_get_is_roch(padapter) == _TRUE) { - _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer); - p2p_cancel_roch_cmd(padapter, 0, NULL, RTW_CMDF_WAIT_ACK); + _cancel_timer_ex(&padapter->rochinfo.remain_on_ch_timer); + rtw_cancel_roch_cmd(padapter, 0, NULL, RTW_CMDF_WAIT_ACK); } +#ifdef CONFIG_P2P /* if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) */ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P) @@ -7038,32 +7567,31 @@ static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, } rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); +#endif /* CONFIG_P2P */ #ifdef RTW_ROCH_DURATION_ENLARGE if (duration < 400) duration = duration * 3; /* extend from exper */ #endif -#if defined(RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE) +#if defined(RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P) if (rtw_mi_check_status(padapter, MI_LINKED)) { if (is_p2p_find) /* p2p_find , duration<1000 */ duration = duration + pwdinfo->ext_listen_interval; - else /* p2p_listen, duration=5000 */ - duration = pwdinfo->ext_listen_interval + (pwdinfo->ext_listen_interval / 4); } -#endif /*defined (RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE) */ +#endif /* defined (RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P) */ rtw_cfg80211_set_is_roch(padapter, _TRUE); - pcfg80211_wdinfo->ro_ch_wdev = wdev; - pcfg80211_wdinfo->remain_on_ch_cookie = *cookie; + prochinfo->ro_ch_wdev = wdev; + prochinfo->remain_on_ch_cookie = *cookie; rtw_cfg80211_set_last_ro_ch_time(padapter); - _rtw_memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel)); + _rtw_memcpy(&prochinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel)); #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) - pcfg80211_wdinfo->remain_on_ch_type = channel_type; + prochinfo->remain_on_ch_type = channel_type; #endif - pcfg80211_wdinfo->restore_channel = rtw_get_oper_ch(padapter); + prochinfo->restore_channel = rtw_get_oper_ch(padapter); - p2p_roch_cmd(padapter, *cookie, wdev, channel, pcfg80211_wdinfo->remain_on_ch_type, + rtw_roch_cmd(padapter, *cookie, wdev, channel, prochinfo->remain_on_ch_type, duration, RTW_CMDF_WAIT_ACK); rtw_cfg80211_ready_on_channel(wdev, *cookie, channel, channel_type, duration, GFP_KERNEL); @@ -7082,8 +7610,10 @@ static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy, s32 err = 0; _adapter *padapter; struct rtw_wdev_priv *pwdev_priv; + struct roch_info *prochinfo; +#ifdef CONFIG_P2P struct wifidirect_info *pwdinfo; - struct cfg80211_wifidirect_info *pcfg80211_wdinfo; +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) #if defined(RTW_DEDICATED_P2P_DEVICE) @@ -7109,22 +7639,25 @@ static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy, #endif pwdev_priv = adapter_wdev_data(padapter); + prochinfo = &padapter->rochinfo; +#ifdef CONFIG_P2P pwdinfo = &padapter->wdinfo; - pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; +#endif RTW_INFO(FUNC_ADPT_FMT"%s cookie:0x%llx\n" , FUNC_ADPT_ARG(padapter), wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : "" , cookie); if (rtw_cfg80211_get_is_roch(padapter) == _TRUE) { - _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer); - p2p_cancel_roch_cmd(padapter, cookie, wdev, RTW_CMDF_WAIT_ACK); + _cancel_timer_ex(&padapter->rochinfo.remain_on_ch_timer); + rtw_cancel_roch_cmd(padapter, cookie, wdev, RTW_CMDF_WAIT_ACK); } exit: return err; } +#ifdef CONFIG_P2P inline int rtw_cfg80211_iface_has_p2p_group_cap(_adapter *adapter) { #if RTW_P2P_GROUP_INTERFACE @@ -7331,11 +7864,9 @@ static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, u8 no_cck, const struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); u8 u_ch = rtw_mi_get_union_chan(padapter); u8 leave_op = 0; -#ifdef CONFIG_P2P - struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; - #ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; +#if defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE) struct wifidirect_info *pwdinfo = &padapter->wdinfo; - #endif #endif rtw_cfg80211_set_is_mgmt_tx(padapter, 1); @@ -7347,9 +7878,9 @@ static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, u8 no_cck, const #ifdef CONFIG_P2P if (rtw_cfg80211_get_is_roch(padapter) == _TRUE) { #ifdef CONFIG_CONCURRENT_MODE - if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { + if (!check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) { RTW_INFO("%s, extend ro ch time\n", __func__); - _set_timer(&padapter->cfg80211_wdinfo.remain_on_ch_timer, pwdinfo->ext_listen_period); + _set_timer(&padapter->rochinfo.remain_on_ch_timer, pwdinfo->ext_listen_period); } #endif /* CONFIG_CONCURRENT_MODE */ } @@ -7368,22 +7899,6 @@ static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, u8 no_cck, const ) { rtw_leave_opch(padapter); leave_op = 1; - - #if defined(RTW_ROCH_BACK_OP) && defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE) - if (rtw_cfg80211_get_is_roch(padapter) - && ATOMIC_READ(&pwdev_priv->switch_ch_to) == 1 - ) { - u16 ext_listen_period; - - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) - ext_listen_period = 500; - else - ext_listen_period = pwdinfo->ext_listen_period; - ATOMIC_SET(&pwdev_priv->switch_ch_to, 0); - _set_timer(&pwdinfo->ap_p2p_switch_timer, ext_listen_period); - RTW_INFO("%s, set switch ch timer, period=%d\n", __func__, ext_listen_period); - } - #endif /* RTW_ROCH_BACK_OP && CONFIG_P2P && CONFIG_CONCURRENT_MODE */ } if (tx_ch != rtw_get_oper_ch(padapter)) @@ -7455,18 +7970,15 @@ issue_mgmt_frame: } exit: - #ifdef CONFIG_P2P if (rtw_cfg80211_get_is_roch(padapter) - && !roch_stay_in_cur_chan(padapter) - && pcfg80211_wdinfo->remain_on_ch_channel.hw_value != u_ch + && !rtw_roch_stay_in_cur_chan(padapter) + && prochinfo->remain_on_ch_channel.hw_value != u_ch ) { /* roch is ongoing, switch back to rch */ - if (pcfg80211_wdinfo->remain_on_ch_channel.hw_value != tx_ch) - set_channel_bwmode(padapter, pcfg80211_wdinfo->remain_on_ch_channel.hw_value + if (prochinfo->remain_on_ch_channel.hw_value != tx_ch) + set_channel_bwmode(padapter, prochinfo->remain_on_ch_channel.hw_value , HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); - } else - #endif - if (leave_op) { + } else if (leave_op) { if (rtw_mi_check_status(padapter, MI_LINKED)) { u8 u_bw = rtw_mi_get_union_bw(padapter); u8 u_offset = rtw_mi_get_union_offset(padapter); @@ -7776,6 +8288,7 @@ cancel_ps_deny: exit: return ret; } + #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) @@ -7789,7 +8302,6 @@ static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, struct net_device *ndev = wdev_to_ndev(wdev); #endif _adapter *adapter; - struct rtw_wdev_priv *pwdev_priv; if (ndev == NULL) @@ -7833,9 +8345,9 @@ exit: } #else static void cfg80211_rtw_update_mgmt_frame_register( - struct wiphy *wiphy, - struct wireless_dev *wdev, - struct mgmt_frame_regs *upd) + struct wiphy *wiphy, + struct wireless_dev *wdev, + struct mgmt_frame_regs *upd) { struct net_device *ndev; _adapter *padapter; @@ -7855,15 +8367,15 @@ static void cfg80211_rtw_update_mgmt_frame_register( #ifdef CONFIG_DEBUG_CFG80211 RTW_INFO(FUNC_ADPT_FMT " global_stypes:0x%08x interface_stypes:0x%08x\n", - FUNC_ADPT_ARG(padapter), upd->global_stypes, upd->interface_stypes); + FUNC_ADPT_ARG(padapter), upd->global_stypes, upd->interface_stypes); RTW_INFO(FUNC_ADPT_FMT " global_mcast_stypes:0x%08x interface_mcast_stypes:0x%08x\n", - FUNC_ADPT_ARG(padapter), upd->global_mcast_stypes, upd->interface_mcast_stypes); + FUNC_ADPT_ARG(padapter), upd->global_mcast_stypes, upd->interface_mcast_stypes); RTW_INFO(FUNC_ADPT_FMT " old_regs:0x%08x new_regs:0x%08x\n", - FUNC_ADPT_ARG(padapter), pwdev_priv->mgmt_regs, - (upd->interface_stypes & rtw_stypes_mask)); + FUNC_ADPT_ARG(padapter), pwdev_priv->mgmt_regs, + (upd->interface_stypes & rtw_stypes_mask)); #endif if (pwdev_priv->mgmt_regs != - (upd->interface_stypes & rtw_stypes_mask)) { + (upd->interface_stypes & rtw_stypes_mask)) { pwdev_priv->mgmt_regs = (upd->interface_stypes & rtw_stypes_mask); } @@ -8040,7 +8552,7 @@ static int cfg80211_rtw_tdls_oper(struct wiphy *wiphy, if (ptdls_sta != NULL) { rtw_tdls_set_link_established(padapter, _TRUE); ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE; - ptdls_sta->state |= _FW_LINKED; + ptdls_sta->state |= WIFI_ASOC_STATE; rtw_tdls_cmd(padapter, txmgmt.peer, TDLS_ESTABLISHED); } break; @@ -9056,9 +9568,9 @@ static int cfg80211_rtw_sched_scan_start(struct wiphy *wiphy, return -EIO; } - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE || - check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE || - check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE || + check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE || + check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE) { RTW_INFO("%s: device is busy.\n", __func__); rtw_scan_abort(padapter); } @@ -9154,7 +9666,7 @@ int cfg80211_rtw_resume(struct wiphy *wiphy) { _exit_critical_bh(&pmlmepriv->lock, &irqL); for (PNOWakeupScanWaitCnt = 0; PNOWakeupScanWaitCnt < 10; PNOWakeupScanWaitCnt++) { - if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _FALSE) + if(check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _FALSE) break; rtw_msleep_os(1000); } @@ -9170,363 +9682,6 @@ int cfg80211_rtw_resume(struct wiphy *wiphy) { } #endif /* CONFIG_PNO_SUPPORT */ -static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len) -{ - int ret = 0; - uint wps_ielen = 0; - u8 *wps_ie; - u32 p2p_ielen = 0; - u8 wps_oui[8] = {0x0, 0x50, 0xf2, 0x04}; - u8 *p2p_ie; - u32 wfd_ielen = 0; - u8 *wfd_ie; - _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - - RTW_INFO(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len); - - if (len > 0) { - wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen); - if (wps_ie) { - #ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("bcn_wps_ielen=%d\n", wps_ielen); - #endif - - if (pmlmepriv->wps_beacon_ie) { - u32 free_len = pmlmepriv->wps_beacon_ie_len; - pmlmepriv->wps_beacon_ie_len = 0; - rtw_mfree(pmlmepriv->wps_beacon_ie, free_len); - pmlmepriv->wps_beacon_ie = NULL; - } - - pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen); - if (pmlmepriv->wps_beacon_ie == NULL) { - RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); - return -EINVAL; - - } - - _rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen); - pmlmepriv->wps_beacon_ie_len = wps_ielen; - - update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE, RTW_CMDF_WAIT_ACK); - - } - - /* buf += wps_ielen; */ - /* len -= wps_ielen; */ - - #ifdef CONFIG_P2P - p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen); - if (p2p_ie) { - #ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("bcn_p2p_ielen=%d\n", p2p_ielen); - #endif - - if (pmlmepriv->p2p_beacon_ie) { - u32 free_len = pmlmepriv->p2p_beacon_ie_len; - pmlmepriv->p2p_beacon_ie_len = 0; - rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len); - pmlmepriv->p2p_beacon_ie = NULL; - } - - pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen); - if (pmlmepriv->p2p_beacon_ie == NULL) { - RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); - return -EINVAL; - - } - - _rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen); - pmlmepriv->p2p_beacon_ie_len = p2p_ielen; - - } - #endif /* CONFIG_P2P */ - - - #ifdef CONFIG_WFD - wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen); - if (wfd_ie) { - #ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("bcn_wfd_ielen=%d\n", wfd_ielen); - #endif - - if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_BEACON_IE, wfd_ie, wfd_ielen) != _SUCCESS) - return -EINVAL; - } - #endif /* CONFIG_WFD */ - - pmlmeext->bstart_bss = _TRUE; - - } - - return ret; - -} - -static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len) -{ - int ret = 0; - uint wps_ielen = 0; - u8 *wps_ie; - u32 p2p_ielen = 0; - u8 *p2p_ie; - u32 wfd_ielen = 0; - u8 *wfd_ie; - _adapter *padapter = (_adapter *)rtw_netdev_priv(net); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - -#ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("%s, ielen=%d\n", __func__, len); -#endif - - if (len > 0) { - wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen); - if (wps_ie) { - uint attr_contentlen = 0; - u16 uconfig_method, *puconfig_method = NULL; - - #ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("probe_resp_wps_ielen=%d\n", wps_ielen); - #endif - - if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) { - u8 sr = 0; - rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL); - - if (sr != 0) - RTW_INFO("%s, got sr\n", __func__); - else { - RTW_INFO("GO mode process WPS under site-survey, sr no set\n"); - return ret; - } - } - - if (pmlmepriv->wps_probe_resp_ie) { - u32 free_len = pmlmepriv->wps_probe_resp_ie_len; - pmlmepriv->wps_probe_resp_ie_len = 0; - rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len); - pmlmepriv->wps_probe_resp_ie = NULL; - } - - pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen); - if (pmlmepriv->wps_probe_resp_ie == NULL) { - RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); - return -EINVAL; - - } - - /* add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode */ - puconfig_method = (u16 *)rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen); - if (puconfig_method != NULL) { - /* struct registry_priv *pregistrypriv = &padapter->registrypriv; */ - struct wireless_dev *wdev = padapter->rtw_wdev; - - #ifdef CONFIG_DEBUG_CFG80211 - /* printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method)); */ - #endif - - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE) - /* for WIFI-DIRECT LOGO 4.2.2, AUTO GO can't set PUSH_BUTTON flags */ - if (wdev->iftype == NL80211_IFTYPE_P2P_GO) { - uconfig_method = WPS_CM_PUSH_BUTTON; - uconfig_method = cpu_to_be16(uconfig_method); - - *puconfig_method &= ~uconfig_method; - } - #endif - } - - _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen); - pmlmepriv->wps_probe_resp_ie_len = wps_ielen; - - } - - /* buf += wps_ielen; */ - /* len -= wps_ielen; */ - - #ifdef CONFIG_P2P - p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen); - if (p2p_ie) { - u8 is_GO = _FALSE; - u32 attr_contentlen = 0; - u16 cap_attr = 0; - - #ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("probe_resp_p2p_ielen=%d\n", p2p_ielen); - #endif - - /* Check P2P Capability ATTR */ - if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8 *)&cap_attr, (uint *) &attr_contentlen)) { - u8 grp_cap = 0; - /* RTW_INFO( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ ); */ - cap_attr = le16_to_cpu(cap_attr); - grp_cap = (u8)((cap_attr >> 8) & 0xff); - - is_GO = (grp_cap & BIT(0)) ? _TRUE : _FALSE; - - if (is_GO) - RTW_INFO("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap); - } - - - if (is_GO == _FALSE) { - if (pmlmepriv->p2p_probe_resp_ie) { - u32 free_len = pmlmepriv->p2p_probe_resp_ie_len; - pmlmepriv->p2p_probe_resp_ie_len = 0; - rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len); - pmlmepriv->p2p_probe_resp_ie = NULL; - } - - pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen); - if (pmlmepriv->p2p_probe_resp_ie == NULL) { - RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); - return -EINVAL; - - } - _rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen); - pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen; - } else { - if (pmlmepriv->p2p_go_probe_resp_ie) { - u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len; - pmlmepriv->p2p_go_probe_resp_ie_len = 0; - rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len); - pmlmepriv->p2p_go_probe_resp_ie = NULL; - } - - pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen); - if (pmlmepriv->p2p_go_probe_resp_ie == NULL) { - RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); - return -EINVAL; - - } - _rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen); - pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen; - } - - } - #endif /* CONFIG_P2P */ - - - #ifdef CONFIG_WFD - wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen); - if (wfd_ie) { - #ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("probe_resp_wfd_ielen=%d\n", wfd_ielen); - #endif - - if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_PROBE_RESP_IE, wfd_ie, wfd_ielen) != _SUCCESS) - return -EINVAL; - } - #endif /* CONFIG_WFD */ - - } - - return ret; - -} - -static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len) -{ - int ret = 0; - _adapter *padapter = (_adapter *)rtw_netdev_priv(net); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - u8 *ie; - u32 ie_len; - - RTW_INFO("%s, ielen=%d\n", __func__, len); - - if (len <= 0) - goto exit; - - ie = rtw_get_wps_ie(buf, len, NULL, &ie_len); - if (ie && ie_len) { - if (pmlmepriv->wps_assoc_resp_ie) { - u32 free_len = pmlmepriv->wps_assoc_resp_ie_len; - - pmlmepriv->wps_assoc_resp_ie_len = 0; - rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len); - pmlmepriv->wps_assoc_resp_ie = NULL; - } - - pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len); - if (pmlmepriv->wps_assoc_resp_ie == NULL) { - RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); - return -EINVAL; - } - _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, ie, ie_len); - pmlmepriv->wps_assoc_resp_ie_len = ie_len; - } - - ie = rtw_get_p2p_ie(buf, len, NULL, &ie_len); - if (ie && ie_len) { - if (pmlmepriv->p2p_assoc_resp_ie) { - u32 free_len = pmlmepriv->p2p_assoc_resp_ie_len; - - pmlmepriv->p2p_assoc_resp_ie_len = 0; - rtw_mfree(pmlmepriv->p2p_assoc_resp_ie, free_len); - pmlmepriv->p2p_assoc_resp_ie = NULL; - } - - pmlmepriv->p2p_assoc_resp_ie = rtw_malloc(ie_len); - if (pmlmepriv->p2p_assoc_resp_ie == NULL) { - RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); - return -EINVAL; - } - _rtw_memcpy(pmlmepriv->p2p_assoc_resp_ie, ie, ie_len); - pmlmepriv->p2p_assoc_resp_ie_len = ie_len; - } - -#ifdef CONFIG_WFD - ie = rtw_get_wfd_ie(buf, len, NULL, &ie_len); - if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_ASSOC_RESP_IE, ie, ie_len) != _SUCCESS) - return -EINVAL; -#endif - -exit: - return ret; -} - -int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len, - int type) -{ - int ret = 0; - uint wps_ielen = 0; - u32 p2p_ielen = 0; - -#ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("%s, ielen=%d\n", __func__, len); -#endif - - if ((rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen > 0)) - #ifdef CONFIG_P2P - || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen > 0)) - #endif - ) { - if (net != NULL) { - switch (type) { - case 0x1: /* BEACON */ - ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len); - break; - case 0x2: /* PROBE_RESP */ - ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len); - #ifdef CONFIG_P2P - if (ret == 0) - adapter_wdev_data((_adapter *)rtw_netdev_priv(net))->probe_resp_ie_update_time = rtw_get_current_time(); - #endif - break; - case 0x4: /* ASSOC_RESP */ - ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len); - break; - } - } - } - - return ret; - -} - #ifdef CONFIG_80211N_HT static void rtw_cfg80211_init_ht_capab_ex(_adapter *padapter , struct ieee80211_sta_ht_cap *ht_cap, BAND_TYPE band, u8 rf_type) @@ -9588,9 +9743,21 @@ static void rtw_cfg80211_init_ht_capab(_adapter *padapter ht_cap->ht_supported = 1; - ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | - IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; + ht_cap->cap = IEEE80211_HT_CAP_MAX_AMSDU; + + if (TEST_FLAG(regsty->short_gi, BIT0)) + ht_cap->cap |= IEEE80211_HT_CAP_SGI_20; + if (hal_is_bw_support(padapter, CHANNEL_WIDTH_40) + && ((band == BAND_ON_2_4G && REGSTY_IS_BW_2G_SUPPORT(regsty, CHANNEL_WIDTH_40)) + || (band == BAND_ON_5G && REGSTY_IS_BW_5G_SUPPORT(regsty, CHANNEL_WIDTH_40))) + ) { + ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; + if (band == BAND_ON_2_4G) + ht_cap->cap |= IEEE80211_HT_CAP_DSSSCCK40; + if (TEST_FLAG(regsty->short_gi, BIT1)) + ht_cap->cap |= IEEE80211_HT_CAP_SGI_40; + } + rtw_cfg80211_init_ht_capab_ex(padapter, ht_cap, band, rf_type); /* @@ -9665,43 +9832,89 @@ void rtw_cfg80211_init_wdev_data(_adapter *padapter) #endif } -void rtw_cfg80211_init_wiphy(_adapter *padapter) +static int rtw_cfg80211_init_wiphy_band(_adapter *padapter, struct wiphy *wiphy) { u8 rf_type; struct ieee80211_supported_band *band; - struct wireless_dev *pwdev = padapter->rtw_wdev; - struct wiphy *wiphy = pwdev->wiphy; + int ret = _FAIL; rf_type = GET_HAL_RFPATH(padapter); RTW_INFO("%s:rf_type=%d\n", __func__, rf_type); if (IsSupported24G(padapter->registrypriv.wireless_mode)) { - band = wiphy->bands[NL80211_BAND_2GHZ]; - if (band) { - #if defined(CONFIG_80211N_HT) - rtw_cfg80211_init_ht_capab(padapter, &band->ht_cap, BAND_ON_2_4G, rf_type); - #endif - } + band = wiphy->bands[NL80211_BAND_2GHZ] = rtw_spt_band_alloc(BAND_ON_2_4G); + if (!band) + goto exit; + rtw_2g_channels_init(band->channels); + rtw_2g_rates_init(band->bitrates); + #if defined(CONFIG_80211N_HT) + rtw_cfg80211_init_ht_capab(padapter, &band->ht_cap, BAND_ON_2_4G, rf_type); + #endif } #if CONFIG_IEEE80211_BAND_5GHZ if (is_supported_5g(padapter->registrypriv.wireless_mode)) { - band = wiphy->bands[NL80211_BAND_5GHZ]; - if (band) { - #if defined(CONFIG_80211N_HT) - rtw_cfg80211_init_ht_capab(padapter, &band->ht_cap, BAND_ON_5G, rf_type); - #endif - #if defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) - rtw_cfg80211_init_vht_capab(padapter, &band->vht_cap, BAND_ON_5G, rf_type); - #endif + band = wiphy->bands[NL80211_BAND_5GHZ] = rtw_spt_band_alloc(BAND_ON_5G); + if (!band) { + if (wiphy->bands[NL80211_BAND_2GHZ]) { + rtw_spt_band_free(wiphy->bands[NL80211_BAND_2GHZ]); + wiphy->bands[NL80211_BAND_2GHZ] = NULL; + } + goto exit; } + rtw_5g_channels_init(band->channels); + rtw_5g_rates_init(band->bitrates); + #if defined(CONFIG_80211N_HT) + rtw_cfg80211_init_ht_capab(padapter, &band->ht_cap, BAND_ON_5G, rf_type); + #endif + #if defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + rtw_cfg80211_init_vht_capab(padapter, &band->vht_cap, BAND_ON_5G, rf_type); + #endif } #endif - /* copy mac_addr to wiphy */ - _rtw_memcpy(wiphy->perm_addr, adapter_mac_addr(padapter), ETH_ALEN); + ret = _SUCCESS; +exit: + return ret; } +#if !defined(CONFIG_REGD_SRC_FROM_OS) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) +void rtw_cfg80211_update_wiphy_max_txpower(_adapter *adapter, struct wiphy *wiphy) +{ + struct ieee80211_supported_band *band; + struct ieee80211_channel *channel; + s16 max_txpwr; + int i; + + if (IsSupported24G(adapter->registrypriv.wireless_mode)) { + band = wiphy->bands[NL80211_BAND_2GHZ]; + if (band) { + max_txpwr = phy_get_txpwr_by_rate_total_max_mbm(adapter, BAND_ON_2_4G, 1, 1); + if (max_txpwr != UNSPECIFIED_MBM) { + for (i = 0; i < band->n_channels; i++) { + channel = &band->channels[i]; + channel->max_power = max_txpwr / MBM_PDBM; + } + } + } + } +#if CONFIG_IEEE80211_BAND_5GHZ + if (is_supported_5g(adapter->registrypriv.wireless_mode)) { + band = wiphy->bands[NL80211_BAND_5GHZ]; + if (band) { + max_txpwr = phy_get_txpwr_by_rate_total_max_mbm(adapter, BAND_ON_5G, 1, 1); + if (max_txpwr != UNSPECIFIED_MBM) { + for (i = 0; i < band->n_channels; i++) { + channel = &band->channels[i]; + channel->max_power = max_txpwr / MBM_PDBM; + } + } + } + } +#endif +} +#endif /* defined(CONFIG_REGD_SRC_FROM_OS) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) */ + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) && defined(RTW_SINGLE_WIPHY) && (CONFIG_IFACE_NUMBER >= 2) struct ieee80211_iface_limit rtw_limits[] = { { @@ -9748,10 +9961,14 @@ struct ieee80211_iface_combination rtw_combinations[] = { }; #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) */ -static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy) +static int rtw_cfg80211_init_wiphy(_adapter *adapter, struct wiphy *wiphy) { struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct registry_priv *regsty = dvobj_to_regsty(dvobj); + int ret = _FAIL; + + /* copy mac_addr to wiphy */ + _rtw_memcpy(wiphy->perm_addr, adapter_mac_addr(adapter), ETH_ALEN); wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; @@ -9768,13 +9985,13 @@ static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy) #endif wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) - | BIT(NL80211_IFTYPE_ADHOC) -#ifdef CONFIG_AP_MODE + #ifdef CONFIG_AP_MODE + | BIT(NL80211_IFTYPE_ADHOC) /* todo : AD-HOC task group will refine it */ | BIT(NL80211_IFTYPE_AP) + #endif #ifdef CONFIG_WIFI_MONITOR | BIT(NL80211_IFTYPE_MONITOR) #endif -#endif #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)) | BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) @@ -9795,9 +10012,7 @@ static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy) #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE) -#ifdef CONFIG_AP_MODE wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes; -#endif /* CONFIG_AP_MODE */ #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) @@ -9812,15 +10027,26 @@ static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy) #endif wiphy->cipher_suites = rtw_cipher_suites; - wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites); - if (IsSupported24G(adapter->registrypriv.wireless_mode)) - wiphy->bands[NL80211_BAND_2GHZ] = rtw_spt_band_alloc(BAND_ON_2_4G); - -#if CONFIG_IEEE80211_BAND_5GHZ - if (is_supported_5g(adapter->registrypriv.wireless_mode)) - wiphy->bands[NL80211_BAND_5GHZ] = rtw_spt_band_alloc(BAND_ON_5G); + /* Todo refine */ + if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_EXTRA_SEC)) + wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites); + else { +#ifdef CONFIG_IEEE80211W + /* remove hardware not support cipher */ + wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites) - 6; +#else + wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites); #endif + } + + if (rtw_cfg80211_init_wiphy_band(adapter, wiphy) != _SUCCESS) { + RTW_ERR("rtw_cfg80211_init_wiphy_band fail\n"); + goto exit; + } + #if !defined(CONFIG_REGD_SRC_FROM_OS) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) + rtw_cfg80211_update_wiphy_max_txpower(adapter, wiphy); + #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) && LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)) wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS; @@ -9860,15 +10086,23 @@ static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy) #endif /* CONFIG_TDLS_DRIVER_SETUP */ #endif /* CONFIG_TDLS */ - if (regsty->power_mgnt != PS_MODE_ACTIVE) +#ifdef CONFIG_LPS wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; - else +#else wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) /* wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; */ #endif +#ifdef CONFIG_RTW_WDS + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) + wiphy->flags |= WIPHY_FLAG_4ADDR_AP; + wiphy->flags |= WIPHY_FLAG_4ADDR_STATION; + #endif +#endif + #ifdef CONFIG_RTW_MESH wiphy->flags |= 0 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) @@ -9888,13 +10122,31 @@ static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy) #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) */ #endif /* CONFIG_RTW_MESH */ -#ifdef CONFIG_NET_NS - wiphy->flags |= WIPHY_FLAG_NETNS_OK; -#endif // NETNS +#if defined(CONFIG_RTW_80211K) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)) + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_RRM); +#endif #if (KERNEL_VERSION(3, 8, 0) <= LINUX_VERSION_CODE) wiphy->features |= NL80211_FEATURE_SAE; #endif + +#ifdef CONFIG_RTW_SCAN_RAND + #if (KERNEL_VERSION(3, 19, 0) <= LINUX_VERSION_CODE) + wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; + #endif +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) +#ifdef CONFIG_WIFI_MONITOR + /* Currently only for Monitor debugging */ + wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ; +#endif +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) */ + + ret = _SUCCESS; + +exit: + return ret; } #ifdef CONFIG_RFKILL_POLL @@ -9941,53 +10193,7 @@ static void cfg80211_rtw_rfkill_poll(struct wiphy *wiphy) #define SURVEY_INFO_TIME_TX SURVEY_INFO_CHANNEL_TIME_TX #endif -#ifdef CONFIG_FIND_BEST_CHANNEL -static void rtw_cfg80211_set_survey_info_with_find_best_channel(struct wiphy *wiphy - , struct net_device *netdev, int idx, struct survey_info *info) -{ - _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev); - struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); - RT_CHANNEL_INFO *ch_set = rfctl->channel_set; - u8 ch_num = rfctl->max_chan_nums; - u32 total_rx_cnt = 0; - int i; - - s8 noise = -50; /*channel noise in dBm. This and all following fields are optional */ - u64 time = 100; /*amount of time in ms the radio was turn on (on the channel)*/ - u64 time_busy = 0; /*amount of time the primary channel was sensed busy*/ - - info->filled = SURVEY_INFO_NOISE_DBM - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) - | SURVEY_INFO_TIME | SURVEY_INFO_TIME_BUSY - #endif - ; - - for (i = 0; i < ch_num; i++) - total_rx_cnt += ch_set[i].rx_count; - - time_busy = ch_set[idx].rx_count * time / total_rx_cnt; - noise += ch_set[idx].rx_count * 50 / total_rx_cnt; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) - #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) - info->channel_time = time; - info->channel_time_busy = time_busy; - #else - info->time = time; - info->time_busy = time_busy; - #endif -#endif - info->noise = noise; - - /* reset if final channel is got */ - if (idx == ch_num - 1) { - for (i = 0; i < ch_num; i++) - ch_set[i].rx_count = 0; - } -} -#endif /* CONFIG_FIND_BEST_CHANNEL */ - -#if defined(CONFIG_RTW_ACS) && defined(CONFIG_BACKGROUND_NOISE_MONITOR) +#ifdef CONFIG_RTW_ACS static void rtw_cfg80211_set_survey_info_with_clm(PADAPTER padapter, int idx, struct survey_info *pinfo) { s8 noise = -50; /*channel noise in dBm. This and all following fields are optional */ @@ -10005,7 +10211,7 @@ static void rtw_cfg80211_set_survey_info_with_clm(PADAPTER padapter, int idx, st ; time_busy = rtw_acs_get_clm_ratio_by_ch_idx(padapter, chan); - noise = rtw_noise_query_by_chan_idx(padapter, chan); + noise = rtw_acs_get_nhm_noise_pwr_by_ch_idx(padapter, chan); /* RTW_INFO("%s: ch-idx:%d time=%llu(ms), time_busy=%llu(ms), noise=%d(dbm)\n", __func__, idx, time, time_busy, noise); */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) @@ -10019,9 +10225,9 @@ static void rtw_cfg80211_set_survey_info_with_clm(PADAPTER padapter, int idx, st #endif pinfo->noise = noise; } -#endif +#endif /* CONFIG_RTW_ACS */ -int rtw_hostapd_acs_dump_survey(struct wiphy *wiphy, struct net_device *netdev, int idx, struct survey_info *info) +static int rtw_hostapd_acs_dump_survey(struct wiphy *wiphy, struct net_device *netdev, int idx, struct survey_info *info) { PADAPTER padapter = (_adapter *)rtw_netdev_priv(netdev); struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); @@ -10056,19 +10262,18 @@ int rtw_hostapd_acs_dump_survey(struct wiphy *wiphy, struct net_device *netdev, if (info->channel->flags == IEEE80211_CHAN_DISABLED) return ret; -#ifdef CONFIG_FIND_BEST_CHANNEL - rtw_cfg80211_set_survey_info_with_find_best_channel(wiphy, netdev, idx, info); -#elif defined(CONFIG_RTW_ACS) && defined(CONFIG_BACKGROUND_NOISE_MONITOR) +#ifdef CONFIG_RTW_ACS rtw_cfg80211_set_survey_info_with_clm(padapter, idx, info); #else - RTW_ERR("%s: unknown acs operation!\n", __func__); + RTW_ERR("%s: unknown acs operation!\n", __func__); #endif return ret; } #endif /* defined(CONFIG_RTW_HOSTAPD_ACS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) */ -#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) \ + || defined(CONFIG_KERNEL_PATCH_EXTERNAL_AUTH) int cfg80211_rtw_external_auth(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_external_auth_params *params) { @@ -10106,6 +10311,7 @@ void rtw_cfg80211_external_auth_status(struct wiphy *wiphy, struct net_device *d psta = rtw_get_stainfo(pstapriv, params->bssid); if (psta && (params->status == WLAN_STATUS_SUCCESS)) { +#ifdef CONFIG_AP_MODE /* AP mode */ RTW_INFO("station match\n"); @@ -10150,6 +10356,7 @@ void rtw_cfg80211_external_auth_status(struct wiphy *wiphy, struct net_device *d buf = NULL; len = 0; } +#endif } else { /* STA mode */ psecuritypriv->extauth_status = params->status; @@ -10170,6 +10377,10 @@ static struct cfg80211_ops rtw_cfg80211_ops = { #endif /*CONFIG_GTK_OL*/ .get_station = cfg80211_rtw_get_station, .scan = cfg80211_rtw_scan, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) && \ + defined(CONFIG_RTW_ABORT_SCAN) + .abort_scan = cfg80211_rtw_abort_scan, +#endif .set_wiphy_params = cfg80211_rtw_set_wiphy_params, .connect = cfg80211_rtw_connect, .disconnect = cfg80211_rtw_disconnect, @@ -10184,10 +10395,10 @@ static struct cfg80211_ops rtw_cfg80211_ops = { .del_pmksa = cfg80211_rtw_del_pmksa, .flush_pmksa = cfg80211_rtw_flush_pmksa, -#ifdef CONFIG_AP_MODE .add_virtual_intf = cfg80211_rtw_add_virtual_intf, .del_virtual_intf = cfg80211_rtw_del_virtual_intf, +#ifdef CONFIG_AP_MODE #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE) .add_beacon = cfg80211_rtw_add_beacon, .set_beacon = cfg80211_rtw_set_beacon, @@ -10238,15 +10449,17 @@ static struct cfg80211_ops rtw_cfg80211_ops = { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) .set_monitor_channel = cfg80211_rtw_set_monitor_channel, #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) + .get_channel = cfg80211_rtw_get_channel, +#endif -#ifdef CONFIG_P2P .remain_on_channel = cfg80211_rtw_remain_on_channel, .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel, - #if defined(RTW_DEDICATED_P2P_DEVICE) + +#if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE) .start_p2p_device = cfg80211_rtw_start_p2p_device, .stop_p2p_device = cfg80211_rtw_stop_p2p_device, - #endif -#endif /* CONFIG_P2P */ +#endif #ifdef CONFIG_RTW_80211R .update_ft_ies = cfg80211_rtw_update_ft_ies, @@ -10280,7 +10493,8 @@ static struct cfg80211_ops rtw_cfg80211_ops = { #if defined(CONFIG_RTW_HOSTAPD_ACS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) .dump_survey = rtw_hostapd_acs_dump_survey, #endif -#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) \ + || defined(CONFIG_KERNEL_PATCH_EXTERNAL_AUTH) .external_auth = cfg80211_rtw_external_auth, #endif }; @@ -10293,7 +10507,7 @@ struct wiphy *rtw_wiphy_alloc(_adapter *padapter, struct device *dev) /* wiphy */ wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wiphy_data)); if (!wiphy) { - RTW_INFO("Couldn't allocate wiphy device\n"); + RTW_ERR("Couldn't allocate wiphy device\n"); goto exit; } set_wiphy_dev(wiphy, dev); @@ -10307,7 +10521,11 @@ struct wiphy *rtw_wiphy_alloc(_adapter *padapter, struct device *dev) wiphy_data->txpwr_total_lmt_mbm = UNSPECIFIED_MBM; wiphy_data->txpwr_total_target_mbm = UNSPECIFIED_MBM; - rtw_cfg80211_preinit_wiphy(padapter, wiphy); + if (rtw_cfg80211_init_wiphy(padapter, wiphy) != _SUCCESS) { + rtw_wiphy_free(wiphy); + wiphy = NULL; + goto exit; + } RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy)); @@ -10338,8 +10556,7 @@ int rtw_wiphy_register(struct wiphy *wiphy) { RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy)); -#if ( ((LINUX_VERSION_CODE < KERNEL_VERSION(5, 3, 0)) && \ - LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) \ +#if ( (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) \ || defined(RTW_VENDOR_EXT_SUPPORT) ) rtw_cfgvendor_attach(wiphy); #endif @@ -10353,8 +10570,7 @@ void rtw_wiphy_unregister(struct wiphy *wiphy) { RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy)); -#if ( ((LINUX_VERSION_CODE < KERNEL_VERSION(5, 3, 0)) && \ - LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) \ +#if ( (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) \ || defined(RTW_VENDOR_EXT_SUPPORT) ) rtw_cfgvendor_detach(wiphy); #endif @@ -10407,18 +10623,13 @@ int rtw_wdev_alloc(_adapter *padapter, struct wiphy *wiphy) pwdev_priv->bandroid_scan = _FALSE; - if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE) - pwdev_priv->power_mgmt = _TRUE; - else - pwdev_priv->power_mgmt = _FALSE; - _rtw_mutex_init(&pwdev_priv->roch_mutex); #ifdef CONFIG_CONCURRENT_MODE ATOMIC_SET(&pwdev_priv->switch_ch_to, 1); #endif -#ifdef CONFIG_RTW_CFGVEDNOR_RSSIMONITOR +#ifdef CONFIG_RTW_CFGVENDOR_RSSIMONITOR pwdev_priv->rssi_monitor_enable = 0; pwdev_priv->rssi_monitor_max = 0; pwdev_priv->rssi_monitor_min = 0; @@ -10527,6 +10738,7 @@ void rtw_cfg80211_ndev_res_free(_adapter *adapter) #endif } + int rtw_cfg80211_ndev_res_register(_adapter *adapter) { #if !defined(RTW_SINGLE_WIPHY) diff --git a/os_dep/linux/ioctl_cfg80211.h b/os_dep/linux/ioctl_cfg80211.h index 45c63bc..7c50e32 100644 --- a/os_dep/linux/ioctl_cfg80211.h +++ b/os_dep/linux/ioctl_cfg80211.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2019 Realtek Corporation. + * Copyright(c) 2007 - 2017 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -166,7 +166,6 @@ struct rtw_wdev_priv { u8 bandroid_scan; bool block; bool block_scan; - bool power_mgmt; /** * mgmt_regs: bitmap of management frame subtypes registered for the @@ -186,12 +185,12 @@ struct rtw_wdev_priv { ATOMIC_T switch_ch_to; #endif -#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI +#if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND) u8 pno_mac_addr[ETH_ALEN]; u16 pno_scan_seq_num; #endif -#ifdef CONFIG_RTW_CFGVEDNOR_RSSIMONITOR +#ifdef CONFIG_RTW_CFGVENDOR_RSSIMONITOR s8 rssi_monitor_max; s8 rssi_monitor_min; u8 rssi_monitor_enable; @@ -246,8 +245,8 @@ struct rtw_wiphy_data { struct wireless_dev *pd_wdev; /* P2P device wdev */ #endif - s16 txpwr_total_lmt_mbm; - s16 txpwr_total_target_mbm; + s16 txpwr_total_lmt_mbm; /* EIRP */ + s16 txpwr_total_target_mbm; /* EIRP */ }; #define rtw_wiphy_priv(wiphy) ((struct rtw_wiphy_data *)wiphy_priv(wiphy)) @@ -299,14 +298,13 @@ s16 rtw_cfg80211_dev_get_total_txpwr_lmt_mbm(struct dvobj_priv *dvobj); s16 rtw_cfg80211_dev_get_total_txpwr_target_mbm(struct dvobj_priv *dvobj); void rtw_cfg80211_init_wdev_data(_adapter *padapter); -void rtw_cfg80211_init_wiphy(_adapter *padapter); void rtw_cfg80211_unlink_bss(_adapter *padapter, struct wlan_network *pnetwork); void rtw_cfg80211_surveydone_event_callback(_adapter *padapter); struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork); int rtw_cfg80211_check_bss(_adapter *padapter); void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter); -int rtw_cfg80211_indicate_connect(_adapter *padapter); +void rtw_cfg80211_indicate_connect(_adapter *padapter); void rtw_cfg80211_indicate_disconnect(_adapter *padapter, u16 reason, u8 locally_generated); void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted); u32 rtw_cfg80211_wait_scan_req_empty(_adapter *adapter, u32 timeout_ms); @@ -319,15 +317,16 @@ void rtw_cfg80211_indicate_scan_done_for_buddy(_adapter *padapter, bool bscan_ab #ifdef CONFIG_AP_MODE void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len); void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, const u8 *da, unsigned short reason); +int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len, int type); #endif /* CONFIG_AP_MODE */ -#ifdef CONFIG_P2P void rtw_cfg80211_set_is_roch(_adapter *adapter, bool val); bool rtw_cfg80211_get_is_roch(_adapter *adapter); bool rtw_cfg80211_is_ro_ch_once(_adapter *adapter); void rtw_cfg80211_set_last_ro_ch_time(_adapter *adapter); s32 rtw_cfg80211_get_last_ro_ch_passing_ms(_adapter *adapter); +#ifdef CONFIG_P2P int rtw_cfg80211_iface_has_p2p_group_cap(_adapter *adapter); int rtw_cfg80211_is_p2p_scan(_adapter *adapter); #if defined(RTW_DEDICATED_P2P_DEVICE) @@ -354,8 +353,6 @@ void rtw_cfg80211_external_auth_request(_adapter *padapter, union recv_frame *rf void rtw_cfg80211_external_auth_status(struct wiphy *wiphy, struct net_device *dev, struct rtw_external_auth_params *params); -int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len, int type); - bool rtw_cfg80211_pwr_mgmt(_adapter *adapter); #ifdef CONFIG_RTW_80211K void rtw_cfg80211_rx_rrm_action(_adapter *adapter, union recv_frame *rframe); @@ -427,6 +424,11 @@ void rtw_cfg80211_deinit_rfkill(struct wiphy *wiphy); u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, u8 ht, bool started); #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) +#define IEEE80211_CHAN_NO_HT40PLUS IEEE80211_CHAN_NO_FAT_ABOVE +#define IEEE80211_CHAN_NO_HT40MINUS IEEE80211_CHAN_NO_FAT_BELOW +#endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0)) #define NL80211_BAND_2GHZ IEEE80211_BAND_2GHZ #define NL80211_BAND_5GHZ IEEE80211_BAND_5GHZ diff --git a/os_dep/linux/ioctl_linux.c b/os_dep/linux/ioctl_linux.c index 8b9e244..1751022 100644 --- a/os_dep/linux/ioctl_linux.c +++ b/os_dep/linux/ioctl_linux.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2017 Realtek Corporation. + * Copyright(c) 2007 - 2019 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -31,6 +31,7 @@ extern int rtw_ht_enable; #endif + #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV+30) #define SCAN_ITEM_SIZE 768 @@ -64,33 +65,7 @@ extern u8 convert_ip_addr(u8 hch, u8 mch, u8 lch); u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000, 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000}; -/** - * hwaddr_aton - Convert ASCII string to MAC address - * @txt: MAC address as a string (e.g., "00:11:22:33:44:55") - * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) - * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) - */ -static int hwaddr_aton_i(const char *txt, u8 *addr) -{ - int i; - - for (i = 0; i < 6; i++) { - int a, b; - - a = hex2num_i(*txt++); - if (a < 0) - return -1; - b = hex2num_i(*txt++); - if (b < 0) - return -1; - *addr++ = (a << 4) | b; - if (i < 5 && *txt++ != ':') - return -1; - } - - return 0; -} -#ifdef CONFIG_ANDROID +#ifdef CONFIG_RTW_ANDROID static void indicate_wx_custom_event(_adapter *padapter, char *msg) { u8 *buff; @@ -262,6 +237,7 @@ uint rtw_is_cckratesonly_included(u8 *rate) } */ +#ifdef CONFIG_IOCTL_WEXT static int search_p2p_wfd_ie(_adapter *padapter, struct iw_request_info *info, struct wlan_network *pnetwork, char *start, char *stop) @@ -721,7 +697,7 @@ static inline char *iwe_stream_rssi_process(_adapter *padapter, #endif ; - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE && is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) { ss = padapter->recvpriv.signal_strength; sq = padapter->recvpriv.signal_qual; @@ -1083,7 +1059,7 @@ static int rtw_set_wpa_ie(_adapter *padapter, char *pie, unsigned short ielen) _rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen); } - if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL, &mfp_opt) == _SUCCESS) { + if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL, NULL, &mfp_opt, NULL) == _SUCCESS) { padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; _rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen); @@ -1176,6 +1152,12 @@ static int rtw_set_wpa_ie(_adapter *padapter, char *pie, unsigned short ielen) } } } + + #ifdef CONFIG_RTW_MULTI_AP + padapter->multi_ap = rtw_get_multi_ap_ie_ext(buf, ielen) & MULTI_AP_BACKHAUL_STA; + if (padapter->multi_ap) + adapter_set_use_wds(padapter, 1); + #endif } /* TKIP and AES disallow multicast packets until installing group key */ @@ -1209,7 +1191,7 @@ static int rtw_wx_get_name(struct net_device *dev, - if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE) { /* parsing HT_CAP_IE */ if( is_supported_ht(padapter->registrypriv.wireless_mode)&&(padapter->registrypriv.ht_enable)) { p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength - 12); @@ -1333,7 +1315,7 @@ static int rtw_wx_get_freq(struct net_device *dev, struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network; - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) != _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE && check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) != _TRUE) { wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000; wrqu->freq.e = 1; @@ -1370,16 +1352,18 @@ static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a, /* initial default type */ dev->type = ARPHRD_ETHER; - if (wrqu->mode == IW_MODE_MONITOR) { - rtw_ps_deny(padapter, PS_DENY_MONITOR_MODE); - LeaveAllPowerSaveMode(padapter); - } else { + if (wrqu->mode != IW_MODE_MONITOR) { rtw_ps_deny_cancel(padapter, PS_DENY_MONITOR_MODE); } switch (wrqu->mode) { +#ifdef CONFIG_WIFI_MONITOR case IW_MODE_MONITOR: networkType = Ndis802_11Monitor; + + rtw_ps_deny(padapter, PS_DENY_MONITOR_MODE); + LeaveAllPowerSaveMode(padapter); + #if 0 dev->type = ARPHRD_IEEE80211; /* IEEE 802.11 : 801 */ #endif @@ -1391,7 +1375,7 @@ static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a, RTW_INFO("kernel version < 2.6.24 not support IW_MODE_MONITOR\n"); #endif break; - +#endif /* CONFIG_WIFI_MONITOR */ case IW_MODE_AUTO: networkType = Ndis802_11AutoUnknown; RTW_INFO("set_mode = IW_MODE_AUTO\n"); @@ -1502,7 +1486,6 @@ static int rtw_wx_set_pmkid(struct net_device *dev, _rtw_memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN); psecuritypriv->PMKIDList[j].bUsed = _TRUE; - psecuritypriv->PMKIDIndex = j + 1; blInserted = _TRUE; break; } @@ -1553,7 +1536,7 @@ static int rtw_wx_get_sens(struct net_device *dev, * 20110311 Commented by Jeff * For rockchip platform's wpa_driver_wext_get_rssi */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { /* wrqu->sens.value=-padapter->recvpriv.signal_strength; */ wrqu->sens.value = -padapter->recvpriv.rssi; /* RTW_INFO("%s: %d\n", __FUNCTION__, wrqu->sens.value); */ @@ -1754,7 +1737,7 @@ static int rtw_wx_set_wap(struct net_device *dev, */ #ifdef CONFIG_CONCURRENT_MODE - if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) { + if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING) == _TRUE) { RTW_INFO("set bssid, but buddy_intf is under scanning or linking\n"); ret = -EINVAL; @@ -1856,7 +1839,7 @@ static int rtw_wx_get_wap(struct net_device *dev, - if (((check_fwstate(pmlmepriv, _FW_LINKED)) == _TRUE) || + if (((check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) == _TRUE) || ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) || ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == _TRUE)) @@ -2000,7 +1983,7 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, /* When Busy Traffic, driver do not site survey. So driver return success. */ /* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */ /* modify by thomas 2011-02-22. */ - if (rtw_mi_busy_traffic_check(padapter, _FALSE)) { + if (rtw_mi_busy_traffic_check(padapter)) { indicate_wx_scan_complete_event(padapter); goto cancel_ps_deny; } @@ -2018,14 +2001,14 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, goto cancel_ps_deny; } - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING) == _TRUE) { indicate_wx_scan_complete_event(padapter); goto cancel_ps_deny; } #ifdef CONFIG_CONCURRENT_MODE if (rtw_mi_buddy_check_fwstate(padapter, - _FW_UNDER_SURVEY | _FW_UNDER_LINKING | WIFI_UNDER_WPS)) { + WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING | WIFI_UNDER_WPS)) { indicate_wx_scan_complete_event(padapter); goto cancel_ps_deny; @@ -2213,18 +2196,18 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, #endif /* CONFIG_P2P */ #if 1 /* Wireless Extension use EAGAIN to try */ - wait_status = _FW_UNDER_SURVEY -#ifndef CONFIG_ANDROID - | _FW_UNDER_LINKING + wait_status = WIFI_UNDER_SURVEY +#ifndef CONFIG_RTW_ANDROID + | WIFI_UNDER_LINKING #endif ; while (check_fwstate(pmlmepriv, wait_status) == _TRUE) return -EAGAIN; #else - wait_status = _FW_UNDER_SURVEY -#ifndef CONFIG_ANDROID - | _FW_UNDER_LINKING + wait_status = WIFI_UNDER_SURVEY +#ifndef CONFIG_RTW_ANDROID + | WIFI_UNDER_LINKING #endif ; @@ -2345,7 +2328,7 @@ static int rtw_wx_set_essid(struct net_device *dev, } #ifdef CONFIG_CONCURRENT_MODE - if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) { + if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING)) { RTW_INFO("set ssid, but buddy_intf is under scanning or linking\n"); ret = -EINVAL; goto cancel_ps_deny; @@ -2454,7 +2437,7 @@ static int rtw_wx_get_essid(struct net_device *dev, - if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) || + if ((check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) || (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) { len = pcur_bss->Ssid.SsidLength; @@ -2479,7 +2462,9 @@ static int rtw_wx_set_rate(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *extra) { - int i, ret = 0; + int ret = 0; +#if 0 + int i; _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); u8 datarates[NumRates]; u32 target_rate = wrqu->bitrate.value; @@ -2553,7 +2538,7 @@ set_rate: ret = -1; } - +#endif return ret; } @@ -2834,7 +2819,7 @@ static int rtw_wx_get_enc(struct net_device *dev, struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - if (check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) != _TRUE) { if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE) { erq->length = 0; erq->flags |= IW_ENCODE_DISABLED; @@ -3032,11 +3017,11 @@ static int rtw_wx_set_auth(struct net_device *dev, case IW_AUTH_80211_AUTH_ALG: -#if defined(CONFIG_ANDROID) || 1 +#if defined(CONFIG_RTW_ANDROID) || 1 /* * It's the starting point of a link layer connection using wpa_supplicant */ - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { + if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) { LeaveAllPowerSaveMode(padapter); rtw_disassoc_cmd(padapter, 500, RTW_CMDF_WAIT_ACK); RTW_INFO("%s...call rtw_indicate_disconnect\n ", __FUNCTION__); @@ -3255,6 +3240,7 @@ static int rtw_wx_get_nick(struct net_device *dev, return 0; } +#endif static int rtw_wx_read32(struct net_device *dev, struct iw_request_info *info, @@ -3429,6 +3415,7 @@ static int rtw_wx_priv_rrm(struct net_device *dev, struct iw_request_info *a, } #endif +#ifdef CONFIG_IOCTL_WEXT static int dummy(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *b) { @@ -3440,6 +3427,7 @@ static int dummy(struct net_device *dev, struct iw_request_info *a, return -1; } +#endif static int rtw_wx_set_channel_plan(struct net_device *dev, struct iw_request_info *info, @@ -3724,7 +3712,7 @@ static int rtw_get_ap_info(struct net_device *dev, goto exit; } - while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING))) == _TRUE) { + while ((check_fwstate(pmlmepriv, (WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING))) == _TRUE) { rtw_msleep_os(30); cnt++; if (cnt > 100) @@ -3756,7 +3744,6 @@ static int rtw_get_ap_info(struct net_device *dev, pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); - /* if(hwaddr_aton_i(pdata->pointer, bssid)) */ if (hwaddr_aton_i(data, bssid)) { RTW_INFO("Invalid BSSID '%s'.\n", (u8 *)data); _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); @@ -3877,6 +3864,9 @@ static int rtw_wext_p2p_enable(struct net_device *dev, struct wifidirect_info *pwdinfo = &(padapter->wdinfo); struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; enum P2P_ROLE init_role = P2P_ROLE_DISABLE; +#ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; +#endif if (*extra == '0') init_role = P2P_ROLE_DISABLE; @@ -3907,7 +3897,7 @@ static int rtw_wext_p2p_enable(struct net_device *dev, #ifdef CONFIG_CONCURRENT_MODE else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) { - _set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval); + _set_timer(&prochinfo->ap_roch_ch_switch_timer, pwdinfo->ext_listen_interval); channel = rtw_mi_get_union_chan(padapter); ch_offset = rtw_mi_get_union_offset(padapter); @@ -4725,6 +4715,9 @@ static int rtw_p2p_connect(struct net_device *dev, _queue *queue = &(pmlmepriv->scanned_queue); struct wlan_network *pnetwork = NULL; uint uintPeerChannel = 0; +#ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; +#endif /* Commented by Albert 20110304 */ /* The input data contains two informations. */ @@ -4778,7 +4771,7 @@ static int rtw_p2p_connect(struct net_device *dev, if (uintPeerChannel) { #ifdef CONFIG_CONCURRENT_MODE if (rtw_mi_check_status(padapter, MI_LINKED)) - _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer); + _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer); #endif /* CONFIG_CONCURRENT_MODE */ _rtw_memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info)); @@ -4846,6 +4839,9 @@ static int rtw_p2p_invite_req(struct net_device *dev, uint p2pielen = 0, attr_contentlen = 0; _irqL irqL; struct tx_invite_req_info *pinvite_req_info = &pwdinfo->invitereq_info; +#ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; +#endif /* Commented by Albert 20120321 */ /* The input data contains two informations. */ @@ -4957,7 +4953,7 @@ static int rtw_p2p_invite_req(struct net_device *dev, if (uintPeerChannel) { #ifdef CONFIG_CONCURRENT_MODE if (rtw_mi_check_status(padapter, MI_LINKED)) - _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer); + _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer); #endif /* CONFIG_CONCURRENT_MODE */ /* Store the GO's bssid */ @@ -5327,6 +5323,9 @@ static int rtw_p2p_prov_disc(struct net_device *dev, u8 *p2pie; uint p2pielen = 0, attr_contentlen = 0; _irqL irqL; +#ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; +#endif /* Commented by Albert 20110301 */ /* The input data contains two informations. */ @@ -5456,7 +5455,7 @@ static int rtw_p2p_prov_disc(struct net_device *dev, RTW_INFO("[%s] peer channel: %d!\n", __FUNCTION__, uintPeerChannel); #ifdef CONFIG_CONCURRENT_MODE if (rtw_mi_check_status(padapter, MI_LINKED)) - _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer); + _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer); #endif /* CONFIG_CONCURRENT_MODE */ _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN); _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN); @@ -5749,68 +5748,6 @@ static int rtw_cta_test_start(struct net_device *dev, return ret; } #endif -extern int rtw_change_ifname(_adapter *padapter, const char *ifname); -static int rtw_rereg_nd_name(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - _adapter *padapter = rtw_netdev_priv(dev); - struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); - struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv; - char new_ifname[IFNAMSIZ]; - - if (rereg_priv->old_ifname[0] == 0) { - char *reg_ifname; -#ifdef CONFIG_CONCURRENT_MODE - if (padapter->isprimary) - reg_ifname = padapter->registrypriv.ifname; - else -#endif - reg_ifname = padapter->registrypriv.if2name; - - strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ); - rereg_priv->old_ifname[IFNAMSIZ - 1] = 0; - } - - /* RTW_INFO("%s wrqu->data.length:%d\n", __FUNCTION__, wrqu->data.length); */ - if (wrqu->data.length > IFNAMSIZ) - return -EFAULT; - - if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ)) - return -EFAULT; - - if (0 == strcmp(rereg_priv->old_ifname, new_ifname)) - return ret; - - RTW_INFO("%s new_ifname:%s\n", __FUNCTION__, new_ifname); - rtw_set_rtnl_lock_holder(dvobj, current); - ret = rtw_change_ifname(padapter, new_ifname); - rtw_set_rtnl_lock_holder(dvobj, NULL); - if (0 != ret) - goto exit; - - if (_rtw_memcmp(rereg_priv->old_ifname, "disable%d", 9) == _TRUE) { - /* rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode); */ - } - - strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ); - rereg_priv->old_ifname[IFNAMSIZ - 1] = 0; - - if (_rtw_memcmp(new_ifname, "disable%d", 9) == _TRUE) { - - RTW_INFO("%s disable\n", __FUNCTION__); - /* free network queue for Android's timming issue */ - rtw_free_network_queue(padapter, _TRUE); - - /* the interface is being "disabled", we can do deeper IPS */ - /* rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv); */ - /* rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL); */ - } -exit: - return ret; - -} #ifdef CONFIG_IOL #include @@ -5826,8 +5763,9 @@ static int rtw_dbg_port(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - _irqL irqL; int ret = 0; +#ifdef CONFIG_RTW_DEBUG + _irqL irqL; u8 major_cmd, minor_cmd; u16 arg; u32 extra_arg, *pdata, val32; @@ -6647,11 +6585,12 @@ static int rtw_dbg_port(struct net_device *dev, break; } - +#endif return ret; } +#ifdef CONFIG_IOCTL_WEXT static int wpa_set_param(struct net_device *dev, u8 name, u32 value) { uint ret = 0; @@ -7184,7 +7123,7 @@ static int rtw_add_sta(struct net_device *dev, struct ieee_param *param) RTW_INFO("rtw_add_sta(aid=%d)=" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr)); - if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE) + if (check_fwstate(pmlmepriv, (WIFI_ASOC_STATE | WIFI_AP_STATE)) != _TRUE) return -EINVAL; if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && @@ -7263,7 +7202,7 @@ static int rtw_del_sta(struct net_device *dev, struct ieee_param *param) RTW_INFO("rtw_del_sta=" MAC_FMT "\n", MAC_ARG(param->sta_addr)); - if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE) + if (check_fwstate(pmlmepriv, (WIFI_ASOC_STATE | WIFI_AP_STATE)) != _TRUE) return -EINVAL; if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && @@ -7281,6 +7220,10 @@ static int rtw_del_sta(struct net_device *dev, struct ieee_param *param) if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) { rtw_list_delete(&psta->asoc_list); pstapriv->asoc_list_cnt--; + #ifdef CONFIG_RTW_TOKEN_BASED_XMIT + if (psta->tbtx_enable) + pstapriv->tbtx_asoc_list_cnt--; + #endif updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, _TRUE); } @@ -7313,7 +7256,7 @@ static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *par RTW_INFO("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr)); - if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE) + if (check_fwstate(pmlmepriv, (WIFI_ASOC_STATE | WIFI_AP_STATE)) != _TRUE) return -EINVAL; if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff && @@ -7392,7 +7335,7 @@ static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param) RTW_INFO("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr)); - if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE) + if (check_fwstate(pmlmepriv, (WIFI_ASOC_STATE | WIFI_AP_STATE)) != _TRUE) return -EINVAL; if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && @@ -7784,7 +7727,7 @@ out: return ret; } -#endif +#endif /* CONFIG_AP_MODE */ static int rtw_wx_set_priv(struct net_device *dev, struct iw_request_info *info, @@ -7799,7 +7742,7 @@ static int rtw_wx_set_priv(struct net_device *dev, int ret = 0; int len = 0; char *ext; -#ifdef CONFIG_ANDROID +#ifdef CONFIG_RTW_ANDROID int i; #endif @@ -7874,7 +7817,7 @@ static int rtw_wx_set_priv(struct net_device *dev, goto FREE_EXT; } -#ifdef CONFIG_ANDROID +#ifdef CONFIG_RTW_ANDROID /* RTW_INFO("rtw_wx_set_priv: %s req=%s\n", dev->name, ext); */ i = rtw_android_cmdstr_to_num(ext); @@ -7890,7 +7833,7 @@ static int rtw_wx_set_priv(struct net_device *dev, struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); struct wlan_network *pcur_network = &pmlmepriv->cur_network; - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) sprintf(ext, "%s rssi %d", pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi); else sprintf(ext, "OK"); @@ -7955,6 +7898,8 @@ FREE_EXT: return ret; } +#endif /*CONFIG_IOCTL_WEXT*/ + #ifdef CONFIG_WOWLAN static int rtw_wowlan_ctrl(struct net_device *dev, struct iw_request_info *info, @@ -7970,7 +7915,7 @@ static int rtw_wowlan_ctrl(struct net_device *dev, RTW_INFO("+rtw_wowlan_ctrl: %s\n", extra); - if (!check_fwstate(pmlmepriv, _FW_LINKED) && + if (!check_fwstate(pmlmepriv, WIFI_ASOC_STATE) && check_fwstate(pmlmepriv, WIFI_STATION_STATE) && !WOWLAN_IS_STA_MIX_MODE(padapter)) { #ifdef CONFIG_PNO_SUPPORT @@ -7981,7 +7926,7 @@ static int rtw_wowlan_ctrl(struct net_device *dev, #endif /* CONFIG_PNO_SUPPORT */ } - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)) rtw_scan_abort(padapter); if (_rtw_memcmp(extra, "enable", 6)) @@ -8036,21 +7981,21 @@ static int rtw_wowlan_set_pattern(struct net_device *dev, struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wowlan_ioctl_param poidparam; int ret = 0; - u8 input[wrqu->data.length]; + u8 input[MAX_IN_PATTERN_SIZE]; u8 index = 0; poidparam.subcode = 0; - if (!check_fwstate(pmlmepriv, _FW_LINKED) && + if (!check_fwstate(pmlmepriv, WIFI_ASOC_STATE) && check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ret = -EFAULT; RTW_INFO("Please Connect With AP First!!\n"); goto _rtw_wowlan_set_pattern_exit; } - if (wrqu->data.length <= 0) { + if ((wrqu->data.length <= 0) || (wrqu->data.length > MAX_IN_PATTERN_SIZE)) { ret = -EFAULT; - RTW_INFO("ERROR: parameter length <= 0\n"); + RTW_INFO("ERROR: parameter length error, len=%d\n", wrqu->data.length); goto _rtw_wowlan_set_pattern_exit; } else { /* set pattern */ @@ -8060,7 +8005,7 @@ static int rtw_wowlan_set_pattern(struct net_device *dev, /* leave PS first */ rtw_ps_deny(padapter, PS_DENY_IOCTL); LeaveAllPowerSaveModeDirect(padapter); - if (strncmp(input, "pattern=", 8) == 0) { + if ((strncmp(input, "pattern=", 8) == 0) ||(strncmp(input, "ack_pattern=", 12) == 0)) { if (pwrpriv->wowlan_pattern_idx >= MAX_WKFM_CAM_NUM) { RTW_INFO("WARNING: priv-pattern is full(idx: %d)\n", pwrpriv->wowlan_pattern_idx); @@ -8074,11 +8019,25 @@ static int rtw_wowlan_set_pattern(struct net_device *dev, &pwrpriv->patterns[index].len, pwrpriv->patterns[index].mask); - if (ret == _TRUE) + if (ret == _TRUE) { + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + if(strncmp(input, "ack_pattern=", 12) == 0) + pwrpriv->wowlan_keep_alive_ack_index = index; + else + pwrpriv->wowlan_wake_pattern_index = index; + RTW_INFO("pwrpriv->wowlan_keep_alive_ack_index =%d\n",pwrpriv->wowlan_keep_alive_ack_index); + RTW_INFO("pwrpriv->wowlan_wake_pattern_index =%d\n",pwrpriv->wowlan_wake_pattern_index); + #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ pwrpriv->wowlan_pattern_idx++; + } } } else if (strncmp(input, "clean", 5) == 0) { poidparam.subcode = WOWLAN_PATTERN_CLEAN; + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + pwrpriv->wowlan_wake_pattern_index = 0xFF; + pwrpriv->wowlan_keep_alive_ack_index = 0xFF; + #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + rtw_hal_set_hwreg(padapter, HW_VAR_WOWLAN, (u8 *)&poidparam); } else if (strncmp(input, "show", 4) == 0) { @@ -8093,6 +8052,105 @@ static int rtw_wowlan_set_pattern(struct net_device *dev, _rtw_wowlan_set_pattern_exit: return ret; } + +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +static int rtw_wowlan_set_keep_alive_pattern(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + + int ret = 0,totoal_len=0,i=0,len=0; + char *cp = NULL; + u32 mode = 0xFF; /*para1*/ + u16 period = 15*10; /* para2;units:100ms,default 15s*/ + char tx_pattern[512]; /*para3*/ + u32 retry_intervel = 2*10; /* para4;units:100ms,default 2s*/ + u32 retry_limit_count = 5; /*para5*/ + + ret = sscanf(extra, "%d %hu %s %d %d", &mode , &period, tx_pattern, &retry_intervel, &retry_limit_count); + pwrpriv->wowlan_keep_alive_mode = mode; + + RTW_INFO("[%s] ret =%d \n", __func__ ,ret); + totoal_len = strlen(tx_pattern); + RTW_INFO("[%s] totoal_len=%d \n", __func__ ,totoal_len); + + if (mode && (ret < 3)) + return -EINVAL; + + if (((mode ==2) ||(mode ==3)) && ((retry_intervel*retry_limit_count) > period)) { + RTW_INFO("[%s] retry_intervel*retry_limit_count need smaller than period\n", __func__ ); + return -EINVAL; + } + + switch(mode){ + case wow_keep_alive_pattern_disable: + /*disable this feature*/ + pwrpriv->keep_alive_pattern_loc = 0; + pwrpriv->keep_alive_pattern_len = 0; + pwrpriv->wowlan_keep_alive_period = 0; + pwrpriv->wowlan_keep_alive_ack_index = 0xFF; + pwrpriv->wowlan_wake_pattern_index = 0xFF; + pwrpriv->wowlan_keep_alive_retry_interval = 0; + pwrpriv->wowlan_keep_alive_retry_counter = 0; + _rtw_memset(pwrpriv->keep_alive_pattern,0,WLAN_MAX_KEEP_ALIVE_IE_LEN); + RTW_INFO("[%s] clear pattern \n", __func__ ); + ret = _SUCCESS; + break; + case wow_keep_alive_pattern_tx: + /*only tx udp packet*/ + pwrpriv->wowlan_keep_alive_period = period; + pwrpriv->wowlan_keep_alive_retry_interval = 0; + pwrpriv->wowlan_keep_alive_retry_counter = 0; + RTW_INFO("[%s] wow_keep_alive_pattern_tx \n", __func__ ); + break; + case wow_keep_alive_pattern_trx: + /*trx+no need wakeup*/ + pwrpriv->wowlan_keep_alive_period = period; + pwrpriv->wowlan_keep_alive_retry_interval = retry_intervel; + pwrpriv->wowlan_keep_alive_retry_counter = retry_limit_count; + RTW_INFO("[%s] wow_keep_alive_pattern_trx \n", __func__ ); + break; + case wow_keep_alive_pattern_trx_with_ack: + /*trx+need wakeup*/ + pwrpriv->wowlan_keep_alive_period = period; + pwrpriv->wowlan_keep_alive_retry_interval = retry_intervel; + pwrpriv->wowlan_keep_alive_retry_counter = retry_limit_count; + RTW_INFO("[%s] wow_keep_alive_pattern_trx_with_ack \n", __func__ ); + break; + default: + RTW_INFO("[%s] please setting valid mode \n", __func__ ); + ret = -EINVAL; + break; + + } + + if((mode == 0) || (mode > 4)) + return ret; + + totoal_len = strlen(tx_pattern); + RTW_INFO("[%s] totoal_len=%d \n", __func__ ,totoal_len); + if (totoal_len > WLAN_MAX_KEEP_ALIVE_IE_LEN*2) { + RTW_INFO("[%s] Fail , not support ie length extend %d\n", __func__ , WLAN_MAX_KEEP_ALIVE_IE_LEN); + return -EFAULT; + } + RTW_INFO("[%s] period = %hu ,ie = %s , len = %d\n", __func__ , period , tx_pattern , totoal_len); + + + if (totoal_len > 0) { + RTW_INFO("[%s] pwrpriv->keep_alive_pattern==========> \n", __func__ ); + for (i = 0 ; i keep_alive_pattern[len] = key_2char2num(tx_pattern[i], tx_pattern[i + 1]); + RTW_INFO("[0x%x] ",pwrpriv->keep_alive_pattern[len]); + len++; + } + RTW_INFO(" \n" ); + pwrpriv->keep_alive_pattern_len = len; + } + + return ret; +} +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + #endif /* CONFIG_WOWLAN */ #ifdef CONFIG_AP_WOWLAN @@ -9132,7 +9190,9 @@ static int rtw_mp_efuse_set(struct net_device *dev, if (copy_from_user(extra, wrqu->pointer, wrqu->length)) return -EFAULT; - +#ifdef CONFIG_RTL8822C + rtw_pre_bt_efuse(padapter); +#endif *(extra + wrqu->length) = '\0'; EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&wifimaplen, _FALSE); @@ -9577,7 +9637,7 @@ static int rtw_mp_efuse_set(struct net_device *dev, err = -EFAULT; } } else if (strcmp(tmp[0], "btfk2map") == 0) { - +#ifdef CONFIG_BT_EFUSE_MASK if (padapter->registrypriv.bBTFileMaskEfuse != _TRUE && pmp_priv->bloadBTefusemap == _TRUE) { RTW_INFO("%s: File BT eFuse mask file not to be loaded\n", __FUNCTION__); sprintf(extra, "Not load BT eFuse mask file yet, Please advance to use [ efuse_bt_mask ], now remove the Adapter.!!!!\n"); @@ -9585,7 +9645,7 @@ static int rtw_mp_efuse_set(struct net_device *dev, err = 0; goto exit; } - +#endif rtw_write8(padapter, 0xa3, 0x05); BTStatus = rtw_read8(padapter, 0xa0); RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __FUNCTION__, BTStatus); @@ -9611,10 +9671,10 @@ static int rtw_mp_efuse_set(struct net_device *dev, rtw_read8(padapter, EFUSE_CTRL); BTEfuse_PowerSwitch(padapter, 1, _FALSE); #endif /* RTW_HALMAC */ - _rtw_memcpy(pEfuseHal->BTEfuseModifiedMap, pEfuseHal->fakeBTEfuseModifiedMap, EFUSE_BT_MAX_MAP_LEN); if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL) { RTW_INFO("%s: rtw_BT_efuse_map_write error!\n", __FUNCTION__); + sprintf(extra, "BT write FAIL !!!\n"); err = -EFAULT; goto exit; } @@ -9803,37 +9863,30 @@ static int rtw_mp_efuse_set(struct net_device *dev, RTW_INFO("%s: MAC address=%s\n", __FUNCTION__, tmp[1]); for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) - pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]); + if ((addr + jj) < EFUSE_MAX_MAP_LEN) + pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]); _rtw_memset(extra, '\0', strlen(extra)); sprintf(extra, "write mac addr to fake map OK\n"); } else if(strcmp(tmp[0], "update") == 0) { - RTW_INFO("To Use new eFuse map\n"); - /*step read efuse/eeprom data and get mac_addr*/ - rtw_hal_read_chip_info(padapter); - /* set mac addr*/ - rtw_macaddr_cfg(adapter_mac_addr(padapter), get_hal_mac_addr(padapter)); - _rtw_memcpy(padapter->pnetdev->dev_addr, get_hal_mac_addr(padapter), ETH_ALEN); /* set mac addr to net_device */ - -#ifdef CONFIG_P2P - rtw_init_wifidirect_addrs(padapter, adapter_mac_addr(padapter), adapter_mac_addr(padapter)); -#endif -#ifdef CONFIG_MI_WITH_MBSSID_CAM - rtw_hal_change_macaddr_mbid(padapter, adapter_mac_addr(padapter)); -#else - rtw_hal_set_hwreg(padapter, HW_VAR_MAC_ADDR, adapter_mac_addr(padapter)); /* set mac addr to mac register */ -#endif - /*pHalFunc->hal_deinit(padapter);*/ - if (pHalFunc->hal_init(padapter) == _FAIL) { - err = -EINVAL; - goto exit; + RTW_INFO("To Use new eFuse map ver3\n"); + if (tmp[1] != 0x00) { + pmp_priv->efuse_update_file = _TRUE; + strcpy(pmp_priv->efuse_file_path , tmp[1]); + RTW_INFO("Got file path %s\n", pmp_priv->efuse_file_path); } - pHalData->current_channel = 0; - pHalData->current_channel_bw = CHANNEL_WIDTH_MAX; - pHalData->current_band_type = BAND_MAX; - - _rtw_memset(extra, '\0', strlen(extra)); - sprintf(extra, "eFuse Update OK\n"); + /*step read efuse/eeprom data and get mac_addr*/ + if (padapter->hal_func.read_adapter_info(padapter)) { + _rtw_memset(extra, '\0', strlen(extra)); + sprintf(extra, "eFuse Update OK\n"); + RTW_INFO("eFuse Update OK\n"); + } else { + _rtw_memset(extra, '\0', strlen(extra)); + sprintf(extra, "eFuse Update FAIL\n"); + RTW_INFO("eFuse Update FAIL\n"); + } + pmp_priv->efuse_update_file = _FALSE; + RTW_INFO("To Use new eFuse map done ver3\n"); } else if (strcmp(tmp[0], "analyze") == 0) { rtw_efuse_analyze(padapter, EFUSE_WIFI, 0); @@ -10127,6 +10180,10 @@ static int rtw_priv_mp_get(struct net_device *dev, RTW_INFO("set case MP_PWRTRK\n"); status = rtw_mp_pwrtrk(dev, info, wrqu, extra); break; + case MP_SET_TSSIDE: + RTW_INFO("set case MP_TSSI_DE\n"); + status = rtw_mp_set_tsside(dev, info, wrqu, extra); + break; #ifdef CONFIG_MP_INCLUDED case EFUSE_SET: RTW_INFO("set case efuse set\n"); @@ -10157,15 +10214,19 @@ static int rtw_priv_mp_get(struct net_device *dev, RTW_INFO("mp_get EFUSE_MASK\n"); status = rtw_efuse_mask_file(dev, info, wdata, extra); break; - case EFUSE_FILE: + case EFUSE_FILE: RTW_INFO("mp_get EFUSE_FILE\n"); status = rtw_efuse_file_map(dev, info, wdata, extra); break; - case MP_TX: + case EFUSE_FILE_STORE: + RTW_INFO("mp_get EFUSE_FILE_STORE\n"); + status = rtw_efuse_file_map_store(dev, info, wdata, extra); + break; + case MP_TX: RTW_INFO("mp_get MP_TX\n"); status = rtw_mp_tx(dev, info, wdata, extra); break; - case MP_RX: + case MP_RX: RTW_INFO("mp_get MP_RX\n"); status = rtw_mp_rx(dev, info, wdata, extra); break; @@ -10173,6 +10234,10 @@ static int rtw_priv_mp_get(struct net_device *dev, RTW_INFO("mp_get MP_HW_TX_MODE\n"); status = rtw_mp_hwtx(dev, info, wdata, extra); break; + case MP_GET_TSSIDE: + RTW_INFO("mp_get TSSI_DE\n"); + status = rtw_mp_get_tsside(dev, info, wrqu, extra); + break; #ifdef CONFIG_RTW_CUSTOMER_STR case MP_CUSTOMER_STR: RTW_INFO("customer str\n"); @@ -10397,6 +10462,13 @@ static int rtw_priv_set(struct net_device *dev, RTW_INFO("set case MP_WOW_SET_PATTERN: %s\n", extra); rtw_wowlan_set_pattern(dev, info, wdata, extra); break; + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + case MP_WOW_SET_KEEP_ALIVE_PATTERN: + RTW_INFO("set case MP_WOW_SET_KEEP_ALIVE_PATTERN: %s\n", extra); + rtw_wowlan_set_keep_alive_pattern(dev, info, wdata, extra); + break; + #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + #endif #ifdef CONFIG_AP_WOWLAN case MP_AP_WOW_ENABLE: @@ -10431,8 +10503,6 @@ static int rtw_priv_get(struct net_device *dev, struct dm_iqk_info *p_iqk_info = &p_dm->IQK_info; u32 i = 100; - if (padapter == NULL) - return -ENETDOWN; if (padapter->bup == _FALSE) { RTW_INFO(" %s fail =>(padapter->bup == _FALSE )\n", __FUNCTION__); @@ -10460,7 +10530,7 @@ static int rtw_priv_get(struct net_device *dev, } i--; } - if (subcmd == MP_CHANNEL || subcmd == MP_BANDWIDTH) + if (subcmd == MP_CHANNEL || subcmd == MP_BANDWIDTH || subcmd == MP_START || subcmd == MP_DPK) p_iqk_info->rfk_forbidden = _FALSE; rtw_priv_mp_get(dev, info, wdata, extra); rtw_msleep_os(10); /* delay 5ms for sending pkt before exit adb shell operation */ @@ -10712,6 +10782,9 @@ static int rtw_tdls_ch_switch(struct net_device *dev, rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk); if (take_care_iqk == _TRUE) { +#ifdef CONFIG_TDLS_CH_SW_V2 + rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_PREPARE); +#else u8 central_chnl; u8 bw_mode; @@ -10721,6 +10794,7 @@ static int rtw_tdls_ch_switch(struct net_device *dev, rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START); else rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_PREPARE); +#endif } else rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START); @@ -11344,7 +11418,7 @@ static int rtw_tdls_get(struct net_device *dev, #if defined(CONFIG_RTL8188E) #include extern void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc); -#define cal_txdesc_chksum rtl8188e_cal_txdesc_chksum +#define cal_txdesc_chksum(padapter, desc) rtl8188e_cal_txdesc_chksum(desc) #ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI) extern void rtl8188es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); #define fill_default_txdesc rtl8188es_fill_default_txdesc @@ -11352,33 +11426,33 @@ extern void rtl8188es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbu #endif /* CONFIG_RTL8188E */ #if defined(CONFIG_RTL8723B) extern void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc); -#define cal_txdesc_chksum rtl8723b_cal_txdesc_chksum +#define cal_txdesc_chksum(padapter, desc) rtl8723b_cal_txdesc_chksum(desc) extern void rtl8723b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); #define fill_default_txdesc rtl8723b_fill_default_txdesc #endif /* CONFIG_RTL8723B */ #if defined(CONFIG_RTL8703B) /* extern void rtl8703b_cal_txdesc_chksum(struct tx_desc *ptxdesc); */ -#define cal_txdesc_chksum rtl8703b_cal_txdesc_chksum +#define cal_txdesc_chksum(padapter, desc) rtl8703b_cal_txdesc_chksum(desc) /* extern void rtl8703b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */ #define fill_default_txdesc rtl8703b_fill_default_txdesc #endif /* CONFIG_RTL8703B */ #if defined(CONFIG_RTL8723D) /* extern void rtl8723d_cal_txdesc_chksum(struct tx_desc *ptxdesc); */ -#define cal_txdesc_chksum rtl8723d_cal_txdesc_chksum +#define cal_txdesc_chksum(padapter, desc) rtl8723d_cal_txdesc_chksum(desc) /* extern void rtl8723d_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */ #define fill_default_txdesc rtl8723d_fill_default_txdesc #endif /* CONFIG_RTL8723D */ #if defined(CONFIG_RTL8710B) -#define cal_txdesc_chksum rtl8710b_cal_txdesc_chksum +#define cal_txdesc_chksum(padapter, desc) rtl8710b_cal_txdesc_chksum(desc) #define fill_default_txdesc rtl8710b_fill_default_txdesc #endif /* CONFIG_RTL8710B */ #if defined(CONFIG_RTL8192E) extern void rtl8192e_cal_txdesc_chksum(struct tx_desc *ptxdesc); -#define cal_txdesc_chksum rtl8192e_cal_txdesc_chksum +#define cal_txdesc_chksum(padapter, desc) rtl8192e_cal_txdesc_chksum(desc) #ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI) extern void rtl8192es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); #define fill_default_txdesc rtl8192es_fill_default_txdesc @@ -11387,16 +11461,46 @@ extern void rtl8192es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbu #if defined(CONFIG_RTL8192F) /* extern void rtl8192f_cal_txdesc_chksum(struct tx_desc *ptxdesc); */ -#define cal_txdesc_chksum rtl8192f_cal_txdesc_chksum +#define cal_txdesc_chksum(padapter, desc) rtl8192f_cal_txdesc_chksum(desc) /* extern void rtl8192f_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */ #define fill_default_txdesc rtl8192f_fill_default_txdesc #endif /* CONFIG_RTL8192F */ +#ifdef CONFIG_RTL8723F +#include <../../hal/rtl8723f/rtl8723f.h> + +#define REG_LOOPBACK_ENABLE 0x0103 +#define LOOKBACK_ENABLE_VALUE 0x0b +#define cal_txdesc_chksum(padapter, desc) rtl8723f_cal_txdesc_chksum(padapter, desc) +#define dump_txdesc_data(padapter, desc) rtl8723f_dbg_dump_tx_desc(padapter, DATA_FRAMETAG, desc); +#define get_rx_desc(rx_desc, rxbuf) rtl8723f_rxdesc2attribute(rx_desc, rxbuf) +#define hal_init rtl8723f_hal_init +#endif /* CONFIG_RTL8723F */ + +void dbg_dump_pkt(char *s, u8 *buf, u8 len) +{ + u8 i, j = 1; + + RTW_INFO("%s size = %u\n", s, len); + + for (i = 0; (i + 4) < len; i += 4) { + if (j % 4 == 1) + RTW_PRINT("idx:%u:", i); + _RTW_PRINT(" 0x%02x 0x%02x 0x%02x 0x%02x", buf[i], buf[i+1], buf[i+2], buf[i+3]); + if ((j++) % 4 == 0) + _RTW_PRINT("\n"); + } + + for (; i < len ; i++) { + _RTW_PRINT(" 0x%02x", buf[i]); + } + _RTW_PRINT("\n ================================\n"); +} + static s32 initLoopback(PADAPTER padapter) { PLOOPBACKDATA ploopback; - if (padapter->ploopback == NULL) { ploopback = (PLOOPBACKDATA)rtw_zmalloc(sizeof(LOOPBACKDATA)); if (ploopback == NULL) @@ -11418,7 +11522,6 @@ static void freeLoopback(PADAPTER padapter) { PLOOPBACKDATA ploopback; - ploopback = padapter->ploopback; if (ploopback) { rtw_mfree((u8 *)ploopback, sizeof(LOOPBACKDATA)); @@ -11454,7 +11557,6 @@ static s32 createpseudoadhoc(PADAPTER padapter) s32 err; _irqL irqL; - pmlmepriv = &padapter->mlmepriv; authmode = Ndis802_11AuthModeOpen; @@ -11536,7 +11638,7 @@ static struct xmit_frame *createloopbackpkt(PADAPTER padapter, u32 size) pframe = NULL; /* 2 1. allocate xmit frame */ - pframe = rtw_alloc_xmitframe(pxmitpriv); + pframe = rtw_alloc_xmitframe(pxmitpriv, 0); if (pframe == NULL) return NULL; pframe->padapter = padapter; @@ -11596,6 +11698,7 @@ static struct xmit_frame *createloopbackpkt(PADAPTER padapter, u32 size) fill_default_txdesc(pframe, (u8 *)desc); +#if 0 /* Hw set sequence number */ ((PTXDESC)desc)->hwseq_en = 0; /* HWSEQ_EN, 0:disable, 1:enable * ((PTXDESC)desc)->hwseq_sel = 0; */ /* HWSEQ_SEL */ @@ -11620,9 +11723,11 @@ static struct xmit_frame *createloopbackpkt(PADAPTER padapter, u32 size) desc->txdw13 = cpu_to_le32(desc->txdw13); desc->txdw14 = cpu_to_le32(desc->txdw14); desc->txdw15 = cpu_to_le32(desc->txdw15); +#endif #endif - cal_txdesc_chksum(desc); + cal_txdesc_chksum(padapter, (u8*)desc); + /* dump_txdesc_data(padapter, (u8*)desc); */ /* 2 5. coalesce */ pkt_start = pframe->buf_addr + TXDESC_SIZE; @@ -11640,7 +11745,11 @@ static struct xmit_frame *createloopbackpkt(PADAPTER padapter, u32 size) get_random_bytes(ptr, pkt_end - ptr); pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz; +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) pxmitbuf->ptail += pxmitbuf->len; +#endif + + dbg_dump_pkt("TX packet", pxmitbuf->pbuf, pxmitbuf->len); return pframe; } @@ -11650,7 +11759,6 @@ static void freeloopbackpkt(PADAPTER padapter, struct xmit_frame *pframe) struct xmit_priv *pxmitpriv; struct xmit_buf *pxmitbuf; - pxmitpriv = &padapter->xmitpriv; pxmitbuf = pframe->pxmitbuf; @@ -11662,7 +11770,6 @@ static void printdata(u8 *pbuf, u32 len) { u32 i, val; - for (i = 0; (i + 4) <= len; i += 4) { printk("%08X", *(u32 *)(pbuf + i)); if ((i + 4) & 0x1F) @@ -11697,15 +11804,23 @@ static void printdata(u8 *pbuf, u32 len) static u8 pktcmp(PADAPTER padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz) { - PHAL_DATA_TYPE phal; + struct rx_pkt_attrib rx_desc; +#if 0 struct recv_stat *prxstat; struct recv_stat report; PRXREPORT prxreport; - u32 drvinfosize; +#endif u32 rxpktsize; - u8 fcssize; + u8 drvinfosize; + u8 shiftsize; u8 ret = _FALSE; + u8 skip_len = 4; /* Don't compare the frame control and duration field */ + get_rx_desc(&rx_desc, rxbuf); + rxpktsize = rx_desc.pkt_len; + drvinfosize = rx_desc.drvinfo_sz; + shiftsize = rx_desc.shift_sz; +#if 0 prxstat = (struct recv_stat *)rxbuf; report.rxdw0 = le32_to_cpu(prxstat->rxdw0); report.rxdw1 = le32_to_cpu(prxstat->rxdw1); @@ -11717,21 +11832,19 @@ static u8 pktcmp(PADAPTER padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz) prxreport = (PRXREPORT)&report; drvinfosize = prxreport->drvinfosize << 3; rxpktsize = prxreport->pktlen; +#endif - phal = GET_HAL_DATA(padapter); if (rtw_hal_rcr_check(padapter, RCR_APPFCS)) - fcssize = IEEE80211_FCS_LEN; - else - fcssize = 0; + rxpktsize -= IEEE80211_FCS_LEN; - if ((txsz - TXDESC_SIZE) != (rxpktsize - fcssize)) { + if ((txsz - TXDESC_SIZE) != rxpktsize) { RTW_INFO("%s: ERROR! size not match tx/rx=%d/%d !\n", - __func__, txsz - TXDESC_SIZE, rxpktsize - fcssize); + __func__, txsz - TXDESC_SIZE, rxpktsize); ret = _FALSE; } else { - ret = _rtw_memcmp(txbuf + TXDESC_SIZE, \ - rxbuf + RXDESC_SIZE + drvinfosize, \ - txsz - TXDESC_SIZE); + ret = _rtw_memcmp(txbuf + TXDESC_SIZE + skip_len, \ + rxbuf + RXDESC_SIZE + skip_len + drvinfosize, \ + txsz - TXDESC_SIZE - skip_len); if (ret == _FALSE) RTW_INFO("%s: ERROR! pkt content mismatch!\n", __func__); } @@ -11739,23 +11852,17 @@ static u8 pktcmp(PADAPTER padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz) if (ret == _FALSE) { RTW_INFO("\n%s: TX PKT total=%d, desc=%d, content=%d\n", __func__, txsz, TXDESC_SIZE, txsz - TXDESC_SIZE); - RTW_INFO("%s: TX DESC size=%d\n", __func__, TXDESC_SIZE); - printdata(txbuf, TXDESC_SIZE); - RTW_INFO("%s: TX content size=%d\n", __func__, txsz - TXDESC_SIZE); - printdata(txbuf + TXDESC_SIZE, txsz - TXDESC_SIZE); + dbg_dump_pkt("TX DESC", txbuf, TXDESC_SIZE); + dbg_dump_pkt("TX content", txbuf + TXDESC_SIZE, txsz - TXDESC_SIZE); RTW_INFO("\n%s: RX PKT read=%d offset=%d(%d,%d) content=%d\n", __func__, rxsz, RXDESC_SIZE + drvinfosize, RXDESC_SIZE, drvinfosize, rxpktsize); if (rxpktsize != 0) { - RTW_INFO("%s: RX DESC size=%d\n", __func__, RXDESC_SIZE); - printdata(rxbuf, RXDESC_SIZE); - RTW_INFO("%s: RX drvinfo size=%d\n", __func__, drvinfosize); - printdata(rxbuf + RXDESC_SIZE, drvinfosize); - RTW_INFO("%s: RX content size=%d\n", __func__, rxpktsize); - printdata(rxbuf + RXDESC_SIZE + drvinfosize, rxpktsize); + dbg_dump_pkt("RX DESC", rxbuf, RXDESC_SIZE); + dbg_dump_pkt("RX drvinfo", rxbuf + RXDESC_SIZE, drvinfosize); + dbg_dump_pkt("RX packet content", rxbuf + RXDESC_SIZE + drvinfosize, rxpktsize); } else { RTW_INFO("%s: RX data size=%d\n", __func__, rxsz); - printdata(rxbuf, rxsz); } } @@ -11772,7 +11879,6 @@ thread_return lbk_thread(thread_context context) u32 pktsize; u32 ff_hwaddr; - padapter = (PADAPTER)context; ploopback = padapter->ploopback; if (ploopback == NULL) @@ -11781,7 +11887,8 @@ thread_return lbk_thread(thread_context context) ok = 0; fail = 0; - daemonize("%s", "RTW_LBK_THREAD"); + thread_enter("RTW_LBK_THREAD"); + /* daemonize("%s", "RTW_LBK_THREAD"); */ allow_signal(SIGTERM); do { @@ -11802,10 +11909,13 @@ thread_return lbk_thread(thread_context context) ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe); cnt++; RTW_INFO("%s: wirte port cnt=%d size=%d\n", __func__, cnt, ploopback->txsize); +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) pxmitframe->pxmitbuf->pdata = ploopback->txbuf; +#endif rtw_write_port(padapter, ff_hwaddr, ploopback->txsize, (u8 *)pxmitframe->pxmitbuf); /* wait for rx pkt */ + RTW_INFO("%s: wait for rx packet\n", __func__); _rtw_down_sema(&ploopback->sema); err = pktcmp(padapter, ploopback->txbuf, ploopback->txsize, ploopback->rxbuf, ploopback->rxsize); @@ -11849,7 +11959,6 @@ static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8 *pmsg) u32 len; s32 err; - ploopback = padapter->ploopback; if (ploopback) { @@ -11864,6 +11973,7 @@ static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8 *pmsg) break; rtw_msleep_os(1); } while (1); + RTW_INFO("Free loopback, end the test.\n"); _rtw_memcpy(pmsg, ploopback->msg, len + 1); freeLoopback(padapter); @@ -11871,8 +11981,10 @@ static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8 *pmsg) } /* disable dynamic algorithm */ +#ifndef CONFIG_NO_PHYDM rtw_phydm_ability_backup(padapter); rtw_phydm_func_disable_all(padapter); +#endif /* create pseudo ad-hoc connection */ err = initpseudoadhoc(padapter); @@ -11899,7 +12011,7 @@ static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8 *pmsg) ploopback->cnt = cnt; ploopback->size = size; ploopback->lbkthread = kthread_run(lbk_thread, padapter, "RTW_LBK_THREAD"); - if (IS_ERR(padapter->lbkthread)) { + if (IS_ERR(ploopback->lbkthread)) { freeLoopback(padapter); ploopback->lbkthread = NULL; sprintf(pmsg, "loopback start FAIL! cnt=%d", cnt); @@ -11950,7 +12062,19 @@ static int rtw_test( } #ifdef CONFIG_MAC_LOOPBACK_DRIVER - if (strcmp(pch, "loopback") == 0) { + if (strcmp(pch, "init") == 0) { + u8 status; + + rtw_clr_drv_stopped(padapter); /* should clear drv_stopped, otherwise driver can't trx */ + + status = hal_init(padapter); + RTW_INFO("HAL_INIT %s\n", status ? "SUCCESS" : "FAIL"); + + rtw_write8(padapter, REG_LOOPBACK_ENABLE, LOOKBACK_ENABLE_VALUE); + RTW_INFO("Write 0x%03x to 0x%02x, enable loopback\n", + REG_LOOPBACK_ENABLE, LOOKBACK_ENABLE_VALUE); + + } else if (strcmp(pch, "loopback") == 0) { s32 cnt = 0; u32 size = 64; @@ -11989,6 +12113,15 @@ static int rtw_test( } else if (strcmp(pch, "btoff") == 0) { rtw_btcoex_SetManualControl(padapter, _TRUE); goto free_buf; + } else if (strcmp(pch, "coex_auto") == 0) { + rtw_btcoex_set_policy_control(padapter, BTCOEX_POLICY_CONTROL_AUTO); + goto free_buf; + } else if (strcmp(pch, "coex_force_freerun") == 0) { + rtw_btcoex_set_policy_control(padapter, BTCOEX_POLICY_CONTROL_FORCE_FREERUN); + goto free_buf; + } else if (strcmp(pch, "coex_force_tdma") == 0) { + rtw_btcoex_set_policy_control(padapter, BTCOEX_POLICY_CONTROL_FORCE_TDMA); + goto free_buf; } #endif @@ -12029,12 +12162,18 @@ static int rtw_test( goto free_buf; } + if (strcmp(pch, "dump_mac_reg") == 0) { + mac_reg_dump(RTW_DBGDUMP, padapter); + goto free_buf; + } + free_buf: rtw_mfree(pbuf, len); return 0; } static iw_handler rtw_handlers[] = { +#ifdef CONFIG_IOCTL_WEXT NULL, /* SIOCSIWCOMMIT */ rtw_wx_get_name, /* SIOCGIWNAME */ dummy, /* SIOCSIWNWID */ @@ -12091,6 +12230,7 @@ static iw_handler rtw_handlers[] = { NULL, /* SIOCGIWENCODEEXT */ rtw_wx_set_pmkid, /* SIOCSIWPMKSA */ NULL, /*---hole---*/ +#endif }; @@ -12194,7 +12334,13 @@ static const struct iw_priv_args rtw_private_args[] = { #else {SIOCIWFIRSTPRIV + 0x17, IW_PRIV_TYPE_CHAR | 1024 , 0 , "NULL"}, #endif - {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ , 0 , "rereg_nd_name"}, + +#ifdef CONFIG_PLATFORM_CMAP_INTFS + {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | 1024 , 0 , "cmap_intfs"}, +#else + {SIOCIWFIRSTPRIV + 0x18, 0, 0, "NULL"}, +#endif + #ifdef CONFIG_MP_INCLUDED {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "NULL"}, {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL"}, @@ -12222,7 +12368,11 @@ static const struct iw_priv_args rtw_private_args[] = { #ifdef CONFIG_WOWLAN { MP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_mode" }, { MP_WOW_SET_PATTERN , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_set_pattern" }, +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + { MP_WOW_SET_KEEP_ALIVE_PATTERN ,IW_PRIV_TYPE_CHAR | 1024 , 0 , "wow_keep_alive"}, +#endif /* defined (CONFIG_KEEP_ALIVE_PATTERN)*/ #endif + #ifdef CONFIG_AP_WOWLAN { MP_AP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "ap_wow_mode" }, /* set */ #endif @@ -12271,6 +12421,7 @@ static const struct iw_priv_args rtw_mp_private_args[] = { { EFUSE_BT_MASK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_bt_mask" }, { EFUSE_MASK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_mask" }, { EFUSE_FILE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_file" }, + { EFUSE_FILE_STORE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_store" }, { MP_TX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_tx" }, { MP_RX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rx" }, { MP_HW_TX_MODE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_hxtx" }, @@ -12284,6 +12435,8 @@ static const struct iw_priv_args rtw_mp_private_args[] = { { MP_LINK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_link" }, { MP_DPK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dpk"}, { MP_DPK_TRK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dpk_trk" }, + { MP_GET_TSSIDE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_get_tsside" }, + { MP_SET_TSSIDE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_set_tsside" }, #ifdef CONFIG_RTW_CUSTOMER_STR { MP_CUSTOMER_STR, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "customer_str" }, #endif @@ -12336,7 +12489,11 @@ static iw_handler rtw_private_handler[] = { #else rtw_wx_priv_null, /* 0x17 */ #endif - rtw_rereg_nd_name, /* 0x18 */ +#ifdef CONFIG_PLATFORM_CMAP_INTFS + cmap_intfs_ioctl, /* 0x18 */ +#else + NULL, /* 0x18 */ +#endif rtw_wx_priv_null, /* 0x19 */ #ifdef CONFIG_MP_INCLUDED rtw_wx_priv_null, /* 0x1A */ @@ -12349,6 +12506,7 @@ static iw_handler rtw_private_handler[] = { rtw_test, /* 0x1D */ }; +#ifdef CONFIG_WIRELESS_EXT #if WIRELESS_EXT >= 17 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev) { @@ -12358,7 +12516,7 @@ static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev) int tmp_qual = 0; int tmp_noise = 0; - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != _TRUE) { + if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) != _TRUE) { piwstats->qual.qual = 0; piwstats->qual.level = 0; piwstats->qual.noise = 0; @@ -12405,7 +12563,6 @@ static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev) } #endif -#ifdef CONFIG_WIRELESS_EXT struct iw_handler_def rtw_handlers_def = { .standard = rtw_handlers, .num_standard = sizeof(rtw_handlers) / sizeof(iw_handler), @@ -12861,6 +13018,7 @@ int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) int ret = 0; switch (cmd) { +#ifdef CONFIG_IOCTL_WEXT case RTL_IOCTL_WPA_SUPPLICANT: ret = wpa_supplicant_ioctl(dev, &wrq->u.data); break; @@ -12874,6 +13032,7 @@ int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; #endif #endif /* CONFIG_AP_MODE */ +#endif /* CONFIG_IOCTL_WEXT */ case SIOCDEVPRIVATE: ret = rtw_ioctl_wext_private(dev, rq); break; diff --git a/os_dep/linux/ioctl_mp.c b/os_dep/linux/ioctl_mp.c index 4a36be1..0c49117 100644 --- a/os_dep/linux/ioctl_mp.c +++ b/os_dep/linux/ioctl_mp.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2019 Realtek Corporation. + * Copyright(c) 2007 - 2017 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -17,6 +17,7 @@ #include #include #include "../../hal/phydm/phydm_precomp.h" +#include #if defined(CONFIG_RTL8723B) @@ -52,7 +53,7 @@ int rtw_mp_write_reg(struct net_device *dev, char *width_str; char width; u32 addr, data; - int ret = 0; + int ret; PADAPTER padapter = rtw_netdev_priv(dev); char input[RTW_IWD_MAX_LEN]; @@ -61,10 +62,8 @@ int rtw_mp_write_reg(struct net_device *dev, _rtw_memset(input, 0, sizeof(input)); - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; input[wrqu->length] = '\0'; @@ -73,39 +72,30 @@ int rtw_mp_write_reg(struct net_device *dev, pch = input; pnext = strpbrk(pch, " ,.-"); - if (pnext == NULL) { - ret = -EINVAL; - goto exit; - } + if (pnext == NULL) + return -EINVAL; *pnext = 0; width_str = pch; pch = pnext + 1; pnext = strpbrk(pch, " ,.-"); - if (pnext == NULL) { - ret = -EINVAL; - goto exit; - } + if (pnext == NULL) + return -EINVAL; *pnext = 0; /*addr = simple_strtoul(pch, &ptmp, 16); _rtw_memset(buf, '\0', sizeof(buf)); _rtw_memcpy(buf, pch, pnext-pch); - kstrtoul(buf, 16, &addr);*/ - sscanf(pch, "%x", &addr); - if (addr > 0x3FFF) { - ret = -EINVAL; - goto exit; - } + ret = kstrtoul(buf, 16, &addr);*/ + ret = sscanf(pch, "%x", &addr); pch = pnext + 1; pnext = strpbrk(pch, " ,.-"); - if ((pch - input) >= wrqu->length) { - ret = -EINVAL; - goto exit; - } + if ((pch - input) >= wrqu->length) + return -EINVAL; /*data = simple_strtoul(pch, &ptmp, 16);*/ - sscanf(pch, "%x", &data); + ret = sscanf(pch, "%x", &data); RTW_INFO("data=%x,addr=%x\n", (u32)data, (u32)addr); + ret = 0; width = width_str[0]; switch (width) { case 'b': @@ -133,9 +123,6 @@ int rtw_mp_write_reg(struct net_device *dev, break; } -exit: - rtw_mfree(input, wrqu->length + 1); - return ret; } @@ -161,23 +148,19 @@ int rtw_mp_read_reg(struct net_device *dev, char width; char data[20], tmp[20]; u32 addr = 0, strtout = 0; - u32 i = 0, j = 0, data32 = 0; + u32 i = 0, j = 0, ret = 0, data32 = 0; PADAPTER padapter = rtw_netdev_priv(dev); char *pextra = extra; - int ret = 0; - if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) + if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) return -EFAULT; if (wrqu->length > 128) return -EFAULT; - _rtw_memset(input, 0, wrqu->length); - - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + _rtw_memset(input, 0, sizeof(input)); + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; input[wrqu->length] = '\0'; _rtw_memset(extra, 0, wrqu->length); @@ -185,21 +168,18 @@ int rtw_mp_read_reg(struct net_device *dev, _rtw_memset(tmp, '\0', sizeof(tmp)); pch = input; pnext = strpbrk(pch, " ,.-"); - if (pnext == NULL) { - ret = -EINVAL; - goto exit; - } + if (pnext == NULL) + return -EINVAL; *pnext = 0; width_str = pch; pch = pnext + 1; - sscanf(pch, "%x", &addr); - if (addr > MP_READ_REG_MAX_OFFSET) { - ret = -EINVAL; - goto exit; - } + ret = sscanf(pch, "%x", &addr); + if (addr > MP_READ_REG_MAX_OFFSET) + return -EINVAL; + ret = 0; width = width_str[0]; switch (width) { @@ -234,7 +214,7 @@ int rtw_mp_read_reg(struct net_device *dev, pnext++; if (*pnext != '\0') { /*strtout = simple_strtoul(pnext , &ptmp, 16);*/ - sscanf(pnext, "%x", &strtout); + ret = sscanf(pnext, "%x", &strtout); pextra += sprintf(pextra, " %d", strtout); } else break; @@ -266,7 +246,7 @@ int rtw_mp_read_reg(struct net_device *dev, pnext++; if (*pnext != '\0') { - sscanf(pnext, "%x", &strtout); + ret = sscanf(pnext, "%x", &strtout); pextra += sprintf(pextra, " %d", strtout); } else break; @@ -281,9 +261,6 @@ int rtw_mp_read_reg(struct net_device *dev, break; } -exit: - rtw_mfree(input, wrqu->length + 1); - return ret; } @@ -298,33 +275,30 @@ int rtw_mp_write_rf(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrqu, char *extra) { - u32 path, addr, data; - int ret = 0, cnt; + int ret; PADAPTER padapter = rtw_netdev_priv(dev); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); char input[RTW_IWD_MAX_LEN]; if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) return -EFAULT; _rtw_memset(input, 0, wrqu->length); + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } - cnt = sscanf(input, "%d,%x,%x", &path, &addr, &data); - if (cnt < 3) { - ret = -EINVAL; - goto exit; - } + ret = sscanf(input, "%d,%x,%x", &path, &addr, &data); + if (ret < 3) + return -EINVAL; - if ((path >= GET_HAL_RFPATH_NUM(padapter)) - || (addr > 0xFF) || (data > 0xFFFFF)) { - ret = -EINVAL; - goto exit; - } + if (path >= hal_spec->rf_reg_path_num) + return -EINVAL; + if (addr > 0xFF) + return -EINVAL; + if (data > 0xFFFFF) + return -EINVAL; _rtw_memset(extra, 0, wrqu->length); @@ -333,10 +307,7 @@ int rtw_mp_write_rf(struct net_device *dev, sprintf(extra, "write_rf completed\n"); wrqu->length = strlen(extra); -exit: - rtw_mfree(input, wrqu->length); - - return ret; + return 0; } @@ -356,35 +327,29 @@ int rtw_mp_read_rf(struct net_device *dev, char *pch, *pnext; char data[20], tmp[20]; u32 path, addr, strtou; - u32 i = 0 , j = 0; + u32 ret, i = 0 , j = 0; PADAPTER padapter = rtw_netdev_priv(dev); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); char *pextra = extra; - int ret = 0, cnt; if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) return -EFAULT; if (wrqu->length > 128) return -EFAULT; - _rtw_memset(input, 0, wrqu->length); + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + ret = sscanf(input, "%d,%x", &path, &addr); + if (ret < 2) + return -EINVAL; - cnt = sscanf(input, "%d,%x", &path, &addr); - if (cnt < 2) { - ret = -EINVAL; - goto exit; - } + if (path >= hal_spec->rf_reg_path_num) + return -EINVAL; - if ((path >= GET_HAL_RFPATH_NUM(padapter)) - || (addr > MP_READ_REG_MAX_OFFSET)) { - ret = -EINVAL; - goto exit; - } + if (addr > MP_READ_REG_MAX_OFFSET) + return -EINVAL; _rtw_memset(extra, 0, wrqu->length); @@ -408,7 +373,7 @@ int rtw_mp_read_rf(struct net_device *dev, pnext++; if (*pnext != '\0') { /*strtou =simple_strtoul(pnext , &ptmp, 16);*/ - sscanf(pnext, "%x", &strtou); + ret = sscanf(pnext, "%x", &strtou); pextra += sprintf(pextra, " %d", strtou); } else break; @@ -416,10 +381,7 @@ int rtw_mp_read_rf(struct net_device *dev, } wrqu->length = strlen(extra); -exit: - rtw_mfree(input, wrqu->length); - - return ret; + return 0; } @@ -436,7 +398,7 @@ int rtw_mp_start(struct net_device *dev, pmppriv->bprocess_mp_mode = _TRUE; - if (rtw_mi_check_fwstate(padapter, _FW_UNDER_SURVEY)) { + if (rtw_mi_check_fwstate(padapter, WIFI_UNDER_SURVEY)) { rtw_mi_buddy_set_scan_deny(padapter, 5000); rtw_mi_scan_abort(padapter, _TRUE); } @@ -463,12 +425,12 @@ int rtw_mp_stop(struct net_device *dev, PADAPTER padapter = rtw_netdev_priv(dev); struct mp_priv *pmppriv = &padapter->mppriv; - if (rtw_mp_cmd(padapter, MP_STOP, RTW_CMDF_WAIT_ACK) != _SUCCESS) - ret = -EPERM; - if (pmppriv->mode != MP_ON) return -EPERM; + if (rtw_mp_cmd(padapter, MP_STOP, RTW_CMDF_WAIT_ACK) != _SUCCESS) + ret = -EPERM; + pmppriv->bprocess_mp_mode = _FALSE; _rtw_memset(extra, 0, wrqu->length); sprintf(extra, "mp_stop %s\n", ret == 0 ? "ok" : "fail"); @@ -483,28 +445,28 @@ int rtw_mp_rate(struct net_device *dev, struct iw_point *wrqu, char *extra) { u32 rate = MPT_RATE_1M; + u8 err = 0; u8 input[RTW_IWD_MAX_LEN]; PADAPTER padapter = rtw_netdev_priv(dev); PMPT_CONTEXT pMptCtx = &(padapter->mppriv.mpt_ctx); - int ret = 0; + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); + struct mp_priv *pmppriv = &padapter->mppriv; if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) return -EFAULT; _rtw_memset(input, 0, sizeof(input)); - - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; input[wrqu->length] = '\0'; rate = rtw_mpRateParseFunc(padapter, input); - padapter->mppriv.rateidx = rate; + pmppriv->rateidx = rate; if (rate == 0 && strcmp(input, "1M") != 0) { rate = rtw_atoi(input); - padapter->mppriv.rateidx = MRateToHwRate(rate); + if (rate <= MGN_VHT4SS_MCS9) + pmppriv->rateidx = MRateToHwRate(rate); /*if (rate <= 0x7f) rate = wifirate2_ratetbl_inx((u8)rate); else if (rate < 0xC8) @@ -517,28 +479,38 @@ int rtw_mp_rate(struct net_device *dev, rate =(rate - MPT_RATE_VHT1SS_MCS0); */ } + _rtw_memset(extra, 0, wrqu->length); - sprintf(extra, "Set data rate to %s index %d" , input, padapter->mppriv.rateidx); - RTW_INFO("%s: %s rate index=%d\n", __func__, input, padapter->mppriv.rateidx); - - if (padapter->mppriv.rateidx >= DESC_RATEVHTSS4MCS9) { - ret = -EINVAL; - goto exit; + if (pmppriv->rateidx > DESC_RATEVHTSS4MCS9) { + sprintf(extra, "Set %s Error" , input); + return -EINVAL; } - pMptCtx->mpt_rate_index = HwRateToMPTRate(padapter->mppriv.rateidx); - SetDataRate(padapter); + if (hal_spec->tx_nss_num < 2 && MPT_IS_2SS_RATE(HwRateToMPTRate(pmppriv->rateidx))) + err = 1; + if (hal_spec->tx_nss_num < 3 && MPT_IS_3SS_RATE(HwRateToMPTRate(pmppriv->rateidx))) + err = 1; + if (hal_spec->tx_nss_num < 4 && MPT_IS_4SS_RATE(HwRateToMPTRate(pmppriv->rateidx))) + err = 1; + if (!is_supported_vht(padapter->registrypriv.wireless_mode) && MPT_IS_VHT_RATE(HwRateToMPTRate(pmppriv->rateidx))) + err = 1; + if (!is_supported_ht(padapter->registrypriv.wireless_mode) && MPT_IS_HT_RATE(HwRateToMPTRate(pmppriv->rateidx))) + err = 1; + if (err == 1) { + sprintf(extra, "Set data rate to %s Error" , input); + pmppriv->rateidx = 0; + } else { + sprintf(extra, "Set data rate to %s index %d" , input, pmppriv->rateidx); + RTW_INFO("%s: %s rate index=%d\n", __func__, input, pmppriv->rateidx); + pMptCtx->mpt_rate_index = HwRateToMPTRate(pmppriv->rateidx); + SetDataRate(padapter); + } wrqu->length = strlen(extra); - -exit: - rtw_mfree(input, wrqu->length + 1); - - return ret; + return err; } - int rtw_mp_channel(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrqu, char *extra) @@ -547,18 +519,15 @@ int rtw_mp_channel(struct net_device *dev, PADAPTER padapter = rtw_netdev_priv(dev); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); u8 input[RTW_IWD_MAX_LEN]; - u32 channel = 1; - int ret = 0; + u8 channel = 1; + struct mp_priv *pmppriv = &padapter->mppriv; if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) return -EFAULT; _rtw_memset(input, 0, sizeof(input)); - - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; input[wrqu->length] = '\0'; channel = rtw_atoi(input); @@ -567,15 +536,12 @@ int rtw_mp_channel(struct net_device *dev, sprintf(extra, "Change channel %d to channel %d", padapter->mppriv.channel , channel); padapter->mppriv.channel = channel; rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0); + rtw_adjust_chbw(padapter, channel, &pmppriv->bandwidth, &pmppriv->prime_channel_offset); SetChannel(padapter); pHalData->current_channel = channel; wrqu->length = strlen(extra); - -exit: - rtw_mfree(input, wrqu->length + 1); - - return ret; + return 0; } @@ -587,32 +553,26 @@ int rtw_mp_ch_offset(struct net_device *dev, PADAPTER padapter = rtw_netdev_priv(dev); u8 input[RTW_IWD_MAX_LEN]; u32 ch_offset = 0; - int ret = 0; + char *pch; if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) return -EFAULT; _rtw_memset(input, 0, sizeof(input)); - - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; input[wrqu->length] = '\0'; ch_offset = rtw_atoi(input); /*RTW_INFO("%s: channel=%d\n", __func__, channel);*/ _rtw_memset(extra, 0, wrqu->length); - sprintf(extra, "Change prime channel offset %d to %d", padapter->mppriv.prime_channel_offset , ch_offset); + pch = extra; + pch += sprintf(pch, "Change prime channel offset %d to %d", padapter->mppriv.prime_channel_offset , ch_offset); padapter->mppriv.prime_channel_offset = ch_offset; SetChannel(padapter); wrqu->length = strlen(extra); - -exit: - rtw_mfree(input, wrqu->length + 1); - - return ret; + return 0; } @@ -620,31 +580,22 @@ int rtw_mp_bandwidth(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrqu, char *extra) { - u32 bandwidth = 0, sg = 0; + u8 bandwidth = 0, sg = 0; PADAPTER padapter = rtw_netdev_priv(dev); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct mp_priv *pmppriv = &padapter->mppriv; u8 input[RTW_IWD_MAX_LEN]; - int ret = 0; if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) return -EFAULT; - _rtw_memset(input, 0, sizeof(input)); + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (sscanf(input, "40M=%hhd,shortGI=%hhd", &bandwidth, &sg) > 0) + RTW_INFO("%s: bw=%hhd sg=%hhd\n", __func__, bandwidth , sg); - if (sscanf(input, "40M=%d,shortGI=%d", &bandwidth, &sg) > 0) - RTW_INFO("%s: bw=%d sg=%d\n", __func__, bandwidth , sg); - - if (bandwidth == 1 && hal_chk_bw_cap(padapter, BW_CAP_40M)) - bandwidth = CHANNEL_WIDTH_40; - else if (bandwidth == 2 && hal_chk_bw_cap(padapter, BW_CAP_80M)) - bandwidth = CHANNEL_WIDTH_80; - else - bandwidth = CHANNEL_WIDTH_20; + rtw_adjust_chbw(padapter, pmppriv->channel, &bandwidth, &pmppriv->prime_channel_offset); padapter->mppriv.bandwidth = (u8)bandwidth; padapter->mppriv.preamble = sg; @@ -656,10 +607,7 @@ int rtw_mp_bandwidth(struct net_device *dev, wrqu->length = strlen(extra); -exit: - rtw_mfree(input, wrqu->length); - - return ret; + return 0; } @@ -673,7 +621,6 @@ int rtw_mp_txpower_index(struct net_device *dev, u32 rfpath = 0 ; u32 txpower_inx = 0, tarpowerdbm = 0; char *pextra = extra; - int ret = 0; if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) return -EFAULT; @@ -683,10 +630,8 @@ int rtw_mp_txpower_index(struct net_device *dev, _rtw_memset(input, 0, sizeof(input)); - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; input[wrqu->length] = '\0'; _rtw_memset(extra, 0, strlen(extra)); @@ -697,13 +642,16 @@ int rtw_mp_txpower_index(struct net_device *dev, txpower_inx = mpt_ProQueryCalTxPower(padapter, rfpath); } pextra += sprintf(pextra, " %d\n", txpower_inx); - if (IS_HARDWARE_TYPE_JAGUAR3(padapter)) { - tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, rfpath); - if (tarpowerdbm > 0) - pextra += sprintf(pextra, " dBm:%d", tarpowerdbm); - } + tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, rfpath); + if (tarpowerdbm > 0) + pextra += sprintf(pextra, "\t\t dBm:%d", tarpowerdbm); } else { - txpower_inx = mpt_ProQueryCalTxPower(padapter, 0); + if (phal_data->ant_path == 1) + rfpath = 1; + else + rfpath = 0; + + txpower_inx = mpt_ProQueryCalTxPower(padapter, rfpath); pextra += sprintf(pextra, "patha=%d", txpower_inx); if (phal_data->rf_type > RF_1T2R) { txpower_inx = mpt_ProQueryCalTxPower(padapter, 1); @@ -715,32 +663,27 @@ int rtw_mp_txpower_index(struct net_device *dev, } if (phal_data->rf_type > RF_3T4R) { txpower_inx = mpt_ProQueryCalTxPower(padapter, 3); - pextra += sprintf(pextra, ",pathd=%d\n", txpower_inx); + pextra += sprintf(pextra, ",pathd=%d", txpower_inx); } - if (IS_HARDWARE_TYPE_JAGUAR3(padapter)) { - tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, 0); - pextra += sprintf(pextra, "patha dBm=%d", tarpowerdbm); - if (phal_data->rf_type > RF_1T2R) { - tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, 1); - pextra += sprintf(pextra, "pathb dBm=%d", tarpowerdbm); - } - if (phal_data->rf_type > RF_2T4R) { - tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, 2); - pextra += sprintf(pextra, "pathc dBm=%d", tarpowerdbm); - } - if (phal_data->rf_type > RF_3T4R) { - tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, 3); - pextra += sprintf(pextra, "pathd dBm=%d", tarpowerdbm); - } + tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, rfpath); + pextra += sprintf(pextra, "\n\t\t\tpatha dBm=%d", tarpowerdbm); + if (phal_data->rf_type > RF_1T2R) { + tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, 1); + pextra += sprintf(pextra, ",pathb dBm=%d", tarpowerdbm); + } + if (phal_data->rf_type > RF_2T4R) { + tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, 2); + pextra += sprintf(pextra, ",pathc dBm=%d", tarpowerdbm); + } + if (phal_data->rf_type > RF_3T4R) { + tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, 3); + pextra += sprintf(pextra, ",pathd dBm=%d", tarpowerdbm); } } wrqu->length = strlen(extra); -exit: - rtw_mfree(input, wrqu->length + 1); - - return ret; + return 0; } @@ -751,27 +694,35 @@ int rtw_mp_txpower(struct net_device *dev, u32 idx_a = 0, idx_b = 0, idx_c = 0, idx_d = 0; int MsetPower = 1; u8 input[RTW_IWD_MAX_LEN]; - int ret = 0; + u8 res = 0; + PADAPTER padapter = rtw_netdev_priv(dev); PMPT_CONTEXT pMptCtx = &(padapter->mppriv.mpt_ctx); if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) return -EFAULT; - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; MsetPower = strncmp(input, "off", 3); if (MsetPower == 0) { padapter->mppriv.bSetTxPower = 0; sprintf(extra, "MP Set power off"); } else { - if (sscanf(input, "patha=%d,pathb=%d,pathc=%d,pathd=%d", &idx_a, &idx_b, &idx_c, &idx_d) < 3) - RTW_INFO("Invalid format on line %s ,patha=%d,pathb=%d,pathc=%d,pathd=%d\n", input , idx_a , idx_b , idx_c , idx_d); + res = sscanf(input, "patha=%d,pathb=%d,pathc=%d,pathd=%d", &idx_a, &idx_b, &idx_c, &idx_d); + if (res < 1) { + if(isdigit(input[0])){ + idx_a = rtw_atoi(input); + RTW_INFO("direct set RF Path A Power =%d\n", idx_a); + } else + RTW_INFO("Invalid format on %s !, Get patha=%d,pathb=%d,pathc=%d,pathd=%d\n", input , idx_a , idx_b , idx_c , idx_d); + } + if (res > 0 || idx_a !=0) + sprintf(extra, "Set power level path_A:%d path_B:%d path_C:%d path_D:%d", idx_a , idx_b , idx_c , idx_d); + else + sprintf(extra, "Invalid format on string :%s ", input); - sprintf(extra, "Set power level path_A:%d path_B:%d path_C:%d path_D:%d", idx_a , idx_b , idx_c , idx_d); padapter->mppriv.txpoweridx = (u8)idx_a; pMptCtx->TxPwrLevel[RF_PATH_A] = (u8)idx_a; @@ -784,10 +735,6 @@ int rtw_mp_txpower(struct net_device *dev, } wrqu->length = strlen(extra); - -exit: - rtw_mfree(input, wrqu->length); - return 0; } @@ -801,17 +748,13 @@ int rtw_mp_ant_tx(struct net_device *dev, u16 antenna = 0; PADAPTER padapter = rtw_netdev_priv(dev); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); - int ret = 0; if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) return -EFAULT; _rtw_memset(input, 0, sizeof(input)); - - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; input[wrqu->length] = '\0'; sprintf(extra, "switch Tx antenna to %s", input); @@ -848,11 +791,7 @@ int rtw_mp_ant_tx(struct net_device *dev, SetAntenna(padapter); wrqu->length = strlen(extra); - -exit: - rtw_mfree(input, wrqu->length + 1); - - return ret; + return 0; } @@ -865,17 +804,13 @@ int rtw_mp_ant_rx(struct net_device *dev, u8 input[RTW_IWD_MAX_LEN]; PADAPTER padapter = rtw_netdev_priv(dev); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); - int ret = 0; if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) return -EFAULT; _rtw_memset(input, 0, sizeof(input)); - - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; input[wrqu->length] = '\0'; /*RTW_INFO("%s: input=%s\n", __func__, input);*/ @@ -908,10 +843,7 @@ int rtw_mp_ant_rx(struct net_device *dev, SetAntenna(padapter); wrqu->length = strlen(extra); -exit: - rtw_mfree(input, wrqu->length + 1); - - return ret; + return 0; } @@ -1104,17 +1036,14 @@ int rtw_mp_disable_bt_coexist(struct net_device *dev, #endif u8 input[RTW_IWD_MAX_LEN]; u32 bt_coexist; - int ret = 0; if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->data.length + 1))) return -EFAULT; _rtw_memset(input, 0, sizeof(input)); - if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; input[wrqu->data.length] = '\0'; @@ -1136,10 +1065,7 @@ int rtw_mp_disable_bt_coexist(struct net_device *dev, #endif } -exit: - rtw_mfree(input, wrqu->data.length + 1); - - return ret; + return 0; } @@ -1151,26 +1077,23 @@ int rtw_mp_arx(struct net_device *dev, int bmac_filter = 0, bmon = 0, bSmpCfg = 0; u8 input[RTW_IWD_MAX_LEN]; char *pch, *token, *tmp[2] = {0x00, 0x00}; - u32 i = 0, jj = 0, kk = 0, cnts = 0; + u32 i = 0, jj = 0, kk = 0, cnts = 0, ret; PADAPTER padapter = rtw_netdev_priv(dev); struct mp_priv *pmppriv = &padapter->mppriv; struct dbg_rx_counter rx_counter; - int ret = 0; if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) return -EFAULT; - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; RTW_INFO("%s: %s\n", __func__, input); #ifdef CONFIG_CONCURRENT_MODE if (!is_primary_adapter(padapter)) { sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n"); wrqu->length = strlen(extra); - goto exit; + return 0; } #endif bStartRx = (strncmp(input, "start", 5) == 0) ? 1 : 0; /* strncmp TRUE is 0*/ @@ -1203,10 +1126,8 @@ int rtw_mp_arx(struct net_device *dev, pmppriv->network_macaddr[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]); RTW_INFO("network_macaddr[%d]=%x\n", jj, pmppriv->network_macaddr[jj]); } - } else { - ret = -EFAULT; - goto exit; - } + } else + return -EFAULT; pmppriv->bSetRxBssid = _TRUE; } @@ -1228,20 +1149,17 @@ int rtw_mp_arx(struct net_device *dev, } if ((tmp[0] != NULL) && (tmp[1] != NULL)) { cnts = strlen(tmp[1]) / 2; - if (cnts < 1) { - ret = -EFAULT; - goto exit; - } + if (cnts < 1) + return -EFAULT; RTW_INFO("%s: cnts=%d\n", __func__, cnts); RTW_INFO("%s: data=%s\n", __func__, tmp[1]); for (jj = 0, kk = 0; jj < cnts ; jj++, kk += 2) { pmppriv->mac_filter[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]); RTW_INFO("%s mac_filter[%d]=%x\n", __func__, jj, pmppriv->mac_filter[jj]); } - } else { - ret = -EFAULT; - goto exit; - } + } else + return -EFAULT; + } if (bStartRx) { @@ -1270,7 +1188,7 @@ int rtw_mp_arx(struct net_device *dev, } if (bmon == 1) { - sscanf(input, "mon=%d", &bmon); + ret = sscanf(input, "mon=%d", &bmon); if (bmon == 1) { pmppriv->rx_bindicatePkt = _TRUE; @@ -1281,7 +1199,7 @@ int rtw_mp_arx(struct net_device *dev, } } if (bSmpCfg == 1) { - sscanf(input, "smpcfg=%d", &bSmpCfg); + ret = sscanf(input, "smpcfg=%d", &bSmpCfg); if (bSmpCfg == 1) { pmppriv->bRTWSmbCfg = _TRUE; @@ -1309,10 +1227,7 @@ int rtw_mp_arx(struct net_device *dev, wrqu->length = strlen(extra) + 1; -exit: - rtw_mfree(input, wrqu->length); - - return ret; + return 0; } @@ -1351,18 +1266,15 @@ int rtw_mp_pwrtrk(struct net_device *dev, { u8 enable; u32 thermal; - s32 res; + s32 ret; PADAPTER padapter = rtw_netdev_priv(dev); u8 input[RTW_IWD_MAX_LEN]; - int ret = 0; if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) return -EFAULT; - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; _rtw_memset(extra, 0, wrqu->length); @@ -1373,30 +1285,21 @@ int rtw_mp_pwrtrk(struct net_device *dev, enable = 0; sprintf(extra, "mp tx power tracking stop"); } else if (sscanf(input, "ther=%d", &thermal) == 1) { - res = SetThermalMeter(padapter, (u8)thermal); - if (res == _FAIL) { - ret = -EPERM; - goto exit; - } + ret = SetThermalMeter(padapter, (u8)thermal); + if (ret == _FAIL) + return -EPERM; sprintf(extra, "mp tx power tracking start,target value=%d ok", thermal); - } else { - ret = -EINVAL; - goto exit; - } + } else + return -EINVAL; } - res = SetPowerTracking(padapter, enable); - if (res == _FAIL) { - ret = -EPERM; - goto exit; - } + ret = SetPowerTracking(padapter, enable); + if (ret == _FAIL) + return -EPERM; wrqu->length = strlen(extra); -exit: - rtw_mfree(input, wrqu->length); - - return ret; + return 0; } @@ -1407,27 +1310,20 @@ int rtw_mp_psd(struct net_device *dev, { PADAPTER padapter = rtw_netdev_priv(dev); u8 input[RTW_IWD_MAX_LEN]; - int ret = 0; if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) return -EFAULT; _rtw_memset(input, 0, sizeof(input)); - - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; input[wrqu->length] = '\0'; strcpy(extra, input); wrqu->length = mp_query_psd(padapter, extra); -exit: - rtw_mfree(input, wrqu->length + 1); - - return ret; + return 0; } @@ -1440,6 +1336,7 @@ int rtw_mp_thermal(struct net_device *dev, u16 ther_path_addr[4] = {0}; u16 cnt = 1; PADAPTER padapter = rtw_netdev_priv(dev); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); int rfpath = RF_PATH_A; #ifdef CONFIG_RTL8188E @@ -1483,7 +1380,13 @@ int rtw_mp_thermal(struct net_device *dev, ther_path_addr[1] = EEPROM_THERMAL_METER_B_8822C; #endif #ifdef CONFIG_RTL8814B - ther_path_addr[0] = EEPROM_THERMAL_METER_8814B; + ther_path_addr[0] = EEPROM_THERMAL_METER_A_8814B; + ther_path_addr[1] = EEPROM_THERMAL_METER_B_8814B; + ther_path_addr[2] = EEPROM_THERMAL_METER_C_8814B; + ther_path_addr[3] = EEPROM_THERMAL_METER_D_8814B; +#endif +#ifdef CONFIG_RTL8723F + ther_path_addr[0] = EEPROM_THERMAL_METER_8723F; #endif if (copy_from_user(extra, wrqu->pointer, wrqu->length)) @@ -1504,7 +1407,7 @@ int rtw_mp_thermal(struct net_device *dev, return -EFAULT; } - for (i = 0; i < GET_HAL_RFPATH_NUM(padapter); i++) { + for (i = 0; i < hal_spec->rf_reg_path_num; i++) { GetThermalMeter(padapter, i , &val[i]); if (ther_path_addr[i] != 0 && val[i] != 0) { if (rtw_efuse_map_write(padapter, ther_path_addr[i], cnt, &val[i]) == _FAIL) { @@ -1524,7 +1427,7 @@ int rtw_mp_thermal(struct net_device *dev, rfpath = RF_PATH_A; RTW_INFO("default thermal of path(%d)\n", rfpath); } - if (rfpath >= GET_HAL_RFPATH_NUM(padapter)) + if (rfpath >= hal_spec->rf_reg_path_num) return -EINVAL; RTW_INFO("read thermal of path(%d)\n", rfpath); @@ -1573,28 +1476,21 @@ int rtw_mp_dump(struct net_device *dev, struct mp_priv *pmp_priv; u8 input[RTW_IWD_MAX_LEN]; PADAPTER padapter = rtw_netdev_priv(dev); - int ret = 0; + + pmp_priv = &padapter->mppriv; if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) return -EFAULT; - pmp_priv = &padapter->mppriv; - - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; if (strncmp(input, "all", 4) == 0) { mac_reg_dump(RTW_DBGDUMP, padapter); bb_reg_dump(RTW_DBGDUMP, padapter); rf_reg_dump(RTW_DBGDUMP, padapter); } - -exit: - rtw_mfree(input, wrqu->length); - - return ret; + return 0; } @@ -1606,27 +1502,24 @@ int rtw_mp_phypara(struct net_device *dev, PADAPTER padapter = rtw_netdev_priv(dev); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); char input[RTW_IWD_MAX_LEN]; - u32 invalxcap = 0, cnt = 0, bwrite_xcap = 0, hwxtaladdr = 0; + u32 invalxcap = 0, ret = 0, bwrite_xcap = 0, hwxtaladdr = 0; u16 pgval; - int ret = 0; if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) return -EFAULT; - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; RTW_INFO("%s:priv in=%s\n", __func__, input); bwrite_xcap = (strncmp(input, "write_xcap=", 11) == 0) ? 1 : 0; if (bwrite_xcap == 1) { - cnt = sscanf(input, "write_xcap=%d", &invalxcap); + ret = sscanf(input, "write_xcap=%d", &invalxcap); invalxcap = invalxcap & 0x7f; /* xtal bit 0 ~6 */ RTW_INFO("get crystal_cap %d\n", invalxcap); - if (IS_HARDWARE_TYPE_8822C(padapter) && cnt == 1) { + if (IS_HARDWARE_TYPE_8822C(padapter) && ret == 1) { hwxtaladdr = 0x110; pgval = invalxcap | 0x80; /* reserved default bit7 on */ pgval = pgval | pgval << 8; /* xtal xi/xo efuse 0x110 0x111 */ @@ -1641,9 +1534,9 @@ int rtw_mp_phypara(struct net_device *dev, } } else { - cnt = sscanf(input, "xcap=%d", &invalxcap); + ret = sscanf(input, "xcap=%d", &invalxcap); - if (cnt == 1) { + if (ret == 1) { pHalData->crystal_cap = (u8)invalxcap; RTW_INFO("%s:crystal_cap=%d\n", __func__, pHalData->crystal_cap); @@ -1656,10 +1549,6 @@ int rtw_mp_phypara(struct net_device *dev, } wrqu->length = strlen(extra) + 1; - -exit: - rtw_mfree(input, wrqu->length); - return ret; } @@ -1671,30 +1560,28 @@ int rtw_mp_SetRFPath(struct net_device *dev, PADAPTER padapter = rtw_netdev_priv(dev); char input[RTW_IWD_MAX_LEN]; int bMain = 1, bTurnoff = 1; - int ret = 0; #ifdef CONFIG_ANTENNA_DIVERSITY - u8 res = _TRUE; + u8 ret = _TRUE; #endif if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) return -EFAULT; - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } RTW_INFO("%s:iwpriv in=%s\n", __func__, input); + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + bMain = strncmp(input, "1", 2); /* strncmp TRUE is 0*/ bTurnoff = strncmp(input, "0", 3); /* strncmp TRUE is 0*/ _rtw_memset(extra, 0, wrqu->length); #ifdef CONFIG_ANTENNA_DIVERSITY if (bMain == 0) - res = rtw_mp_set_antdiv(padapter, _TRUE); + ret = rtw_mp_set_antdiv(padapter, _TRUE); else - res = rtw_mp_set_antdiv(padapter, _FALSE); - if (res == _FALSE) + ret = rtw_mp_set_antdiv(padapter, _FALSE); + if (ret == _FALSE) RTW_INFO("%s:ANTENNA_DIVERSITY FAIL\n", __func__); #endif @@ -1709,16 +1596,13 @@ int rtw_mp_SetRFPath(struct net_device *dev, sprintf(extra, "mp_setrfpath Aux\n"); } else { bMain = MP_PHY_QueryRFPathSwitch(padapter); - RTW_INFO("%s:PHY_SetRFPathSwitch = %s\n", __func__, (bMain ? "Main":"Aux")); - sprintf(extra, "mp_setrfpath %s\n" , (bMain ? "Main":"Aux")); + RTW_INFO("%s:Query RF Path = %s\n", __func__, (bMain ? "Main":"Aux")); + sprintf(extra, "RF Path %s\n" , (bMain ? "1":"0")); } wrqu->length = strlen(extra); -exit: - rtw_mfree(input, wrqu->length); - - return ret; + return 0; } @@ -1729,55 +1613,50 @@ int rtw_mp_switch_rf_path(struct net_device *dev, PADAPTER padapter = rtw_netdev_priv(dev); struct mp_priv *pmp_priv; char input[RTW_IWD_MAX_LEN]; + char *pch; int bwlg = 1, bwla = 1, btg = 1, bbt=1; - int ret = 0; + u8 ret = 0; if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) return -EFAULT; - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; pmp_priv = &padapter->mppriv; RTW_INFO("%s: in=%s\n", __func__, input); - bwlg = strncmp(input, "WLG", 3); /* strncmp TRUE is 0*/ - bwla = strncmp(input, "WLA", 3); /* strncmp TRUE is 0*/ - btg = strncmp(input, "BTG", 3); /* strncmp TRUE is 0*/ - bbt = strncmp(input, "BT", 3); /* strncmp TRUE is 0*/ - - _rtw_memset(extra, 0, wrqu->length); + _rtw_memset(extra, '\0', wrqu->length); + pch = extra; #ifdef CONFIG_RTL8821C /* only support for 8821c wlg/wla/btg/bt RF switch path */ - if (bwlg == 0) { + if ((strncmp(input, "WLG", 3) == 0) || (strncmp(input, "1", 1) == 0)) { pmp_priv->rf_path_cfg = SWITCH_TO_WLG; - sprintf(extra, "switch rf path WLG\n"); - } else if (bwla == 0) { + pch += sprintf(pch, "switch rf path WLG\n"); + + } else if ((strncmp(input, "WLA", 3) == 0) || (strncmp(input, "2", 1) == 0)) { pmp_priv->rf_path_cfg = SWITCH_TO_WLA; - sprintf(extra, "switch rf path WLA\n"); - } else if (btg == 0) { + pch += sprintf(pch, "switch rf path WLA\n"); + + } else if ((strncmp(input, "BTG", 3) == 0) || (strncmp(input, "0", 1) == 0)) { pmp_priv->rf_path_cfg = SWITCH_TO_BTG; - sprintf(extra, "switch rf path BTG\n"); - } else if (bbt == 0) { + pch += sprintf(pch, "switch rf path BTG\n"); + + } else if ((strncmp(input, "BT", 3) == 0) || (strncmp(input, "3", 1) == 0)) { pmp_priv->rf_path_cfg = SWITCH_TO_BT; - sprintf(extra, "switch rf path BG\n"); + pch += sprintf(pch, "switch rf path BT\n"); } else { - sprintf(extra, "Error set %s\n", __func__); - ret = -EFAULT; - goto exit; + pmp_priv->rf_path_cfg = SWITCH_TO_WLG; + pch += sprintf(pch, "Error input, default set WLG\n"); + return -EFAULT; } mp_phy_switch_rf_path_set(padapter, &pmp_priv->rf_path_cfg); #endif - wrqu->length = strlen(extra); -exit: - rtw_mfree(input, wrqu->length + 1); - return ret; + } int rtw_mp_QueryDrv(struct net_device *dev, struct iw_request_info *info, @@ -1786,17 +1665,14 @@ int rtw_mp_QueryDrv(struct net_device *dev, PADAPTER padapter = rtw_netdev_priv(dev); char input[RTW_IWD_MAX_LEN]; int qAutoLoad = 1; - int ret = 0; PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->data.length)) return -EFAULT; - if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; RTW_INFO("%s:iwpriv in=%s\n", __func__, input); qAutoLoad = strncmp(input, "autoload", 8); /* strncmp TRUE is 0*/ @@ -1810,11 +1686,7 @@ int rtw_mp_QueryDrv(struct net_device *dev, sprintf(extra, "ok"); } wrqu->data.length = strlen(extra) + 1; - -exit: - rtw_mfree(input, wrqu->data.length); - - return ret; + return 0; } @@ -1827,17 +1699,14 @@ int rtw_mp_PwrCtlDM(struct net_device *dev, u8 pwrtrk_state = 0; u8 pwtk_type[5][25] = {"Thermal tracking off","Thermal tracking on", "TSSI tracking off","TSSI tracking on","TSSI calibration"}; - int ret = 0; if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) return -EFAULT; - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; - input[wrqu->length] = '\0'; + input[wrqu->length - 1] = '\0'; RTW_INFO("%s: in=%s\n", __func__, input); if (wrqu->length == 2) { @@ -1852,7 +1721,7 @@ int rtw_mp_PwrCtlDM(struct net_device *dev, } wrqu->length = strlen(extra); - goto exit; + return 0; } if (strncmp(input, "start", 5) == 0 || strncmp(input, "thertrk on", 10) == 0) {/* strncmp TRUE is 0*/ pwrtrk_state = 1; @@ -1870,21 +1739,19 @@ int rtw_mp_PwrCtlDM(struct net_device *dev, pwrtrk_state = 4; sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]); } else { - pwrtrk_state = 0; - sprintf(extra, "Error input, default PwrCtlDM stop\n" + sprintf(extra, "Error input !!!\n" " thertrk off : Thermal tracking off\n thertrk on : Thermal tracking on\n" " tssitrk off : TSSI tracking off\n tssitrk on : TSSI tracking on\n tssik : TSSI calibration\n\n" " 0 : Thermal tracking off\n 1 : Thermal tracking on\n 2 : TSSI tracking off\n" " 3 : TSSI tracking on\n 4 : TSSI calibration\n"); + wrqu->length = strlen(extra); + return 0; } MPT_PwrCtlDM(padapter, pwrtrk_state); wrqu->length = strlen(extra); -exit: - rtw_mfree(input, wrqu->length); - - return ret; + return 0; } int rtw_mp_iqk(struct net_device *dev, @@ -1917,6 +1784,7 @@ int rtw_mp_dpk(struct net_device *dev, HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct dm_struct *pDM_Odm = &pHalData->odmpriv; struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); + char *pch; u8 ips_mode = IPS_NUM; /* init invalid value */ u8 lps_mode = PS_MODE_NUM; /* init invalid value */ @@ -1925,16 +1793,17 @@ int rtw_mp_dpk(struct net_device *dev, return -EFAULT; *(extra + wrqu->data.length) = '\0'; + pch = extra; if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) { pDM_Odm->dpk_info.is_dpk_enable = 0; halrf_dpk_enable_disable(pDM_Odm); - sprintf(extra, "set dpk off\n"); + pch += sprintf(pch, "set dpk off\n"); } else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) { pDM_Odm->dpk_info.is_dpk_enable = 1; halrf_dpk_enable_disable(pDM_Odm); - sprintf(extra, "set dpk on\n"); + pch += sprintf(pch, "set dpk on\n"); } else { #ifdef CONFIG_LPS lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */ @@ -1954,7 +1823,7 @@ int rtw_mp_dpk(struct net_device *dev, rtw_pm_set_lps(padapter, lps_mode); #endif /* CONFIG_LPS */ } - sprintf(extra, "set dpk trigger\n"); + pch += sprintf(pch, "set dpk trigger\n"); } wrqu->data.length = strlen(extra); @@ -1962,6 +1831,148 @@ int rtw_mp_dpk(struct net_device *dev, return 0; } +int rtw_mp_get_tsside(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + PADAPTER padapter = rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct dm_struct *pDM_Odm = &pHalData->odmpriv; + char input[RTW_IWD_MAX_LEN]; + u8 rfpath; + u32 tssi_de; + + u8 legal_param_num = 1; + int param_num; + char pout_str_buf[7]; + u8 signed_flag = 0; + int integer_num; + u32 decimal_num; + s32 pout; + char *pextra; + int i; + + #ifdef CONFIG_RTL8723F + /* + * rtwpriv wlan0 mp_get_tsside rf_path pout + * rf_path : 0 ~ 1 + * pout : -15.000 ~ 25.000 + * ex : rtwpriv wlan0 mp_get_tsside 0 -12.123 + */ + legal_param_num = 2; + #endif + if (wrqu->length > 128) + return -EFAULT; + + _rtw_memset(input, 0, sizeof(input)); + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + param_num = sscanf(input, "%hhu %7s", &rfpath, pout_str_buf); + + /* Check parameter format*/ + if(param_num != legal_param_num) + goto invalid_param_format; + + if(rfpath <0 || 3 < rfpath) + goto invalid_param_format; + +#ifdef CONFIG_RTL8723F + /* Convert pout from floating-point to integer + * For Floating-Point Precision, pout*1000 + */ + if(pout_str_buf[0] == '-') + signed_flag = 1; + i = sscanf(pout_str_buf, "%d.%3u", &integer_num, &decimal_num); + pout = integer_num * 1000; + if(i == 2) { + /* Convert decimal number + * ex : 0.1 => 100, -0.1 => 100 + */ + decimal_num = (decimal_num < 10) ? decimal_num * 100 : decimal_num; + decimal_num = (decimal_num < 100) ? decimal_num * 10 : decimal_num; + pout += ((pout < 0 || signed_flag == 1) ? -decimal_num : decimal_num); + } + if(pout < -15000 || 25000 < pout) + goto invalid_param_format; +#endif + +#ifdef CONFIG_RTL8723F + /* For Floating-Point Precision, pout */ + tssi_de = halrf_get_online_tssi_de(pDM_Odm, rfpath, pout); +#else + tssi_de = halrf_tssi_get_de(pDM_Odm, rfpath); +#endif + + if (rfpath == 0) + sprintf(extra, "patha=%d hex=%02x", tssi_de, (u8)tssi_de); + else if (rfpath == 1) + sprintf(extra, "pathb=%d hex=%02x", tssi_de, (u8)tssi_de); + else if (rfpath == 2) + sprintf(extra, "pathc=%d hex=%02x", tssi_de, (u8)tssi_de); + else if (rfpath == 3) + sprintf(extra, "pathd=%d hex=%02x", tssi_de, (u8)tssi_de); + + wrqu->length = strlen(extra); + return 0; + +invalid_param_format: + sprintf(extra, "Invalid command format, please indicate RF path 0/1/2/3"); +#ifdef CONFIG_RTL8723F + pextra = extra + strlen(extra); + sprintf(pextra, " and pout value : -15.000 ~ 25.000\n"); +#endif + wrqu->length = strlen(extra); + + return 0; +} + +int rtw_mp_set_tsside(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u32 tsside_a = 0, tsside_b = 0, tsside_c = 0, tsside_d = 0; + char input[RTW_IWD_MAX_LEN]; + + PADAPTER padapter = rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct dm_struct *pDM_Odm = &pHalData->odmpriv; + + if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) + return -EFAULT; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + if (sscanf(input, "patha=%d", &tsside_a) == 1) { + sprintf(extra, "Set TSSI DE path_A: %d", tsside_a); + halrf_tssi_set_de_for_tx_verify(pDM_Odm, tsside_a, RF_PATH_A); + mpt_trigger_tssi_tracking(padapter, RF_PATH_A); + + } else if (sscanf(input, "pathb=%d", &tsside_b) == 1) { + sprintf(extra, "Set TSSI DE path_B: %d", tsside_b); + halrf_tssi_set_de_for_tx_verify(pDM_Odm, tsside_b, RF_PATH_B); + mpt_trigger_tssi_tracking(padapter, RF_PATH_B); + + } else if (sscanf(input, "pathc=%d", &tsside_c) == 1) { + sprintf(extra, "Set TSSI DE path_C: %d", tsside_c); + halrf_tssi_set_de_for_tx_verify(pDM_Odm, tsside_c, RF_PATH_C); + mpt_trigger_tssi_tracking(padapter, RF_PATH_C); + + } else if (sscanf(input, "pathd=%d", &tsside_d) == 1) { + sprintf(extra, "Set TSSI DE path_D: %d", tsside_d); + halrf_tssi_set_de_for_tx_verify(pDM_Odm, tsside_d, RF_PATH_D); + mpt_trigger_tssi_tracking(padapter, RF_PATH_D); + + } else + sprintf(extra, "Invalid command format, please input TSSI DE value within patha/b/c/d=xyz"); + + wrqu->length = strlen(extra); + + return 0; +} + int rtw_mp_getver(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -2022,7 +2033,7 @@ int rtw_mp_mon(struct net_device *dev, padapter->registrypriv.mp_mode = 0; pHalFunc->hal_init(padapter); /*rtw_disassoc_cmd(padapter, 0, 0);*/ - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { rtw_disassoc_cmd(padapter, 500, 0); rtw_indicate_disconnect(padapter, 0, _FALSE); /*rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);*/ @@ -2575,8 +2586,10 @@ int rtw_mp_hwtx(struct net_device *dev, PADAPTER padapter = rtw_netdev_priv(dev); struct mp_priv *pmp_priv = &padapter->mppriv; PMPT_CONTEXT pMptCtx = &(padapter->mppriv.mpt_ctx); + char *pch; -#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8821B) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) +#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8821B) || defined(CONFIG_RTL8822B) \ + || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8723F) if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) return -EFAULT; *(extra + wrqu->data.length) = '\0'; @@ -2584,14 +2597,17 @@ int rtw_mp_hwtx(struct net_device *dev, _rtw_memset(&pMptCtx->PMacTxInfo, 0, sizeof(RT_PMAC_TX_INFO)); _rtw_memcpy((void *)&pMptCtx->PMacTxInfo, (void *)extra, sizeof(RT_PMAC_TX_INFO)); _rtw_memset(extra, 0, wrqu->data.length); + pch = extra; if (pMptCtx->PMacTxInfo.bEnPMacTx == 1 && pmp_priv->mode != MP_ON) { - sprintf(extra, "MP Tx Running, Please Set PMac Tx Mode Stop\n"); + pch += sprintf(pch, "MP Tx Running, Please Set PMac Tx Mode Stop\n"); RTW_INFO("Error !!! MP Tx Running, Please Set PMac Tx Mode Stop\n"); } else { RTW_INFO("To set MAC Tx mode\n"); - mpt_ProSetPMacTx(padapter); - sprintf(extra, "Set PMac Tx Mode OK\n"); + if (mpt_ProSetPMacTx(padapter)) + pch += sprintf(pch, "Set PMac Tx Mode OK\n"); + else + pch += sprintf(pch, "Set PMac Tx Mode Error\n"); } wrqu->data.length = strlen(extra); #endif @@ -2605,25 +2621,26 @@ int rtw_mp_pwrlmt(struct net_device *dev, { PADAPTER padapter = rtw_netdev_priv(dev); struct registry_priv *registry_par = &padapter->registrypriv; - u8 pwrlimtstat = 0; + char *pch; if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) return -EFAULT; *(extra + wrqu->data.length) = '\0'; + pch = extra; + #if CONFIG_TXPWR_LIMIT - pwrlimtstat = registry_par->RegEnableTxPowerLimit; if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) { padapter->registrypriv.RegEnableTxPowerLimit = 0; - sprintf(extra, "Turn off Power Limit\n"); + pch += sprintf(pch, "Turn off Power Limit\n"); } else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) { padapter->registrypriv.RegEnableTxPowerLimit = 1; - sprintf(extra, "Turn on Power Limit\n"); + pch += sprintf(pch, "Turn on Power Limit\n"); } else #endif - sprintf(extra, "Get Power Limit Status:%s\n", (pwrlimtstat == 1) ? "ON" : "OFF"); + pch += sprintf(pch, "Get Power Limit Status:%s\n", (registry_par->RegEnableTxPowerLimit == 1) ? "ON" : "OFF"); wrqu->data.length = strlen(extra); @@ -2664,20 +2681,21 @@ int rtw_mp_dpk_track(struct net_device *dev, PADAPTER padapter = rtw_netdev_priv(dev); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct dm_struct *pDM_Odm = &pHalData->odmpriv; - + char *pch; if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) return -EFAULT; *(extra + wrqu->data.length) = '\0'; + pch = extra; if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) { halrf_set_dpk_track(pDM_Odm, FALSE); - sprintf(extra, "set dpk track off\n"); + pch += sprintf(pch, "set dpk track off\n"); } else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) { halrf_set_dpk_track(pDM_Odm, TRUE); - sprintf(extra, "set dpk track on\n"); + pch += sprintf(pch, "set dpk track on\n"); } wrqu->data.length = strlen(extra); @@ -2690,6 +2708,8 @@ int rtw_bt_efuse_mask_file(struct net_device *dev, union iwreq_data *wrqu, char *extra) { char *rtw_efuse_mask_file_path; + u8 *pch; + char *ptmp, tmp; u8 Status; PADAPTER padapter = rtw_netdev_priv(dev); @@ -2699,14 +2719,12 @@ int rtw_bt_efuse_mask_file(struct net_device *dev, return -EFAULT; *(extra + wrqu->data.length) = '\0'; + ptmp = extra; if (strncmp(extra, "data,", 5) == 0) { - u8 *pch; - char *ptmp, tmp; u8 count = 0; u8 i = 0; - ptmp = extra; pch = strsep(&ptmp, ","); if ((pch == NULL) || (strlen(pch) == 0)) { @@ -2737,7 +2755,7 @@ int rtw_bt_efuse_mask_file(struct net_device *dev, padapter->registrypriv.bBTFileMaskEfuse = _TRUE; - sprintf(ptmp, "\nLoad BT Efuse Mask data %d hex ok\n", count); + ptmp += sprintf(ptmp, "\nLoad BT Efuse Mask data %d hex ok\n", count); wrqu->data.length = strlen(extra); return 0; } @@ -2746,17 +2764,18 @@ int rtw_bt_efuse_mask_file(struct net_device *dev, if (rtw_is_file_readable(rtw_efuse_mask_file_path) == _TRUE) { RTW_INFO("%s do rtw_is_file_readable = %s! ,sizeof BT maskfileBuffer %zu\n", __func__, rtw_efuse_mask_file_path, sizeof(btmaskfileBuffer)); Status = rtw_efuse_file_read(padapter, rtw_efuse_mask_file_path, btmaskfileBuffer, sizeof(btmaskfileBuffer)); + _rtw_memset(extra, '\0' , strlen(extra)); if (Status == _TRUE) { padapter->registrypriv.bBTFileMaskEfuse = _TRUE; - sprintf(extra, "BT efuse mask file read OK\n"); + ptmp += sprintf(ptmp, "BT efuse mask file read OK\n"); } else { padapter->registrypriv.bBTFileMaskEfuse = _FALSE; - sprintf(extra, "read BT efuse mask file FAIL\n"); + ptmp += sprintf(ptmp, "read BT efuse mask file FAIL\n"); RTW_INFO("%s rtw_efuse_file_read BT mask fail!\n", __func__); } } else { padapter->registrypriv.bBTFileMaskEfuse = _FALSE; - sprintf(extra, "BT efuse mask file readable FAIL\n"); + ptmp += sprintf(ptmp, "BT efuse mask file readable FAIL\n"); RTW_INFO("%s rtw_is_file_readable BT Mask file fail!\n", __func__); } wrqu->data.length = strlen(extra); @@ -2891,6 +2910,45 @@ int rtw_efuse_file_map(struct net_device *dev, return 0; } + +int rtw_efuse_file_map_store(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + char *rtw_efuse_file_map_path; + u8 Status; + u16 mapLen; + PEFUSE_HAL pEfuseHal; + PADAPTER padapter = rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct mp_priv *pmp_priv = &padapter->mppriv; + + pEfuseHal = &pHalData->EfuseHal; + if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; + + rtw_efuse_file_map_path = extra; + RTW_INFO("%s rtw_is_file_readable! %s\n", __func__, rtw_efuse_file_map_path); + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapLen, _FALSE); + + if (mapLen != 0) { + RTW_INFO("%s, efuse store path = %s! mapLen = %d\n", __func__, rtw_efuse_file_map_path, mapLen); + Status = rtw_efuse_file_store(padapter, rtw_efuse_file_map_path, pEfuseHal->fakeEfuseModifiedMap, mapLen); + if (Status) { + sprintf(extra, "efuse file restore OK\n"); + } else { + sprintf(extra, "efuse file restore FAIL\n"); + } + } else { + sprintf(extra, "efuse file readable FAIL\n"); + RTW_INFO("%s rtw_is_file_readable fail! map Len %d\n", __func__, mapLen); + } + + wrqu->data.length = strlen(extra); + return 0; +} + int rtw_bt_efuse_file_map(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -2947,22 +3005,20 @@ int rtw_mp_link(struct net_device *dev, struct mp_priv *pmp_priv; char input[RTW_IWD_MAX_LEN]; int bgetrxdata = 0, btxdata = 0, bsetbt = 0; + u8 err = 0; u32 i = 0, datalen = 0,jj, kk, waittime = 0; - u16 val = 0x00, res = 0; + u16 val = 0x00, ret = 0; char *pextra = NULL; u8 *setdata = NULL; char *pch, *ptmp, *token, *tmp[4] = {0x00, 0x00, 0x00}; - int ret = 0; pmp_priv = &padapter->mppriv; if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) return -EFAULT; - if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - ret = -EFAULT; - goto exit; - } + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; _rtw_memset(extra, 0, wrqu->length); @@ -2975,7 +3031,7 @@ int rtw_mp_link(struct net_device *dev, if (bgetrxdata) { RTW_INFO("%s: in= 1 \n", __func__); if (pmp_priv->mplink_brx == _TRUE) { - + pch = extra; while (waittime < 100 && pmp_priv->mplink_brx == _FALSE) { if (pmp_priv->mplink_brx == _FALSE) rtw_msleep_os(10); @@ -2984,10 +3040,10 @@ int rtw_mp_link(struct net_device *dev, waittime++; } if (pmp_priv->mplink_brx == _TRUE) { - sprintf(extra, "\n"); - pextra = extra + strlen(extra); + pch += sprintf(pch, "\n"); + for (i = 0; i < pmp_priv->mplink_rx_len; i ++) { - pextra += sprintf(pextra, "%02x:", pmp_priv->mplink_buf[i]); + pch += sprintf(pch, "%02x:", pmp_priv->mplink_buf[i]); } _rtw_memset(pmp_priv->mplink_buf, '\0' , sizeof(pmp_priv->mplink_buf)); pmp_priv->mplink_brx = _FALSE; @@ -2999,7 +3055,7 @@ int rtw_mp_link(struct net_device *dev, pch = input; setdata = rtw_zmalloc(1024); if (setdata == NULL) { - ret = -ENOMEM; + err = -ENOMEM; goto exit; } @@ -3014,20 +3070,20 @@ int rtw_mp_link(struct net_device *dev, /* tmp[0],[1],[2] */ /* txdata,00e04c871200........... */ if (strcmp(tmp[0], "txdata") == 0) { - if (tmp[1] == NULL) { - ret = -EINVAL; + if ((tmp[1] == NULL)) { + err = -EINVAL; goto exit; } } datalen = strlen(tmp[1]); if (datalen % 2) { - ret = -EINVAL; + err = -EINVAL; goto exit; } datalen /= 2; if (datalen == 0) { - ret = -EINVAL; + err = -EINVAL; goto exit; } @@ -3063,7 +3119,7 @@ int rtw_mp_link(struct net_device *dev, } if (tmp[1] == NULL) { - ret = -EINVAL; + err = -EINVAL; goto exit; } @@ -3097,7 +3153,7 @@ int rtw_mp_link(struct net_device *dev, } else if (strcmp(tmp[1], "testmode") == 0) { if (tmp[2] == NULL) { - ret = -EINVAL; + err = -EINVAL; goto exit; } @@ -3106,12 +3162,13 @@ int rtw_mp_link(struct net_device *dev, if (tmp[2] != NULL) { _rtw_memset(extra, 0, wrqu->length); - res = rtw_btcoex_btset_testmode(padapter, val); - if (!CHECK_STATUS_CODE_FROM_BT_MP_OPER_RET(res, BT_STATUS_BT_OP_SUCCESS)) { + pch = extra; + ret = rtw_btcoex_btset_testmode(padapter, val); + if (!CHECK_STATUS_CODE_FROM_BT_MP_OPER_RET(ret, BT_STATUS_BT_OP_SUCCESS)) { RTW_INFO("%s: BT_OP fail = 0x%x!\n", __FUNCTION__, val); - sprintf(extra, "BT_OP fail 0x%x!\n", val); + pch += sprintf(pch, "BT_OP fail 0x%x!\n", val); } else - sprintf(extra, "Set BT_OP 0x%x done!\n", val); + pch += sprintf(pch, "Set BT_OP 0x%x done!\n", val); } } @@ -3123,10 +3180,8 @@ exit: rtw_mfree(setdata, 1024); wrqu->length = strlen(extra); + return err; - rtw_mfree(input, wrqu->length); - - return ret; } #if defined(CONFIG_RTL8723B) @@ -3156,6 +3211,7 @@ int rtw_mp_SetBT(struct net_device *dev, return -EFAULT; *(extra + wrqu->data.length) = '\0'; + pch = extra; if (strlen(extra) < 1) return -EFAULT; @@ -3178,7 +3234,7 @@ int rtw_mp_SetBT(struct net_device *dev, BTStatus = rtw_read8(padapter, 0xa0); RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __func__, BTStatus); if (BTStatus != 0x04) { - sprintf(extra, "BT Status not Active DLFW FAIL\n"); + pch += sprintf(pch, "BT Status not Active DLFW FAIL\n"); goto exit; } @@ -3223,11 +3279,11 @@ int rtw_mp_SetBT(struct net_device *dev, if ((pMptCtx->mptOutBuf[4] == 0x00) && (pMptCtx->mptOutBuf[5] == 0x00)) { if (padapter->mppriv.bTxBufCkFail == _TRUE) - sprintf(extra, "check TxBuf Fail.\n"); + pch += sprintf(pch, "check TxBuf Fail.\n"); else - sprintf(extra, "download FW Fail.\n"); + pch += sprintf(pch, "download FW Fail.\n"); } else { - sprintf(extra, "download FW OK.\n"); + pch += sprintf(pch, "download FW OK.\n"); goto exit; } goto exit; @@ -3239,7 +3295,7 @@ int rtw_mp_SetBT(struct net_device *dev, BTStatus = rtw_read8(padapter, 0xa0); RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __func__, BTStatus); if (BTStatus != 0x04) { - sprintf(extra, "BT Status not Active DLFW FAIL\n"); + pch += sprintf(pch, "BT Status not Active DLFW FAIL\n"); goto exit; } @@ -3293,15 +3349,15 @@ int rtw_mp_SetBT(struct net_device *dev, RTW_INFO("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4], pMptCtx->mptOutBuf[5]); if ((pMptCtx->mptOutBuf[4] == 0x00) && (pMptCtx->mptOutBuf[5] == 0x00)) { if (padapter->mppriv.bTxBufCkFail == _TRUE) - sprintf(extra, "check TxBuf Fail.\n"); + pch += sprintf(pch, "check TxBuf Fail.\n"); else - sprintf(extra, "download FW Fail.\n"); + pch += sprintf(pch, "download FW Fail.\n"); } else { #ifdef CONFIG_BT_COEXIST rtw_btcoex_SwitchBtTRxMask(padapter); #endif rtw_msleep_os(200); - sprintf(extra, "download FW OK.\n"); + pch += sprintf(pch, "download FW OK.\n"); goto exit; } goto exit; @@ -3370,7 +3426,6 @@ int rtw_mp_SetBT(struct net_device *dev, goto todo; } - pch = extra; i = 0; while ((token = strsep(&pch, ",")) != NULL) { if (i > 1) @@ -3444,23 +3499,23 @@ todo: _rtw_memset(extra, '\0', wrqu->data.length); if (pHalData->bBTFWReady == _FALSE) { - sprintf(extra, "BTFWReady = FALSE.\n"); + pch += sprintf(pch, "BTFWReady = FALSE.\n"); goto exit; } mptbt_BtControlProcess(padapter, &BtReq); if (readtherm == 0) { - sprintf(extra, "BT thermal="); + pch += sprintf(pch, "BT thermal="); for (i = 4; i < pMptCtx->mptOutLen; i++) { if ((pMptCtx->mptOutBuf[i] == 0x00) && (pMptCtx->mptOutBuf[i + 1] == 0x00)) goto exit; - sprintf(extra, "%s %d ", extra, (pMptCtx->mptOutBuf[i] & 0x1f)); + pch += sprintf(pch, " %d ", (pMptCtx->mptOutBuf[i] & 0x1f)); } } else { for (i = 4; i < pMptCtx->mptOutLen; i++) - sprintf(extra, "%s 0x%x ", extra, pMptCtx->mptOutBuf[i]); + pch += sprintf(pch, " 0x%x ", pMptCtx->mptOutBuf[i]); } exit: diff --git a/os_dep/linux/mlme_linux.c b/os_dep/linux/mlme_linux.c index 0c3bc0b..6fd24e8 100644 --- a/os_dep/linux/mlme_linux.c +++ b/os_dep/linux/mlme_linux.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2019 Realtek Corporation. + * Copyright(c) 2007 - 2017 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -54,20 +54,16 @@ void Linkdown_workitem_callback(struct work_struct *work) extern void rtw_indicate_wx_assoc_event(_adapter *padapter); extern void rtw_indicate_wx_disassoc_event(_adapter *padapter); -int rtw_os_indicate_connect(_adapter *adapter) +void rtw_os_indicate_connect(_adapter *adapter) { struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); - int err = 0; #ifdef CONFIG_IOCTL_CFG80211 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) || - (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) { + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) rtw_cfg80211_ibss_indicate_connect(adapter); - } else { - err = rtw_cfg80211_indicate_connect(adapter); - if (err) - return -1; - } + else + rtw_cfg80211_indicate_connect(adapter); #endif /* CONFIG_IOCTL_CFG80211 */ rtw_indicate_wx_assoc_event(adapter); @@ -86,7 +82,7 @@ int rtw_os_indicate_connect(_adapter *adapter) _set_workitem(&adapter->mlmepriv.Linkup_workitem); #endif - return err; + } extern void indicate_wx_scan_complete_event(_adapter *padapter); @@ -110,6 +106,11 @@ void rtw_reset_securitypriv(_adapter *adapter) _enter_critical_bh(&adapter->security_key_mutex, &irqL); if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /* 802.1x */ + u8 backup_sw_encrypt, backup_sw_decrypt; + + backup_sw_encrypt = adapter->securitypriv.sw_encrypt; + backup_sw_decrypt = adapter->securitypriv.sw_decrypt; + /* Added by Albert 2009/02/18 */ /* We have to backup the PMK information for WiFi PMK Caching test item. */ /* */ @@ -136,6 +137,9 @@ void rtw_reset_securitypriv(_adapter *adapter) adapter->securitypriv.extauth_status = WLAN_STATUS_UNSPECIFIED_FAILURE; + adapter->securitypriv.sw_encrypt = backup_sw_encrypt; + adapter->securitypriv.sw_decrypt = backup_sw_decrypt; + } else { /* reset values in securitypriv */ /* if(adapter->mlmepriv.fw_state & WIFI_STATION_STATE) */ /* { */ @@ -177,7 +181,9 @@ void rtw_os_indicate_disconnect(_adapter *adapter, u16 reason, u8 locally_gener _set_workitem(&adapter->mlmepriv.Linkdown_workitem); #endif /* modify for CONFIG_IEEE80211W, none 11w also can use the same command */ - rtw_reset_securitypriv(adapter); + rtw_reset_securitypriv_cmd(adapter); + + } void rtw_report_sec_ie(_adapter *adapter, u8 authmode, u8 *sec_ie) diff --git a/os_dep/linux/nlrtw.c b/os_dep/linux/nlrtw.c new file mode 100644 index 0000000..14d164b --- /dev/null +++ b/os_dep/linux/nlrtw.c @@ -0,0 +1,583 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2020 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#define _RTW_NLRTW_C_ + +#include +#include "nlrtw.h" + +#ifdef CONFIG_RTW_NLRTW + +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)) +#include +#endif + + +enum nlrtw_cmds { + NLRTW_CMD_UNSPEC, + + NLRTW_CMD_CHANNEL_UTILIZATION, + NLRTW_CMD_REG_CHANGE, + NLRTW_CMD_REG_BEACON_HINT, + NLRTW_CMD_RADAR_EVENT, + NLRTW_CMD_RADIO_OPMODE, + + __NLRTW_CMD_AFTER_LAST, + NLRTW_CMD_MAX = __NLRTW_CMD_AFTER_LAST - 1 +}; + +enum nlrtw_attrs { + NLRTW_ATTR_UNSPEC, + + NLRTW_ATTR_WIPHY_NAME, + NLRTW_ATTR_CHANNEL_UTILIZATIONS, + NLRTW_ATTR_CHANNEL_UTILIZATION_THRESHOLD, + NLRTW_ATTR_CHANNEL_CENTER, + NLRTW_ATTR_CHANNEL_WIDTH, + NLRTW_ATTR_RADAR_EVENT, + NLRTW_ATTR_OP_CLASS, + NLRTW_ATTR_OP_CHANNEL, + NLRTW_ATTR_OP_TXPWR_MAX, + NLRTW_ATTR_IF_OPMODES, + + __NLRTW_ATTR_AFTER_LAST, + NUM_NLRTW_ATTR = __NLRTW_ATTR_AFTER_LAST, + NLRTW_ATTR_MAX = __NLRTW_ATTR_AFTER_LAST - 1 +}; + +enum nlrtw_ch_util_attrs { + __NLRTW_ATTR_CHANNEL_UTILIZATION_INVALID, + + NLRTW_ATTR_CHANNEL_UTILIZATION_VALUE, + NLRTW_ATTR_CHANNEL_UTILIZATION_BSSID, + + __NLRTW_ATTR_CHANNEL_UTILIZATION_AFTER_LAST, + NUM_NLRTW_ATTR_CHANNEL_UTILIZATION = __NLRTW_ATTR_CHANNEL_UTILIZATION_AFTER_LAST, + NLRTW_ATTR_CHANNEL_UTILIZATION_MAX = __NLRTW_ATTR_CHANNEL_UTILIZATION_AFTER_LAST - 1 +}; + +enum nlrtw_radar_event { + NLRTW_RADAR_DETECTED, + NLRTW_RADAR_CAC_FINISHED, + NLRTW_RADAR_CAC_ABORTED, + NLRTW_RADAR_NOP_FINISHED, + NLRTW_RADAR_NOP_STARTED, /* NON_OCP started not by local radar detection */ +}; + +enum nlrtw_if_opmode_attrs { + NLRTW_IF_OPMODE_UNSPEC, + + NLRTW_IF_OPMODE_MACADDR, + NLRTW_IF_OPMODE_OP_CLASS, + NLRTW_IF_OPMODE_OP_CHANNEL, + + __NLRTW_IF_OPMODE_ATTR_AFTER_LAST, + NUM_NLRTW_IF_OPMODE_ATTR = __NLRTW_IF_OPMODE_ATTR_AFTER_LAST, + NLRTW_IF_OPMODE_ATTR_MAX = __NLRTW_IF_OPMODE_ATTR_AFTER_LAST - 1 +}; + +static int nlrtw_ch_util_set(struct sk_buff *skb, struct genl_info *info) +{ + unsigned int msg; + + if (!info->attrs[NLRTW_ATTR_CHANNEL_UTILIZATION_THRESHOLD]) + return -EINVAL; + msg = nla_get_u8(info->attrs[NLRTW_ATTR_CHANNEL_UTILIZATION_THRESHOLD]); + + return 0; +} + +static struct nla_policy nlrtw_genl_policy[NUM_NLRTW_ATTR] = { + [NLRTW_ATTR_CHANNEL_UTILIZATION_THRESHOLD] = { .type = NLA_U8 }, +}; + +static struct genl_ops nlrtw_genl_ops[] = { + { + .cmd = NLRTW_CMD_CHANNEL_UTILIZATION, + .flags = 0, +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) + .policy = nlrtw_genl_policy, +#endif + .doit = nlrtw_ch_util_set, + .dumpit = NULL, + }, +}; + +enum nlrtw_multicast_groups { + NLRTW_MCGRP_DEFAULT, +}; +static struct genl_multicast_group nlrtw_genl_mcgrp[] = { + [NLRTW_MCGRP_DEFAULT] = { .name = "nlrtw_default" }, +}; + +/* family definition */ +static struct genl_family nlrtw_genl_family = { + .hdrsize = 0, + .name = "nlrtw_"DRV_NAME, + .version = 1, + .maxattr = NLRTW_ATTR_MAX, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) + .policy = nlrtw_genl_policy, +#endif + .netnsok = true, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 12) + .module = THIS_MODULE, +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) + .ops = nlrtw_genl_ops, + .n_ops = ARRAY_SIZE(nlrtw_genl_ops), + .mcgrps = nlrtw_genl_mcgrp, + .n_mcgrps = ARRAY_SIZE(nlrtw_genl_mcgrp), +#endif +}; + +static inline int nlrtw_multicast(const struct genl_family *family, + struct sk_buff *skb, u32 portid, + unsigned int group, gfp_t flags) +{ + int ret; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) + ret = genlmsg_multicast(&nlrtw_genl_family, skb, portid, group, flags); +#else + ret = genlmsg_multicast(skb, portid, nlrtw_genl_mcgrp[group].id, flags); +#endif + return ret; +} + +int rtw_nlrtw_ch_util_rpt(_adapter *adapter, u8 n_rpts, u8 *val, u8 **mac_addr) +{ + struct sk_buff *skb = NULL; + void *msg_header = NULL; + struct nlattr *nl_ch_util, *nl_ch_utils; + struct wiphy *wiphy; + u8 i; + int ret; + + wiphy = adapter_to_wiphy(adapter); + if (!wiphy) + return -EINVAL; + + /* allocate memory */ + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) { + nlmsg_free(skb); + return -ENOMEM; + } + + /* create the message headers */ + msg_header = genlmsg_put(skb, 0, 0, &nlrtw_genl_family, 0, + NLRTW_CMD_CHANNEL_UTILIZATION); + if (!msg_header) { + ret = -ENOMEM; + goto err_out; + } + + /* add attributes */ + ret = nla_put_string(skb, NLRTW_ATTR_WIPHY_NAME, wiphy_name(wiphy)); + + nl_ch_utils = nla_nest_start(skb, NLRTW_ATTR_CHANNEL_UTILIZATIONS); + if (!nl_ch_utils) { + ret = -EMSGSIZE; + goto err_out; + } + + for (i = 0; i < n_rpts; i++) { + nl_ch_util = nla_nest_start(skb, i); + if (!nl_ch_util) { + ret = -EMSGSIZE; + goto err_out; + } + + ret = nla_put(skb, NLRTW_ATTR_CHANNEL_UTILIZATION_BSSID, ETH_ALEN, *(mac_addr + i)); + if (ret != 0) + goto err_out; + + ret = nla_put_u8(skb, NLRTW_ATTR_CHANNEL_UTILIZATION_VALUE, *(val + i)); + if (ret != 0) + goto err_out; + + nla_nest_end(skb, nl_ch_util); + } + + nla_nest_end(skb, nl_ch_utils); + + /* finalize the message */ + genlmsg_end(skb, msg_header); + + ret = nlrtw_multicast(&nlrtw_genl_family, skb, 0, NLRTW_MCGRP_DEFAULT, GFP_KERNEL); + if (ret == -ESRCH) { + RTW_INFO("[%s] return ESRCH(No such process)." + " Maybe no process waits for this msg\n", __func__); + return ret; + } else if (ret != 0) { + RTW_INFO("[%s] ret = %d\n", __func__, ret); + return ret; + } + + return 0; +err_out: + nlmsg_free(skb); + return ret; +} + +int rtw_nlrtw_reg_change_event(_adapter *adapter) +{ + struct sk_buff *skb = NULL; + void *msg_header = NULL; + struct wiphy *wiphy; + u8 i; + int ret; + + wiphy = adapter_to_wiphy(adapter); + if (!wiphy) { + ret = -EINVAL; + goto err_out; + } + + /* allocate memory */ + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) { + ret = -ENOMEM; + goto err_out; + } + + /* create the message headers */ + msg_header = genlmsg_put(skb, 0, 0, &nlrtw_genl_family, 0, NLRTW_CMD_REG_CHANGE); + if (!msg_header) { + ret = -ENOMEM; + goto err_out; + } + + /* add attributes */ + ret = nla_put_string(skb, NLRTW_ATTR_WIPHY_NAME, wiphy_name(wiphy)); + if (ret) + goto err_out; + + /* finalize the message */ + genlmsg_end(skb, msg_header); + + ret = nlrtw_multicast(&nlrtw_genl_family, skb, 0, NLRTW_MCGRP_DEFAULT, GFP_KERNEL); + if (ret == -ESRCH) { + RTW_DBG(FUNC_WIPHY_FMT" return -ESRCH(No such process)." + " Maybe no process waits for this msg\n", FUNC_WIPHY_ARG(wiphy)); + return ret; + } else if (ret != 0) { + RTW_WARN(FUNC_WIPHY_FMT" return %d\n", FUNC_WIPHY_ARG(wiphy), ret); + return ret; + } + + return 0; + +err_out: + if (skb) + nlmsg_free(skb); + return ret; +} + +int rtw_nlrtw_reg_beacon_hint_event(_adapter *adapter) +{ + struct sk_buff *skb = NULL; + void *msg_header = NULL; + struct wiphy *wiphy; + u8 i; + int ret; + + wiphy = adapter_to_wiphy(adapter); + if (!wiphy) { + ret = -EINVAL; + goto err_out; + } + + /* allocate memory */ + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) { + ret = -ENOMEM; + goto err_out; + } + + /* create the message headers */ + msg_header = genlmsg_put(skb, 0, 0, &nlrtw_genl_family, 0, NLRTW_CMD_REG_BEACON_HINT); + if (!msg_header) { + ret = -ENOMEM; + goto err_out; + } + + /* add attributes */ + ret = nla_put_string(skb, NLRTW_ATTR_WIPHY_NAME, wiphy_name(wiphy)); + if (ret) + goto err_out; + + /* finalize the message */ + genlmsg_end(skb, msg_header); + + ret = nlrtw_multicast(&nlrtw_genl_family, skb, 0, NLRTW_MCGRP_DEFAULT, GFP_KERNEL); + if (ret == -ESRCH) { + RTW_DBG(FUNC_WIPHY_FMT" return -ESRCH(No such process)." + " Maybe no process waits for this msg\n", FUNC_WIPHY_ARG(wiphy)); + return ret; + } else if (ret != 0) { + RTW_WARN(FUNC_WIPHY_FMT" return %d\n", FUNC_WIPHY_ARG(wiphy), ret); + return ret; + } + + return 0; + +err_out: + if (skb) + nlmsg_free(skb); + return ret; +} + +#ifdef CONFIG_DFS_MASTER +static int _rtw_nlrtw_radar_event(_adapter *adapter, enum nlrtw_radar_event evt_type, u8 cch, u8 bw) +{ + struct sk_buff *skb = NULL; + void *msg_header = NULL; + struct wiphy *wiphy; + u8 i; + int ret; + + wiphy = adapter_to_wiphy(adapter); + if (!wiphy) { + ret = -EINVAL; + goto err_out; + } + + /* allocate memory */ + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) { + ret = -ENOMEM; + goto err_out; + } + + /* create the message headers */ + msg_header = genlmsg_put(skb, 0, 0, &nlrtw_genl_family, 0, NLRTW_CMD_RADAR_EVENT); + if (!msg_header) { + ret = -ENOMEM; + goto err_out; + } + + /* add attributes */ + ret = nla_put_string(skb, NLRTW_ATTR_WIPHY_NAME, wiphy_name(wiphy)); + if (ret) + goto err_out; + + ret = nla_put_u8(skb, NLRTW_ATTR_RADAR_EVENT, (uint8_t)evt_type); + if (ret != 0) + goto err_out; + + ret = nla_put_u8(skb, NLRTW_ATTR_CHANNEL_CENTER, cch); + if (ret != 0) + goto err_out; + + ret = nla_put_u8(skb, NLRTW_ATTR_CHANNEL_WIDTH, bw); + if (ret != 0) + goto err_out; + + /* finalize the message */ + genlmsg_end(skb, msg_header); + + ret = nlrtw_multicast(&nlrtw_genl_family, skb, 0, NLRTW_MCGRP_DEFAULT, GFP_KERNEL); + if (ret == -ESRCH) { + RTW_DBG(FUNC_WIPHY_FMT" return -ESRCH(No such process)." + " Maybe no process waits for this msg\n", FUNC_WIPHY_ARG(wiphy)); + return ret; + } else if (ret != 0) { + RTW_WARN(FUNC_WIPHY_FMT" return %d\n", FUNC_WIPHY_ARG(wiphy), ret); + return ret; + } + + return 0; + +err_out: + if (skb) + nlmsg_free(skb); + return ret; +} + +int rtw_nlrtw_radar_detect_event(_adapter *adapter, u8 cch, u8 bw) +{ + return _rtw_nlrtw_radar_event(adapter, NLRTW_RADAR_DETECTED, cch, bw); +} + +int rtw_nlrtw_cac_finish_event(_adapter *adapter, u8 cch, u8 bw) +{ + return _rtw_nlrtw_radar_event(adapter, NLRTW_RADAR_CAC_FINISHED, cch, bw); +} + +int rtw_nlrtw_cac_abort_event(_adapter *adapter, u8 cch, u8 bw) +{ + return _rtw_nlrtw_radar_event(adapter, NLRTW_RADAR_CAC_ABORTED, cch, bw); +} + +int rtw_nlrtw_nop_finish_event(_adapter *adapter, u8 cch, u8 bw) +{ + return _rtw_nlrtw_radar_event(adapter, NLRTW_RADAR_NOP_FINISHED, cch, bw); +} + +int rtw_nlrtw_nop_start_event(_adapter *adapter, u8 cch, u8 bw) +{ + return _rtw_nlrtw_radar_event(adapter, NLRTW_RADAR_NOP_STARTED, cch, bw); +} +#endif /* CONFIG_DFS_MASTER */ + +int rtw_nlrtw_radio_opmode_notify(struct rf_ctl_t *rfctl) +{ + struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl); + _adapter *iface; + struct sk_buff *skb = NULL; + void *msg_header = NULL; + struct nlattr *nl_if_opmodes, *nl_if_opmode; + struct wiphy *wiphy; + u16 op_txpwr_max_u16; + u8 i; + int ret; + + wiphy = dvobj_to_wiphy(dvobj); + if (!wiphy) { + ret = -EINVAL; + goto err_out; + } + + /* allocate memory */ + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) { + ret = -ENOMEM; + goto err_out; + } + + /* create the message headers */ + msg_header = genlmsg_put(skb, 0, 0, &nlrtw_genl_family, 0, NLRTW_CMD_RADIO_OPMODE); + if (!msg_header) { + ret = -ENOBUFS; + goto err_out; + } + + /* add attributes */ + ret = nla_put_string(skb, NLRTW_ATTR_WIPHY_NAME, wiphy_name(wiphy)); + if (ret) + goto err_out; + + ret = nla_put_u8(skb, NLRTW_ATTR_OP_CLASS, rfctl->op_class); + if (ret != 0) + goto err_out; + + ret = nla_put_u8(skb, NLRTW_ATTR_OP_CHANNEL, rfctl->op_ch); + if (ret != 0) + goto err_out; + + *((s16 *)&op_txpwr_max_u16) = rfctl->op_txpwr_max; + ret = nla_put_u16(skb, NLRTW_ATTR_OP_TXPWR_MAX, op_txpwr_max_u16); + if (ret != 0) + goto err_out; + + if (0) + RTW_INFO("radio: %u,%u %d\n", rfctl->op_class, rfctl->op_ch, rfctl->op_txpwr_max); + + nl_if_opmodes = nla_nest_start(skb, NLRTW_ATTR_IF_OPMODES); + if (!nl_if_opmodes) { + ret = -ENOBUFS; + goto err_out; + } + + for (i = 0; i < dvobj->iface_nums; i++) { + if (!dvobj->padapters[i]) + continue; + iface = dvobj->padapters[i]; + + if (!rfctl->if_op_class[i] || !rfctl->if_op_ch[i]) + continue; + + if (0) + RTW_INFO(ADPT_FMT": %u,%u\n", ADPT_ARG(iface), rfctl->if_op_class[i], rfctl->if_op_ch[i]); + + nl_if_opmode = nla_nest_start(skb, i + 1); + if (!nl_if_opmode) { + ret = -ENOBUFS; + goto err_out; + } + + ret = nla_put(skb, NLRTW_IF_OPMODE_MACADDR, ETH_ALEN, adapter_mac_addr(iface)); + if (ret != 0) + goto err_out; + + ret = nla_put_u8(skb, NLRTW_IF_OPMODE_OP_CLASS, rfctl->if_op_class[i]); + if (ret != 0) + goto err_out; + + ret = nla_put_u8(skb, NLRTW_IF_OPMODE_OP_CHANNEL, rfctl->if_op_ch[i]); + if (ret != 0) + goto err_out; + + nla_nest_end(skb, nl_if_opmode); + } + + nla_nest_end(skb, nl_if_opmodes); + + /* finalize the message */ + genlmsg_end(skb, msg_header); + + ret = nlrtw_multicast(&nlrtw_genl_family, skb, 0, NLRTW_MCGRP_DEFAULT, GFP_KERNEL); + if (ret == -ESRCH) { + RTW_DBG(FUNC_WIPHY_FMT" return -ESRCH(No such process)." + " Maybe no process waits for this msg\n", FUNC_WIPHY_ARG(wiphy)); + return ret; + } else if (ret != 0) { + RTW_WARN(FUNC_WIPHY_FMT" return %d\n", FUNC_WIPHY_ARG(wiphy), ret); + return ret; + } + + return 0; + +err_out: + if (skb) + nlmsg_free(skb); + return ret; +} + +int rtw_nlrtw_init(void) +{ + int err; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) + err = genl_register_family(&nlrtw_genl_family); + if (err) + return err; +#else + err = genl_register_family_with_ops(&nlrtw_genl_family, nlrtw_genl_ops, ARRAY_SIZE(nlrtw_genl_ops)); + if (err) + return err; + + err = genl_register_mc_group(&nlrtw_genl_family, &nlrtw_genl_mcgrp[0]); + if (err) { + genl_unregister_family(&nlrtw_genl_family); + return err; + } +#endif + RTW_INFO("[%s] %s\n", __func__, nlrtw_genl_family.name); + return 0; +} + +int rtw_nlrtw_deinit(void) +{ + int err; + + err = genl_unregister_family(&nlrtw_genl_family); + RTW_INFO("[%s] err = %d\n", __func__, err); + + return err; +} +#endif /* CONFIG_RTW_NLRTW */ diff --git a/os_dep/linux/nlrtw.h b/os_dep/linux/nlrtw.h new file mode 100644 index 0000000..374002a --- /dev/null +++ b/os_dep/linux/nlrtw.h @@ -0,0 +1,48 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2020 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#ifndef __RTW_NLRTW_H_ +#define __RTW_NLRTW_H_ + +#ifdef CONFIG_RTW_NLRTW +int rtw_nlrtw_init(void); +int rtw_nlrtw_deinit(void); +int rtw_nlrtw_ch_util_rpt(_adapter *adapter, u8 n_rpts, u8 *val, u8 **mac_addr); +int rtw_nlrtw_reg_change_event(_adapter *adapter); +int rtw_nlrtw_reg_beacon_hint_event(_adapter *adapter); +int rtw_nlrtw_radio_opmode_notify(struct rf_ctl_t *rfctl); +#else +static inline int rtw_nlrtw_init(void) {return _FAIL;} +static inline int rtw_nlrtw_deinit(void) {return _FAIL;} +static inline int rtw_nlrtw_ch_util_rpt(_adapter *adapter, u8 n_rpts, u8 *val, u8 **mac_addr) {return _FAIL;} +static inline int rtw_nlrtw_reg_change_event(_adapter *adapter) {return _FAIL;} +static inline int rtw_nlrtw_reg_beacon_hint_event(_adapter *adapter) {return _FAIL;} +static inline int rtw_nlrtw_radio_opmode_notify(struct rf_ctl_t *rfctl) {return _FAIL;} +#endif /* CONFIG_RTW_NLRTW */ + +#if defined(CONFIG_RTW_NLRTW) && defined(CONFIG_DFS_MASTER) +int rtw_nlrtw_radar_detect_event(_adapter *adapter, u8 cch, u8 bw); +int rtw_nlrtw_cac_finish_event(_adapter *adapter, u8 cch, u8 bw); +int rtw_nlrtw_cac_abort_event(_adapter *adapter, u8 cch, u8 bw); +int rtw_nlrtw_nop_finish_event(_adapter *adapter, u8 cch, u8 bw); +int rtw_nlrtw_nop_start_event(_adapter *adapter, u8 cch, u8 bw); +#else +static inline int rtw_nlrtw_radar_detect_event(_adapter *adapter, u8 cch, u8 bw) {return _FAIL;} +static inline int rtw_nlrtw_cac_finish_event(_adapter *adapter, u8 cch, u8 bw) {return _FAIL;} +static inline int rtw_nlrtw_cac_abort_event(_adapter *adapter, u8 cch, u8 bw) {return _FAIL;} +static inline int rtw_nlrtw_nop_finish_event(_adapter *adapter, u8 cch, u8 bw) {return _FAIL;} +static inline int rtw_nlrtw_nop_start_event(_adapter *adapter, u8 cch, u8 bw) {return _FAIL;} +#endif /* defined(CONFIG_RTW_NLRTW) && defined(CONFIG_DFS_MASTER) */ + +#endif /* __RTW_NLRTW_H_ */ diff --git a/os_dep/linux/os_intfs.c b/os_dep/linux/os_intfs.c index 05d7672..6ff81a4 100644 --- a/os_dep/linux/os_intfs.c +++ b/os_dep/linux/os_intfs.c @@ -209,12 +209,14 @@ static uint rtw_tx_aclt_conf_default_num = 0; module_param_array(rtw_tx_aclt_conf_default, uint, &rtw_tx_aclt_conf_default_num, 0644); MODULE_PARM_DESC(rtw_tx_aclt_conf_default, "device TX AC queue lifetime config for default status"); -#ifdef CONFIG_TX_MCAST2UNI +#ifdef CONFIG_AP_MODE +#if CONFIG_RTW_AP_DATA_BMC_TO_UC static uint rtw_tx_aclt_conf_ap_m2u[3] = CONFIG_TX_ACLT_CONF_AP_M2U; static uint rtw_tx_aclt_conf_ap_m2u_num = 0; module_param_array(rtw_tx_aclt_conf_ap_m2u, uint, &rtw_tx_aclt_conf_ap_m2u_num, 0644); MODULE_PARM_DESC(rtw_tx_aclt_conf_ap_m2u, "device TX AC queue lifetime config for AP mode M2U status"); #endif +#endif /* CONFIG_AP_MODE */ #ifdef CONFIG_RTW_MESH static uint rtw_tx_aclt_conf_mesh[3] = CONFIG_TX_ACLT_CONF_MESH; @@ -259,6 +261,8 @@ int rtw_rx_ampdu_amsdu;/* 0: disabled, 1:enabled, 2:auto . There is an IOT issu */ int rtw_tx_ampdu_amsdu = 2; +int rtw_quick_addba_req = 0; + static uint rtw_rx_ampdu_sz_limit_1ss[4] = CONFIG_RTW_RX_AMPDU_SZ_LIMIT_1SS; static uint rtw_rx_ampdu_sz_limit_1ss_num = 0; module_param_array(rtw_rx_ampdu_sz_limit_1ss, uint, &rtw_rx_ampdu_sz_limit_1ss_num, 0644); @@ -288,8 +292,12 @@ int rtw_short_gi = 0xf; /* BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx, BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx */ int rtw_ldpc_cap = 0x33; /* BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx, BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx */ +#ifdef CONFIG_RTL8192F +int rtw_stbc_cap = 0x30; +#else int rtw_stbc_cap = 0x13; - +#endif +module_param(rtw_stbc_cap, int, 0644); /* * BIT0: Enable VHT SU Beamformer * BIT1: Enable VHT SU Beamformee @@ -308,6 +316,9 @@ int rtw_bfee_rf_number = 0; /*BeamformeeCapRfNum Rf path number, 0 for auto, ot int rtw_vht_enable = 1; /* 0:disable, 1:enable, 2:force auto enable */ module_param(rtw_vht_enable, int, 0644); +int rtw_vht_24g_enable = 1; /* 0:disable, 1:enable */ +module_param(rtw_vht_24g_enable, int, 0644); + int rtw_ampdu_factor = 7; uint rtw_vht_rx_mcs_map = 0xaaaa; @@ -315,8 +326,6 @@ module_param(rtw_vht_rx_mcs_map, uint, 0644); MODULE_PARM_DESC(rtw_vht_rx_mcs_map, "VHT RX MCS map"); #endif /* CONFIG_80211AC_VHT */ -int rtw_lowrate_two_xmit = 1;/* Use 2 path Tx to transmit MCS0~7 and legacy mode */ - /* 0: not check in watch dog, 1: check in watch dog */ int rtw_check_hw_status = 0; @@ -324,23 +333,37 @@ int rtw_check_hw_status = 0; int rtw_low_power = 0; int rtw_wifi_spec = 0; + +int rtw_trx_path_bmp = 0x00; +module_param(rtw_trx_path_bmp, int, 0644); /* [7:4]TX path bmp, [0:3]RX path bmp, 0: not specified */ + #ifdef CONFIG_SPECIAL_RF_PATH /* configure Nss/xTxR IC to 1ss/1T1R */ -int rtw_rf_path = RF_1T1R; +int rtw_tx_path_lmt = 1; +int rtw_rx_path_lmt = 1; int rtw_tx_nss = 1; int rtw_rx_nss = 1; #elif defined(CONFIG_CUSTOMER01_SMART_ANTENNA) -int rtw_rf_path = RF_2T2R; +int rtw_tx_path_lmt = 2; +int rtw_rx_path_lmt = 2; int rtw_tx_nss = 1; int rtw_rx_nss = 1; #else -int rtw_rf_path = RF_TYPE_MAX; +int rtw_tx_path_lmt = 0; +int rtw_rx_path_lmt = 0; int rtw_tx_nss = 0; int rtw_rx_nss = 0; #endif -module_param(rtw_rf_path, int, 0644); +module_param(rtw_tx_path_lmt, int, 0644); /* limit of TX path number, 0: not specified */ +module_param(rtw_rx_path_lmt, int, 0644); /* limit of RX path number, 0: not specified */ module_param(rtw_tx_nss, int, 0644); module_param(rtw_rx_nss, int, 0644); +#ifdef CONFIG_REGD_SRC_FROM_OS +static uint rtw_regd_src = CONFIG_RTW_REGD_SRC; +module_param(rtw_regd_src, uint, 0644); +MODULE_PARM_DESC(rtw_regd_src, "The default regd source selection, 0:Realtek defined, 1: OS"); +#endif + char rtw_country_unspecified[] = {0xFF, 0xFF, 0x00}; char *rtw_country_code = rtw_country_unspecified; module_param(rtw_country_code, charp, 0644); @@ -410,10 +433,6 @@ int rtw_hw_wps_pbc = 1; int rtw_hw_wps_pbc = 0; #endif -#ifdef CONFIG_TX_MCAST2UNI -int rtw_mc2u_disable = 0; -#endif /* CONFIG_TX_MCAST2UNI */ - #ifdef CONFIG_80211D int rtw_80211d = 0; #endif @@ -492,16 +511,41 @@ char *rtw_initmac = 0; /* temp mac address if users want to use instead of the #endif #ifdef CONFIG_P2P + + #ifdef CONFIG_SEL_P2P_IFACE + int rtw_sel_p2p_iface = CONFIG_SEL_P2P_IFACE; + #else int rtw_sel_p2p_iface = IFACE_ID1; + #endif module_param(rtw_sel_p2p_iface, int, 0644); #endif #endif + #ifdef CONFIG_AP_MODE u8 rtw_bmc_tx_rate = MGN_UNKNOWN; -#endif + +#if CONFIG_RTW_AP_DATA_BMC_TO_UC +int rtw_ap_src_b2u_flags = CONFIG_RTW_AP_SRC_B2U_FLAGS; +module_param(rtw_ap_src_b2u_flags, int, 0644); + +int rtw_ap_fwd_b2u_flags = CONFIG_RTW_AP_FWD_B2U_FLAGS; +module_param(rtw_ap_fwd_b2u_flags, int, 0644); +#endif /* CONFIG_RTW_AP_DATA_BMC_TO_UC */ +#endif /* CONFIG_AP_MODE */ + +#ifdef CONFIG_RTW_MESH +#if CONFIG_RTW_MESH_DATA_BMC_TO_UC +int rtw_msrc_b2u_flags = CONFIG_RTW_MSRC_B2U_FLAGS; +module_param(rtw_msrc_b2u_flags, int, 0644); + +int rtw_mfwd_b2u_flags = CONFIG_RTW_MFWD_B2U_FLAGS; +module_param(rtw_mfwd_b2u_flags, int, 0644); +#endif /* CONFIG_RTW_MESH_DATA_BMC_TO_UC */ +#endif /* CONFIG_RTW_MESH */ + #ifdef RTW_WOW_STA_MIX int rtw_wowlan_sta_mix_mode = 1; #else @@ -533,12 +577,12 @@ module_param(rtw_ampdu_enable, int, 0644); module_param(rtw_rx_stbc, int, 0644); module_param(rtw_rx_ampdu_amsdu, int, 0644); module_param(rtw_tx_ampdu_amsdu, int, 0644); +module_param(rtw_quick_addba_req, int, 0644); #endif /* CONFIG_80211N_HT */ #ifdef CONFIG_BEAMFORMING module_param(rtw_beamform_cap, int, 0644); #endif -module_param(rtw_lowrate_two_xmit, int, 0644); module_param(rtw_power_mgnt, int, 0644); module_param(rtw_smart_ps, int, 0644); @@ -602,10 +646,6 @@ MODULE_PARM_DESC(rtw_fw_mp_bt_file_path, "The path of fw for MP-BT image"); #endif /* CONFIG_MP_INCLUDED */ #endif /* CONFIG_FILE_FWIMG */ -#ifdef CONFIG_TX_MCAST2UNI -module_param(rtw_mc2u_disable, int, 0644); -#endif /* CONFIG_TX_MCAST2UNI */ - #ifdef CONFIG_80211D module_param(rtw_80211d, int, 0644); MODULE_PARM_DESC(rtw_80211d, "Enable 802.11d mechanism"); @@ -646,9 +686,13 @@ MODULE_PARM_DESC(rtw_adaptivity_th_edcca_hl_diff, "th_edcca_hl_diff for Adaptivi #ifdef CONFIG_DFS_MASTER uint rtw_dfs_region_domain = CONFIG_RTW_DFS_REGION_DOMAIN; module_param(rtw_dfs_region_domain, uint, 0644); -MODULE_PARM_DESC(rtw_dfs_region_domain, "0:UNKNOWN, 1:FCC, 2:MKK, 3:ETSI"); +MODULE_PARM_DESC(rtw_dfs_region_domain, "0:NONE, 1:FCC, 2:MKK, 3:ETSI"); #endif +uint rtw_amsdu_mode = RTW_AMSDU_MODE_NON_SPP; +module_param(rtw_amsdu_mode, uint, 0644); +MODULE_PARM_DESC(rtw_amsdu_mode, "0:non-spp, 1:spp, 2:all drop"); + uint rtw_amplifier_type_2g = CONFIG_RTW_AMPLIFIER_TYPE_2G; module_param(rtw_amplifier_type_2g, uint, 0644); MODULE_PARM_DESC(rtw_amplifier_type_2g, "BIT3:2G ext-PA, BIT4:2G ext-LNA"); @@ -757,6 +801,10 @@ module_param_array(rtw_target_tx_pwr_5g_d, int, &rtw_target_tx_pwr_5g_d_num, 064 MODULE_PARM_DESC(rtw_target_tx_pwr_5g_d, "5G target tx power (unit:dBm) of RF path D for each rate section, should match the real calibrate power, -1: undefined"); #endif /* CONFIG_IEEE80211_BAND_5GHZ */ +int rtw_antenna_gain = CONFIG_RTW_ANTENNA_GAIN; +module_param(rtw_antenna_gain, int, 0644); +MODULE_PARM_DESC(rtw_antenna_gain, "Antenna gain in mBi. 0x7FFF: unspecifed"); + #ifdef CONFIG_RTW_TX_NPATH_EN /*0:disable ,1: 2path*/ int rtw_tx_npath_enable = 1; @@ -800,6 +848,10 @@ module_param(rtw_decrypt_phy_file, int, 0644); MODULE_PARM_DESC(rtw_decrypt_phy_file, "Enable Decrypt PHY File"); #endif +uint rtw_recvbuf_nr = NR_RECVBUFF; +module_param(rtw_recvbuf_nr, int, 0644); +MODULE_PARM_DESC(rtw_recvbuf_nr, "Preallocated number of struct recv_buf"); + #ifdef CONFIG_SUPPORT_TRX_SHARED #ifdef DFT_TRX_SHARE_MODE int rtw_trx_share_mode = DFT_TRX_SHARE_MODE; @@ -845,11 +897,6 @@ MODULE_PARM_DESC(rtw_peer_alive_based_preq, "On demand PREQ will reference peer alive status. 0: Off, 1: On"); #endif -int rtw_vht_2g4 = RTW_VHT_2G4; -module_param(rtw_vht_2g4, int, 0644); -MODULE_PARM_DESC(rtw_vht_2g4, "Allow VHT rate on 2.4G channel." \ - "(0 for deny and 1 for allow)"); - int _netdev_open(struct net_device *pnetdev); int netdev_open(struct net_device *pnetdev); static int netdev_close(struct net_device *pnetdev); @@ -943,7 +990,18 @@ module_param(rtw_tdmadig_mode, int, 0644); module_param(rtw_dynamic_tdmadig, int, 0644); #endif/*CONFIG_TDMADIG*/ +/*dynamic RRSR default enable*/ +int rtw_en_dyn_rrsr = 1; +int rtw_rrsr_value = 0xFFFFFFFF; +module_param(rtw_en_dyn_rrsr, int, 0644); +module_param(rtw_rrsr_value, int, 0644); + #ifdef CONFIG_WOWLAN +/* + * 0: disable, 1: enable + */ +uint rtw_wow_enable = 1; +module_param(rtw_wow_enable, uint, 0644); /* * bit[0]: magic packet wake up * bit[1]: unucast packet(HW/FW unuicast) @@ -960,6 +1018,27 @@ uint rtw_suspend_type = RTW_SUSPEND_TYPE; module_param(rtw_suspend_type, uint, 0644); #endif +#ifdef RTW_BUSY_DENY_SCAN +uint rtw_scan_interval_thr = BUSY_TRAFFIC_SCAN_DENY_PERIOD; +module_param(rtw_scan_interval_thr, uint, 0644); +MODULE_PARM_DESC(rtw_scan_interval_thr, "Threshold used to judge if scan " \ + "request comes from scan UI, unit is ms."); +#endif /* RTW_BUSY_DENY_SCAN */ + +#ifdef CONFIG_RTL8822C_XCAP_NEW_POLICY +uint rtw_8822c_xcap_overwrite = 1; +module_param(rtw_8822c_xcap_overwrite, uint, 0644); +#endif + +#ifdef CONFIG_RTW_MULTI_AP +static int rtw_unassoc_sta_mode_of_stype[UNASOC_STA_SRC_NUM] = CONFIG_RTW_UNASOC_STA_MODE_OF_STYPE; +static int rtw_unassoc_sta_mode_of_stype_num = 0; +module_param_array(rtw_unassoc_sta_mode_of_stype, int, &rtw_unassoc_sta_mode_of_stype_num, 0644); + +uint rtw_max_unassoc_sta_cnt = 0; +module_param(rtw_max_unassoc_sta_cnt, uint, 0644); +#endif + #if CONFIG_TX_AC_LIFETIME static void rtw_regsty_load_tx_ac_lifetime(struct registry_priv *regsty) { @@ -973,10 +1052,12 @@ static void rtw_regsty_load_tx_ac_lifetime(struct registry_priv *regsty) conf = ®sty->tx_aclt_confs[i]; if (i == TX_ACLT_CONF_DEFAULT) parm = rtw_tx_aclt_conf_default; - #ifdef CONFIG_TX_MCAST2UNI + #ifdef CONFIG_AP_MODE + #if CONFIG_RTW_AP_DATA_BMC_TO_UC else if (i == TX_ACLT_CONF_AP_M2U) parm = rtw_tx_aclt_conf_ap_m2u; #endif + #endif /* CONFIG_AP_MODE */ #ifdef CONFIG_RTW_MESH else if (i == TX_ACLT_CONF_MESH) parm = rtw_tx_aclt_conf_mesh; @@ -1064,6 +1145,18 @@ inline void rtw_regsty_init_rx_ampdu_sz_limit(struct registry_priv *regsty) } #endif /* CONFIG_80211N_HT */ +#ifdef CONFIG_RTW_MULTI_AP +inline void rtw_regsty_init_unassoc_sta_param(struct registry_priv *regsty) +{ + int i; + + for (i = 0; i < UNASOC_STA_SRC_NUM; i++) + regsty->unassoc_sta_mode_of_stype[i] = rtw_unassoc_sta_mode_of_stype[i]; + + regsty->max_unassoc_sta_cnt = (u16) rtw_max_unassoc_sta_cnt; +} +#endif + uint loadparam(_adapter *padapter) { uint status = _SUCCESS; @@ -1117,6 +1210,8 @@ uint loadparam(_adapter *padapter) registry_par->ips_mode = (u8)rtw_ips_mode; #endif/*CONFIG_TDMADIG*/ registry_par->lps_level = (u8)rtw_lps_level; + registry_par->en_dyn_rrsr = (u8)rtw_en_dyn_rrsr; + registry_par->set_rrsr_value = (u32)rtw_rrsr_value; #ifdef CONFIG_LPS_1T1R registry_par->lps_1t1r = (u8)(rtw_lps_1t1r ? 1 : 0); #endif @@ -1176,6 +1271,7 @@ uint loadparam(_adapter *padapter) registry_par->rx_stbc = (u8)rtw_rx_stbc; registry_par->rx_ampdu_amsdu = (u8)rtw_rx_ampdu_amsdu; registry_par->tx_ampdu_amsdu = (u8)rtw_tx_ampdu_amsdu; + registry_par->tx_quick_addba_req = (u8)rtw_quick_addba_req; registry_par->short_gi = (u8)rtw_short_gi; registry_par->ldpc_cap = (u8)rtw_ldpc_cap; #if defined(CONFIG_CUSTOMER01_SMART_ANTENNA) @@ -1203,6 +1299,7 @@ uint loadparam(_adapter *padapter) #ifdef CONFIG_80211AC_VHT registry_par->vht_enable = (u8)rtw_vht_enable; + registry_par->vht_24g_enable = (u8)rtw_vht_24g_enable; registry_par->ampdu_factor = (u8)rtw_ampdu_factor; registry_par->vht_rx_mcs_map[0] = (u8)(rtw_vht_rx_mcs_map & 0xFF); registry_par->vht_rx_mcs_map[1] = (u8)((rtw_vht_rx_mcs_map & 0xFF00) >> 8); @@ -1211,8 +1308,9 @@ uint loadparam(_adapter *padapter) #ifdef CONFIG_TX_EARLY_MODE registry_par->early_mode = (u8)rtw_early_mode; #endif - registry_par->lowrate_two_xmit = (u8)rtw_lowrate_two_xmit; - registry_par->rf_path = (u8)rtw_rf_path; /*rf_config/rtw_rf_config*/ + registry_par->trx_path_bmp = (u8)rtw_trx_path_bmp; + registry_par->tx_path_lmt = (u8)rtw_tx_path_lmt; + registry_par->rx_path_lmt = (u8)rtw_rx_path_lmt; registry_par->tx_nss = (u8)rtw_tx_nss; registry_par->rx_nss = (u8)rtw_rx_nss; registry_par->low_power = (u8)rtw_low_power; @@ -1221,6 +1319,15 @@ uint loadparam(_adapter *padapter) registry_par->wifi_spec = (u8)rtw_wifi_spec; +#ifdef CONFIG_REGD_SRC_FROM_OS + if (regd_src_is_valid(rtw_regd_src)) + registry_par->regd_src = (u8)rtw_regd_src; + else { + RTW_WARN("%s invalid rtw_regd_src(%u), use REGD_SRC_RTK_PRIV instead\n", __func__, rtw_regd_src); + registry_par->regd_src = REGD_SRC_RTK_PRIV; + } +#endif + if (strlen(rtw_country_code) != 2 || is_alpha(rtw_country_code[0]) == _FALSE || is_alpha(rtw_country_code[1]) == _FALSE @@ -1252,10 +1359,6 @@ uint loadparam(_adapter *padapter) registry_par->drv_ant_band_switch = (u8) rtw_drv_ant_band_switch; registry_par->switch_usb_mode = (u8)rtw_switch_usb_mode; - -#ifdef CONFIG_AUTOSUSPEND - registry_par->usbss_enable = (u8)rtw_enusbss;/* 0:disable,1:enable */ -#endif #ifdef SUPPORT_HW_RFOFF_DETECTED registry_par->hwpdn_mode = (u8)rtw_hwpdn_mode;/* 0:disable,1:enable,2:by EFUSE config */ registry_par->hwpwrp_detect = (u8)rtw_hwpwrp_detect;/* 0:disable,1:enable */ @@ -1301,6 +1404,8 @@ uint loadparam(_adapter *padapter) rtw_regsty_load_target_tx_power(registry_par); + registry_par->antenna_gain = (s16)rtw_antenna_gain; + registry_par->tsf_update_pause_factor = (u8)rtw_tsf_update_pause_factor; registry_par->tsf_update_restore_factor = (u8)rtw_tsf_update_restore_factor; @@ -1351,8 +1456,16 @@ uint loadparam(_adapter *padapter) #ifdef CONFIG_DFS_MASTER registry_par->dfs_region_domain = (u8)rtw_dfs_region_domain; + #ifdef CONFIG_REGD_SRC_FROM_OS + if (rtw_regd_src == REGD_SRC_OS && registry_par->dfs_region_domain != RTW_DFS_REGD_NONE) { + RTW_WARN("%s force disable radar detection capability when regd_src is OS\n", __func__); + registry_par->dfs_region_domain = RTW_DFS_REGD_NONE; + } + #endif #endif + registry_par->amsdu_mode = (u8)rtw_amsdu_mode; + #ifdef CONFIG_MCC_MODE registry_par->en_mcc = (u8)rtw_en_mcc; registry_par->rtw_mcc_ap_bw20_target_tx_tp = (u32)rtw_mcc_ap_bw20_target_tx_tp; @@ -1369,10 +1482,19 @@ uint loadparam(_adapter *padapter) #endif /*CONFIG_MCC_MODE */ #ifdef CONFIG_WOWLAN + registry_par->wowlan_enable = rtw_wow_enable; registry_par->wakeup_event = rtw_wakeup_event; registry_par->suspend_type = rtw_suspend_type; #endif +#if defined(CONFIG_SDIO_HCI) && defined(CONFIG_PREALLOC_RX_SKB_BUFFER) + if (rtw_recvbuf_nr != NR_RECVBUFF) { + RTW_WARN("CONFIG_PREALLOC_RX_SKB_BUFFER && CONFIG_SDIO_HCI, force recvbuf_nr to NR_RECVBUFF(%d)\n", NR_RECVBUFF); + rtw_recvbuf_nr = NR_RECVBUFF; + } +#endif + registry_par->recvbuf_nr = rtw_recvbuf_nr; + #ifdef CONFIG_SUPPORT_TRX_SHARED registry_par->trx_share_mode = rtw_trx_share_mode; #endif @@ -1412,7 +1534,19 @@ uint loadparam(_adapter *padapter) #endif #ifdef CONFIG_AP_MODE registry_par->bmc_tx_rate = rtw_bmc_tx_rate; -#endif + #if CONFIG_RTW_AP_DATA_BMC_TO_UC + registry_par->ap_src_b2u_flags = rtw_ap_src_b2u_flags; + registry_par->ap_fwd_b2u_flags = rtw_ap_fwd_b2u_flags; + #endif +#endif /* CONFIG_AP_MODE */ + +#ifdef CONFIG_RTW_MESH + #if CONFIG_RTW_MESH_DATA_BMC_TO_UC + registry_par->msrc_b2u_flags = rtw_msrc_b2u_flags; + registry_par->mfwd_b2u_flags = rtw_mfwd_b2u_flags; + #endif +#endif /* CONFIG_RTW_MESH */ + #ifdef CONFIG_FW_HANDLE_TXBCN registry_par->fw_tbtt_rpt = rtw_tbtt_rpt; #endif @@ -1422,7 +1556,17 @@ uint loadparam(_adapter *padapter) registry_par->peer_alive_based_preq = rtw_peer_alive_based_preq; #endif - registry_par->vht_2g4 = (u8)rtw_vht_2g4; +#ifdef RTW_BUSY_DENY_SCAN + registry_par->scan_interval_thr = rtw_scan_interval_thr; +#endif + +#ifdef CONFIG_RTL8822C_XCAP_NEW_POLICY + registry_par->rtw_8822c_xcap_overwrite = (u8)rtw_8822c_xcap_overwrite; +#endif + +#ifdef CONFIG_RTW_MULTI_AP + rtw_regsty_init_unassoc_sta_param(registry_par); +#endif return status; } @@ -1459,9 +1603,9 @@ static int rtw_net_set_mac_address(struct net_device *pnetdev, void *addr) } /* if the net_device is linked, it's not permit to modify mac addr */ - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) || - check_fwstate(pmlmepriv, _FW_LINKED) || - check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { + if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) || + check_fwstate(pmlmepriv, WIFI_ASOC_STATE) || + check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)) { RTW_INFO(FUNC_ADPT_FMT": The net_device's is not idle currently\n" , FUNC_ADPT_ARG(padapter)); @@ -1586,36 +1730,29 @@ static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb return rtw_1d_to_queue[skb->priority]; } +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) */ -u16 rtw_recv_select_queue(struct sk_buff *skb) +u16 rtw_os_recv_select_queue(u8 *msdu, enum rtw_rx_llc_hdl llc_hdl) { - struct iphdr *piphdr; - unsigned int dscp; - u16 eth_type; - u32 priority; - u8 *pdata = skb->data; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) + u32 priority = 0; - _rtw_memcpy(ð_type, pdata + (ETH_ALEN << 1), 2); + if (llc_hdl == RTW_RX_LLC_REMOVE) { + u16 eth_type = RTW_GET_BE16(msdu + SNAP_SIZE); - switch (eth_type) { - case htons(ETH_P_IP): + if (eth_type == ETH_P_IP) { + struct iphdr *iphdr = (struct iphdr *)(msdu + SNAP_SIZE + 2); + unsigned int dscp = iphdr->tos & 0xfc; - piphdr = (struct iphdr *)(pdata + ETH_HLEN); - - dscp = piphdr->tos & 0xfc; - - priority = dscp >> 5; - - break; - default: - priority = 0; + priority = dscp >> 5; + } } return rtw_1d_to_queue[priority]; - -} - +#else + return 0; #endif +} static u8 is_rtw_ndev(struct net_device *ndev) { @@ -1860,13 +1997,10 @@ int rtw_os_ndev_alloc(_adapter *adapter) #if defined(CONFIG_IOCTL_CFG80211) if (rtw_cfg80211_ndev_res_alloc(adapter) != _SUCCESS) { rtw_warn_on(1); - goto free_ndev; - } + } else #endif - ret = _SUCCESS; -free_ndev: if (ret != _SUCCESS && ndev) rtw_free_netdev(ndev); exit: @@ -1879,18 +2013,122 @@ void rtw_os_ndev_free(_adapter *adapter) rtw_cfg80211_ndev_res_free(adapter); #endif - /* free the old_pnetdev */ - if (adapter->rereg_nd_name_priv.old_pnetdev) { - rtw_free_netdev(adapter->rereg_nd_name_priv.old_pnetdev); - adapter->rereg_nd_name_priv.old_pnetdev = NULL; - } - if (adapter->pnetdev) { rtw_free_netdev(adapter->pnetdev); adapter->pnetdev = NULL; } } +/* For ethtool +++ */ +#ifdef CONFIG_IOCTL_CFG80211 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 8)) +static void rtw_ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct wireless_dev *wdev = NULL; + _adapter *padapter = NULL; + HAL_DATA_TYPE *hal_data = NULL; + + wdev = dev->ieee80211_ptr; + if (wdev) { + strlcpy(info->driver, wiphy_dev(wdev->wiphy)->driver->name, + sizeof(info->driver)); + } else { + strlcpy(info->driver, "N/A", sizeof(info->driver)); + } + + strlcpy(info->version, DRIVERVERSION, sizeof(info->version)); + + padapter = (_adapter *)rtw_netdev_priv(dev); + if (padapter) { + hal_data = GET_HAL_DATA(padapter); + } + + if (hal_data) { + scnprintf(info->fw_version, sizeof(info->fw_version), "%d.%d", + hal_data->firmware_version, hal_data->firmware_sub_version); + } else { + strlcpy(info->fw_version, "N/A", sizeof(info->fw_version)); + } + + strlcpy(info->bus_info, dev_name(wiphy_dev(wdev->wiphy)), + sizeof(info->bus_info)); +} + +static const char rtw_ethtool_gstrings_sta_stats[][ETH_GSTRING_LEN] = { + "rx_packets", "rx_bytes", "rx_dropped", + "tx_packets", "tx_bytes", "tx_dropped", +}; + +#define RTW_ETHTOOL_STATS_LEN ARRAY_SIZE(rtw_ethtool_gstrings_sta_stats) + +static int rtw_ethtool_get_sset_count(struct net_device *dev, int sset) +{ + int rv = 0; + + if (sset == ETH_SS_STATS) + rv += RTW_ETHTOOL_STATS_LEN; + + if (rv == 0) + return -EOPNOTSUPP; + + return rv; +} + +static void rtw_ethtool_get_strings(struct net_device *dev, u32 sset, u8 *data) +{ + int sz_sta_stats = 0; + + if (sset == ETH_SS_STATS) { + sz_sta_stats = sizeof(rtw_ethtool_gstrings_sta_stats); + memcpy(data, rtw_ethtool_gstrings_sta_stats, sz_sta_stats); + } +} + +static void rtw_ethtool_get_stats(struct net_device *dev, + struct ethtool_stats *stats, + u64 *data) +{ + int i = 0; + _adapter *padapter = NULL; + struct xmit_priv *pxmitpriv = NULL; + struct recv_priv *precvpriv = NULL; + + memset(data, 0, sizeof(u64) * RTW_ETHTOOL_STATS_LEN); + + padapter = (_adapter *)rtw_netdev_priv(dev); + if (padapter) { + pxmitpriv = &(padapter->xmitpriv); + precvpriv = &(padapter->recvpriv); + + data[i++] = precvpriv->rx_pkts; + data[i++] = precvpriv->rx_bytes; + data[i++] = precvpriv->rx_drop; + + data[i++] = pxmitpriv->tx_pkts; + data[i++] = pxmitpriv->tx_bytes; + data[i++] = pxmitpriv->tx_drop; + } else { + data[i++] = 0; + data[i++] = 0; + data[i++] = 0; + + data[i++] = 0; + data[i++] = 0; + data[i++] = 0; + } +} + +static const struct ethtool_ops rtw_ethtool_ops = { + .get_drvinfo = rtw_ethtool_get_drvinfo, + .get_link = ethtool_op_get_link, + .get_strings = rtw_ethtool_get_strings, + .get_ethtool_stats = rtw_ethtool_get_stats, + .get_sset_count = rtw_ethtool_get_sset_count, +}; +#endif // LINUX_VERSION_CODE >= 3.7.8 +#endif /* CONFIG_IOCTL_CFG80211 */ +/* For ethtool --- */ + int rtw_os_ndev_register(_adapter *adapter, const char *name) { struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); @@ -1908,6 +2146,10 @@ int rtw_os_ndev_register(_adapter *adapter, const char *name) ret = _FAIL; goto exit; } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 8)) + netdev_set_default_ethtool_ops(ndev, &rtw_ethtool_ops); +#endif /* LINUX_VERSION_CODE >= 3.7.8 */ #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && defined(CONFIG_PCI_HCI) ndev->gro_flush_timeout = 100000; @@ -1917,10 +2159,6 @@ int rtw_os_ndev_register(_adapter *adapter, const char *name) _rtw_memcpy(ndev->dev_addr, adapter_mac_addr(adapter), ETH_ALEN); - #ifdef CONFIG_NET_NS - dev_net_set(ndev, wiphy_net(adapter_to_wiphy(adapter))); - #endif //CONFIG_NET_NS - /* Tell the network stack we exist */ if (rtnl_lock_needed) @@ -1942,7 +2180,9 @@ int rtw_os_ndev_register(_adapter *adapter, const char *name) } #endif +#if defined(CONFIG_IOCTL_CFG80211) exit: +#endif #ifdef CONFIG_RTW_NAPI if (ret != _SUCCESS) netif_napi_del(&adapter->napi); @@ -2040,8 +2280,7 @@ int rtw_os_ndevs_alloc(struct dvobj_priv *dvobj) #if defined(CONFIG_IOCTL_CFG80211) if (rtw_cfg80211_dev_res_alloc(dvobj) != _SUCCESS) { rtw_warn_on(1); - status = _FAIL; - goto exit; + return _FAIL; } #endif @@ -2081,7 +2320,7 @@ int rtw_os_ndevs_alloc(struct dvobj_priv *dvobj) if (status != _SUCCESS) rtw_cfg80211_dev_res_free(dvobj); #endif -exit: + return status; } @@ -2250,9 +2489,7 @@ u8 rtw_init_default_value(_adapter *padapter) psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; psecuritypriv->ndisencryptstatus = Ndis802_11WEPDisabled; -#ifdef CONFIG_CONCURRENT_MODE psecuritypriv->dot118021x_bmc_cam_id = INVALID_SEC_MAC_CAM_ID; -#endif /* pwrctrl_priv */ @@ -2289,6 +2526,10 @@ u8 rtw_init_default_value(_adapter *padapter) padapter->rsvd_page_num = 0; #ifdef CONFIG_AP_MODE padapter->bmc_tx_rate = pregistrypriv->bmc_tx_rate; + #if CONFIG_RTW_AP_DATA_BMC_TO_UC + padapter->b2u_flags_ap_src = pregistrypriv->ap_src_b2u_flags; + padapter->b2u_flags_ap_fwd = pregistrypriv->ap_fwd_b2u_flags; + #endif #endif padapter->driver_tx_bw_mode = pregistrypriv->tx_bw_mode; @@ -2324,6 +2565,13 @@ u8 rtw_init_default_value(_adapter *padapter) else rtw_nm_disable(padapter); #endif + +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + ATOMIC_SET(&padapter->tbtx_tx_pause, _FALSE); + ATOMIC_SET(&padapter->tbtx_remove_tx_pause, _FALSE); + padapter->tbtx_capability = _TRUE; +#endif + return ret; } #ifdef CONFIG_CLIENT_PORT_CFG @@ -2375,7 +2623,7 @@ struct dvobj_priv *devobj_init(void) #endif _rtw_spinlock_init(&pdvobj->cam_ctl.lock); _rtw_mutex_init(&pdvobj->cam_ctl.sec_cam_access_mutex); -#if defined(RTK_129X_PLATFORM) && defined(CONFIG_PCI_HCI) +#if defined(CONFIG_PLATFORM_RTK129X) && defined(CONFIG_PCI_HCI) _rtw_spinlock_init(&pdvobj->io_reg_lock); #endif #ifdef CONFIG_MBSSID_CAM @@ -2472,7 +2720,7 @@ void devobj_deinit(struct dvobj_priv *pdvobj) _rtw_spinlock_free(&pdvobj->cam_ctl.lock); _rtw_mutex_free(&pdvobj->cam_ctl.sec_cam_access_mutex); -#if defined(RTK_129X_PLATFORM) && defined(CONFIG_PCI_HCI) +#if defined(CONFIG_PLATFORM_RTK129X) && defined(CONFIG_PCI_HCI) _rtw_spinlock_free(&pdvobj->io_reg_lock); #endif #ifdef CONFIG_MBSSID_CAM @@ -2541,13 +2789,7 @@ u8 rtw_reset_drv_sw(_adapter *padapter) pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0; pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0; - _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING); - -#ifdef CONFIG_AUTOSUSPEND -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)) - adapter_to_dvobj(padapter)->pusbdev->autosuspend_disabled = 1;/* autosuspend disabled by the user */ -#endif -#endif + _clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING); #ifdef DBG_CONFIG_ERROR_DETECT if (is_primary_adapter(padapter)) @@ -2593,13 +2835,19 @@ u8 rtw_init_drv_sw(_adapter *padapter) struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); dvobj->macid_ctl.num = rtw_min(hal_spec->macid_num, MACID_NUM_SW_LIMIT); - dvobj->macid_ctl.macid_cap = hal_spec->macid_cap; dvobj->macid_ctl.macid_txrpt = hal_spec->macid_txrpt; dvobj->macid_ctl.macid_txrpt_pgsz = hal_spec->macid_txrpt_pgsz; dvobj->cam_ctl.sec_cap = hal_spec->sec_cap; dvobj->cam_ctl.num = rtw_min(hal_spec->sec_cam_ent_num, SEC_CAM_ENT_NUM_SW_LIMIT); + + dvobj->wow_ctl.wow_cap = hal_spec->wow_cap; + #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT + dvobj->tx_aval_int_thr_mode = 2; /*setting by max tx length*/ + dvobj->tx_aval_int_thr_value = 0; + #endif /*CONFIG_SDIO_TX_ENABLE_AVAL_INT*/ + #if CONFIG_TX_AC_LIFETIME { struct registry_priv *regsty = adapter_to_regsty(padapter); @@ -2621,6 +2869,9 @@ u8 rtw_init_drv_sw(_adapter *padapter) dvobj->tx_aclt_force_val.en = 0xFF; } #endif + #if defined (CONFIG_CONCURRENT_MODE) && defined (CONFIG_TSF_SYNC) + dvobj->sync_tsfr_counter = 0x0; + #endif } ret8 = rtw_init_default_value(padapter); @@ -2637,9 +2888,6 @@ u8 rtw_init_drv_sw(_adapter *padapter) goto exit; } - if (is_primary_adapter(padapter)) - rtw_rfctl_init(padapter); - if (is_primary_adapter(padapter)) { if (rtw_hal_rfpath_init(padapter) == _FAIL) { ret8 = _FAIL; @@ -2649,6 +2897,14 @@ u8 rtw_init_drv_sw(_adapter *padapter) ret8 = _FAIL; goto exit; } + if (rtw_hal_runtime_trx_path_decision(padapter) == _FAIL) { + ret8 = _FAIL; + goto exit; + } + if (rtw_rfctl_init(padapter) == _FAIL) { + ret8 = _FAIL; + goto exit; + } } if (rtw_init_mlme_priv(padapter) == _FAIL) { @@ -2656,13 +2912,14 @@ u8 rtw_init_drv_sw(_adapter *padapter) goto exit; } +#if (defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)) || defined(CONFIG_IOCTL_CFG80211) + rtw_init_roch_info(padapter); +#endif + #ifdef CONFIG_P2P rtw_init_wifidirect_timers(padapter); init_wifidirect_info(padapter, P2P_ROLE_DISABLE); reset_global_wifidirect_info(padapter); - #ifdef CONFIG_IOCTL_CFG80211 - rtw_init_cfg80211_wifidirect_info(padapter); - #endif #ifdef CONFIG_WFD if (rtw_init_wifi_display_info(padapter) == _FAIL) RTW_ERR("Can't init init_wifi_display_info\n"); @@ -2736,6 +2993,10 @@ u8 rtw_init_drv_sw(_adapter *padapter) #endif rtw_hal_dm_init(padapter); + + if (is_primary_adapter(padapter)) + rtw_rfctl_chplan_init(padapter); + #ifdef CONFIG_RTW_SW_LED rtw_hal_sw_led_init(padapter); #endif @@ -2812,9 +3073,7 @@ void rtw_cancel_all_timer(_adapter *padapter) #endif #ifdef CONFIG_IOCTL_CFG80211 -#ifdef CONFIG_P2P - _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer); -#endif /* CONFIG_P2P */ + _cancel_timer_ex(&padapter->rochinfo.remain_on_ch_timer); #endif /* CONFIG_IOCTL_CFG80211 */ #ifdef CONFIG_SET_SCAN_DENY_TIMER @@ -2830,6 +3089,11 @@ void rtw_cancel_all_timer(_adapter *padapter) _cancel_timer_ex(&(adapter_to_pwrctl(padapter)->pwr_rpwm_timer)); #endif /* CONFIG_LPS_RPWM_TIMER */ +#ifdef CONFIG_RTW_TOKEN_BASED_XMIT + _cancel_timer_ex(&padapter->mlmeextpriv.tbtx_xmit_timer); + _cancel_timer_ex(&padapter->mlmeextpriv.tbtx_token_dispatch_timer); +#endif + /* cancel dm timer */ rtw_hal_dm_deinit(padapter); @@ -2851,12 +3115,15 @@ u8 rtw_free_drv_sw(_adapter *padapter) #ifdef CONFIG_P2P { struct wifidirect_info *pwdinfo = &padapter->wdinfo; + #ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; + #endif if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { _cancel_timer_ex(&pwdinfo->find_phase_timer); _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer); _cancel_timer_ex(&pwdinfo->pre_tx_scan_timer); #ifdef CONFIG_CONCURRENT_MODE - _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer); + _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer); #endif /* CONFIG_CONCURRENT_MODE */ rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE); } @@ -2898,6 +3165,13 @@ u8 rtw_free_drv_sw(_adapter *padapter) rtw_free_pwrctrl_priv(padapter); +#ifdef CONFIG_PLATFORM_CMAP_INTFS + if (padapter->cmap_bss_status_evt) { + cmap_intfs_mfree(padapter->cmap_bss_status_evt, padapter->cmap_bss_status_evt_len); + padapter->cmap_bss_status_evt = NULL; + } +#endif + /* rtw_mfree((void *)padapter, sizeof (padapter)); */ rtw_hal_free_data(padapter); @@ -2909,11 +3183,13 @@ void rtw_intf_start(_adapter *adapter) { if (adapter->intf_start) adapter->intf_start(adapter); + GET_HAL_DATA(adapter)->intf_start = 1; } void rtw_intf_stop(_adapter *adapter) { if (adapter->intf_stop) adapter->intf_stop(adapter); + GET_HAL_DATA(adapter)->intf_start = 0; } #ifdef CONFIG_CONCURRENT_MODE @@ -2978,7 +3254,6 @@ int _netdev_vir_if_open(struct net_device *pnetdev) #endif #ifdef CONFIG_IOCTL_CFG80211 - rtw_cfg80211_init_wiphy(padapter); rtw_cfg80211_init_wdev_data(padapter); #endif @@ -3100,6 +3375,10 @@ _adapter *rtw_drv_add_vir_if(_adapter *primary_padapter, _adapter *padapter = NULL; struct dvobj_priv *pdvobjpriv; u8 mac[ETH_ALEN]; +#ifdef CONFIG_MI_UNIQUE_MACADDR_BIT + u32 mi_unique_macaddr_bit = 0; + u8 i; +#endif /****** init adapter ******/ padapter = (_adapter *)rtw_zvmalloc(sizeof(*padapter)); @@ -3123,6 +3402,8 @@ _adapter *rtw_drv_add_vir_if(_adapter *primary_padapter, #ifdef CONFIG_MI_WITH_MBSSID_CAM padapter->hw_port = HW_PORT0; +#elif defined(CONFIG_PORT_BASED_TXBCN) + padapter->hw_port = adapter_to_dvobj(padapter)->iface_nums; #else padapter->hw_port = HW_PORT1; #endif @@ -3149,13 +3430,35 @@ _adapter *rtw_drv_add_vir_if(_adapter *primary_padapter, /*get mac address from primary_padapter*/ _rtw_memcpy(mac, adapter_mac_addr(primary_padapter), ETH_ALEN); +#ifdef CONFIG_MI_UNIQUE_MACADDR_BIT + mi_unique_macaddr_bit = BIT(CONFIG_MI_UNIQUE_MACADDR_BIT) >> 24; + /* Find out CONFIG_MI_UNIQUE_MACADDR_BIT in which nic specific byte */ + for(i=3;i<6;i++) { + if((mi_unique_macaddr_bit >> 8) == 0) + break; + + mi_unique_macaddr_bit >>= 8; + } + + if((mac[i] & (u8)mi_unique_macaddr_bit)== 0) { + RTW_INFO("%s() "MAC_FMT" : BIT%u is zero\n", __func__, MAC_ARG(mac), CONFIG_MI_UNIQUE_MACADDR_BIT); + /* IFACE_ID1/IFACE_ID3 : set locally administered bit */ + if(padapter->iface_id & BIT(0)) + mac[0] |= BIT(1); + /* IFACE_ID2/IFACE_ID3 : set bit(CONFIG_MI_UNIQUE_MACADDR_BIT) */ + if(padapter->iface_id >> 1) + mac[i] |= (u8)mi_unique_macaddr_bit; + } else +#endif + { /* * If the BIT1 is 0, the address is universally administered. * If it is 1, the address is locally administered */ mac[0] |= BIT(1); if (padapter->iface_id > IFACE_ID1) - mac[4] ^= BIT(padapter->iface_id); + mac[0] ^= ((padapter->iface_id)<<2); + } _rtw_memcpy(adapter_mac_addr(padapter), mac, ETH_ALEN); /* update mac-address to mbsid-cam cache*/ @@ -3195,7 +3498,7 @@ void rtw_drv_stop_vir_if(_adapter *padapter) pnetdev = padapter->pnetdev; - if (check_fwstate(pmlmepriv, _FW_LINKED)) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) rtw_disassoc_cmd(padapter, 0, RTW_CMDF_DIRECTLY); #ifdef CONFIG_AP_MODE @@ -3399,8 +3702,7 @@ int rtw_os_ndevs_register(struct dvobj_priv *dvobj) #if defined(CONFIG_IOCTL_CFG80211) if (rtw_cfg80211_dev_res_register(dvobj) != _SUCCESS) { rtw_warn_on(1); - status = _FAIL; - goto exit; + return _FAIL; } #endif @@ -3449,7 +3751,6 @@ int rtw_os_ndevs_register(struct dvobj_priv *dvobj) if (status != _SUCCESS) rtw_cfg80211_dev_res_unregister(dvobj); #endif -exit: return status; } @@ -3558,13 +3859,6 @@ int _netdev_open(struct net_device *pnetdev) RTW_INFO(FUNC_NDEV_FMT" start\n", FUNC_NDEV_ARG(pnetdev)); - #ifdef CONFIG_AUTOSUSPEND - if (pwrctrlpriv->ps_flag == _TRUE) { - padapter->net_closed = _FALSE; - goto netdev_open_normal_process; - } - #endif /*CONFIG_AUTOSUSPEND*/ - if (!rtw_is_hw_init_completed(padapter)) { // ips rtw_clr_surprise_removed(padapter); rtw_clr_drv_stopped(padapter); @@ -3616,7 +3910,6 @@ int _netdev_open(struct net_device *pnetdev) #endif #ifdef CONFIG_IOCTL_CFG80211 - rtw_cfg80211_init_wiphy(padapter); rtw_cfg80211_init_wdev_data(padapter); #endif /* rtw_netif_carrier_on(pnetdev); */ /* call this func when rtw_joinbss_event_callback return success */ @@ -3634,9 +3927,6 @@ int _netdev_open(struct net_device *pnetdev) pwrctrlpriv->bips_processing = _FALSE; } -#ifdef CONFIG_AUTOSUSPEND -netdev_open_normal_process: -#endif RTW_INFO(FUNC_NDEV_FMT" Success (bup=%d)\n", FUNC_NDEV_ARG(pnetdev), padapter->bup); return 0; @@ -3678,13 +3968,6 @@ int _netdev_open(struct net_device *pnetdev) rtw_sdio_set_power(1); #endif /* CONFIG_PLATFORM_INTEL_BYT */ - #ifdef CONFIG_AUTOSUSPEND - if (pwrctrlpriv->ps_flag == _TRUE) { - padapter->net_closed = _FALSE; - goto netdev_open_normal_process; - } - #endif - if (padapter->bup == _FALSE) { #ifdef CONFIG_PLATFORM_INTEL_BYT rtw_macaddr_cfg(adapter_mac_addr(padapter), get_hal_mac_addr(padapter)); @@ -3728,7 +4011,6 @@ int _netdev_open(struct net_device *pnetdev) #endif /* !RTW_HALMAC */ #ifdef CONFIG_IOCTL_CFG80211 - rtw_cfg80211_init_wiphy(padapter); rtw_cfg80211_init_wdev_data(padapter); #endif @@ -3767,10 +4049,6 @@ int _netdev_open(struct net_device *pnetdev) RTW_INFO("CONFIG_BT_COEXIST: VIRTUAL_ADAPTER\n"); #endif /* CONFIG_BT_COEXIST_SOCKET_TRX */ -#ifdef CONFIG_AUTOSUSPEND -netdev_open_normal_process: -#endif - #ifdef CONFIG_CONCURRENT_MODE { _adapter *sec_adapter = adapter_to_dvobj(padapter)->padapters[IFACE_ID1]; @@ -3782,7 +4060,7 @@ netdev_open_normal_process: } #endif -#ifdef CONFIG_RTW_CFGVEDNOR_LLSTATS +#ifdef CONFIG_RTW_CFGVENDOR_LLSTATS pwrctrlpriv->radio_on_start_time = rtw_get_current_time(); pwrctrlpriv->pwr_saving_start_time = rtw_get_current_time(); pwrctrlpriv->pwr_saving_time = 0; @@ -3969,13 +4247,6 @@ int _pm_netdev_open(_adapter *padapter) RTW_INFO(FUNC_NDEV_FMT" start\n", FUNC_NDEV_ARG(pnetdev)); - #ifdef CONFIG_AUTOSUSPEND - if (pwrctrlpriv->ps_flag == _TRUE) { - padapter->net_closed = _FALSE; - goto netdev_open_normal_process; - } - #endif /*CONFIG_AUTOSUSPEND*/ - if (!rtw_is_hw_init_completed(padapter)) { // ips rtw_clr_surprise_removed(padapter); rtw_clr_drv_stopped(padapter); @@ -4013,9 +4284,6 @@ int _pm_netdev_open(_adapter *padapter) pwrctrlpriv->bips_processing = _FALSE; } -#ifdef CONFIG_AUTOSUSPEND -netdev_open_normal_process: -#endif RTW_INFO(FUNC_NDEV_FMT" Success (bup=%d)\n", FUNC_NDEV_ARG(pnetdev), padapter->bup); return 0; @@ -4088,13 +4356,6 @@ static int netdev_close(struct net_device *pnetdev) RTW_INFO(FUNC_NDEV_FMT" , bup=%d\n", FUNC_NDEV_ARG(pnetdev), padapter->bup); #ifndef CONFIG_PLATFORM_INTEL_BYT - #ifdef CONFIG_AUTOSUSPEND - if (pwrctl->bInternalAutoSuspend == _TRUE) { - /* rtw_pwr_wakeup(padapter); */ - if (pwrctl->rf_pwrstate == rf_off) - pwrctl->ps_flag = _TRUE; - } - #endif padapter->net_closed = _TRUE; padapter->netif_up = _FALSE; pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE; @@ -4118,7 +4379,7 @@ static int netdev_close(struct net_device *pnetdev) if (pnetdev) rtw_netif_stop_queue(pnetdev); -#ifndef CONFIG_ANDROID +#ifndef CONFIG_RTW_ANDROID /* s2. */ LeaveAllPowerSaveMode(padapter); rtw_disassoc_cmd(padapter, 500, RTW_CMDF_WAIT_ACK); @@ -4257,9 +4518,7 @@ static int route_dump(u32 *gw_addr , int *gw_index) struct msghdr msg; struct iovec iov; struct sockaddr_nl nladdr; - #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) mm_segment_t oldfs; - #endif char *pg; int size = 0; @@ -4298,18 +4557,14 @@ static int route_dump(u32 *gw_addr , int *gw_index) msg.msg_controllen = 0; msg.msg_flags = MSG_DONTWAIT; - #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) oldfs = get_fs(); set_fs(KERNEL_DS); - #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) err = sock_sendmsg(sock, &msg); #else err = sock_sendmsg(sock, &msg, sizeof(req)); #endif - #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) set_fs(oldfs); - #endif if (err < 0) goto out_sock; @@ -4334,18 +4589,14 @@ restart: iov_iter_init(&msg.msg_iter, READ, &iov, 1, PAGE_SIZE); #endif - #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) oldfs = get_fs(); set_fs(KERNEL_DS); - #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) err = sock_recvmsg(sock, &msg, MSG_DONTWAIT); #else err = sock_recvmsg(sock, &msg, PAGE_SIZE, MSG_DONTWAIT); #endif - #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) set_fs(oldfs); - #endif if (err < 0) goto out_sock_pg; @@ -4416,18 +4667,14 @@ done: msg.msg_controllen = 0; msg.msg_flags = MSG_DONTWAIT; - #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) oldfs = get_fs(); set_fs(KERNEL_DS); - #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) err = sock_sendmsg(sock, &msg); #else err = sock_sendmsg(sock, &msg, sizeof(req)); #endif - #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) set_fs(oldfs); - #endif if (err > 0) goto restart; @@ -4530,7 +4777,7 @@ void rtw_dev_unload(PADAPTER padapter) #ifdef CONFIG_GPIO_WAKEUP /*default wake up pin change to BT*/ RTW_INFO("%s:default wake up pin change to BT\n", __FUNCTION__); - rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _FALSE); + rtw_hal_switch_gpio_wl_ctrl(padapter, pwrctl->wowlan_gpio_index, _FALSE); #endif /* CONFIG_GPIO_WAKEUP */ #endif /* CONFIG_WOWLAN */ @@ -4541,18 +4788,14 @@ void rtw_dev_unload(PADAPTER padapter) #endif rtw_intf_stop(padapter); + + rtw_stop_drv_threads(padapter); - #ifdef CONFIG_AUTOSUSPEND - if (!pwrctl->bInternalAutoSuspend) - #endif - { - rtw_stop_drv_threads(padapter); - - if (ATOMIC_READ(&(pcmdpriv->cmdthd_running)) == _TRUE) { - RTW_ERR("cmd_thread not stop !!\n"); - rtw_warn_on(1); - } + if (ATOMIC_READ(&(pcmdpriv->cmdthd_running)) == _TRUE) { + RTW_ERR("cmd_thread not stop !!\n"); + rtw_warn_on(1); } + /* check the status of IPS */ if (rtw_hal_check_ips_status(padapter) == _TRUE || pwrctl->rf_pwrstate == rf_off) { /* check HW status and SW state */ RTW_PRINT("%s: driver in IPS-FWLPS\n", __func__); @@ -4597,7 +4840,7 @@ int rtw_suspend_free_assoc_resource(_adapter *padapter) if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) { if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) - && check_fwstate(pmlmepriv, _FW_LINKED) + && check_fwstate(pmlmepriv, WIFI_ASOC_STATE) #ifdef CONFIG_P2P && (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) #if defined(CONFIG_IOCTL_CFG80211) && RTW_P2P_GROUP_INTERFACE @@ -4615,7 +4858,7 @@ int rtw_suspend_free_assoc_resource(_adapter *padapter) } } - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED)) { + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) { rtw_disassoc_cmd(padapter, 0, RTW_CMDF_DIRECTLY); /* s2-2. indicate disconnect to os */ rtw_indicate_disconnect(padapter, 0, _FALSE); @@ -4629,18 +4872,15 @@ int rtw_suspend_free_assoc_resource(_adapter *padapter) rtw_free_assoc_resources(padapter, _TRUE); /* s2-4. */ -#ifdef CONFIG_AUTOSUSPEND - if (is_primary_adapter(padapter) && (!adapter_to_pwrctl(padapter)->bInternalAutoSuspend)) -#endif - rtw_free_network_queue(padapter, _TRUE); + rtw_free_network_queue(padapter, _TRUE); - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)) { RTW_PRINT("%s: fw_under_survey\n", __func__); rtw_indicate_scan_done(padapter, 1); - clr_fwstate(pmlmepriv, _FW_UNDER_SURVEY); + clr_fwstate(pmlmepriv, WIFI_UNDER_SURVEY); } - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE) { RTW_PRINT("%s: fw_under_linking\n", __FUNCTION__); rtw_indicate_disconnect(padapter, 0, _FALSE); } @@ -4657,6 +4897,11 @@ int rtw_suspend_wow(_adapter *padapter) struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); struct wowlan_ioctl_param poidparam; int ret = _SUCCESS; + u8 en = _TRUE, i; + struct registry_priv *registry_par = &padapter->registrypriv; + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + _adapter *iface = NULL; + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); RTW_INFO("==> "FUNC_ADPT_FMT" entry....\n", FUNC_ADPT_ARG(padapter)); @@ -4683,7 +4928,28 @@ int rtw_suspend_wow(_adapter *padapter) /* 2.1 clean interrupt */ rtw_hal_clear_interrupt(padapter); #endif /* CONFIG_SDIO_HCI */ - + + /* enable ac lifetime during scan to avoid txfifo not empty. */ + dvobj->lifetime_en = rtw_read8(padapter, 0x426); + dvobj->pkt_lifetime = rtw_read32(padapter, 0x4c0); + rtw_write8(padapter, 0x426, rtw_read8(padapter, 0x426) | 0x0f); + if(hal_spec->tx_aclt_unit_factor == 1) { + rtw_write16(padapter, 0x4c0, 0x1000); // unit: 32us. 131ms + rtw_write16(padapter, 0x4c0 + 2 , 0x1000); // unit: 32us. 131ms + } else { + rtw_write16(padapter, 0x4c0, 0x0200); // unit: 256us. 131ms + rtw_write16(padapter, 0x4c0 + 2 , 0x0200); // unit: 256us. 131ms + } + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if ((iface) && rtw_is_adapter_up(iface)) { + rtw_write_port_cancel(iface); + RTW_INFO(ADPT_FMT " write port cancel\n", ADPT_ARG(iface)); + } + } + RTW_INFO("lifetime_en=%x, pkt_lifetime=%x\n", rtw_read8(padapter, 0x426), rtw_read32(padapter, 0x4c0)); + rtw_msleep_os(200); + /* 1. stop thread */ rtw_set_drv_stopped(padapter); /*for stop thread*/ rtw_mi_stop_drv_threads(padapter); @@ -4707,13 +4973,16 @@ int rtw_suspend_wow(_adapter *padapter) rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL); } #endif - + if(registry_par->suspend_type == FW_IPS_WRC) + rtw_hal_set_hwreg(padapter, HW_VAR_VENDOR_WOW_MODE, &en); +#ifdef CONFIG_LPS rtw_wow_lps_level_decide(padapter, _TRUE); +#endif poidparam.subcode = WOWLAN_ENABLE; rtw_hal_set_hwreg(padapter, HW_VAR_WOWLAN, (u8 *)&poidparam); if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) { if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) - && check_fwstate(pmlmepriv, _FW_LINKED)) { + && check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) { RTW_INFO("%s %s(" MAC_FMT "), length:%d assoc_ssid.length:%d\n", __FUNCTION__, pmlmepriv->cur_network.network.Ssid.Ssid, MAC_ARG(pmlmepriv->cur_network.network.MacAddress), @@ -4726,13 +4995,12 @@ int rtw_suspend_wow(_adapter *padapter) RTW_PRINT("%s: wowmode suspending\n", __func__); - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE) { RTW_PRINT("%s: fw_under_survey\n", __func__); rtw_indicate_scan_done(padapter, 1); - clr_fwstate(pmlmepriv, _FW_UNDER_SURVEY); + clr_fwstate(pmlmepriv, WIFI_UNDER_SURVEY); } -#if 1 if (rtw_mi_check_status(padapter, MI_LINKED)) { ch = rtw_mi_get_union_chan(padapter); bw = rtw_mi_get_union_bw(padapter); @@ -4741,14 +5009,7 @@ int rtw_suspend_wow(_adapter *padapter) FUNC_ADPT_ARG(padapter), ch, bw, offset); set_channel_bwmode(padapter, ch, offset, bw); } -#else - if (rtw_mi_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { - RTW_INFO(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", - FUNC_ADPT_ARG(padapter), ch, bw, offset); - set_channel_bwmode(padapter, ch, offset, bw); - rtw_mi_update_union_chan_inf(padapter, ch, offset, bw); - } -#endif + #ifdef CONFIG_CONCURRENT_MODE rtw_mi_buddy_suspend_free_assoc_resource(padapter); #endif @@ -4830,7 +5091,7 @@ int rtw_suspend_ap_wow(_adapter *padapter) rtw_hal_set_hwreg(padapter, HW_VAR_WOWLAN, (u8 *)&poidparam); RTW_PRINT("%s: wowmode suspending\n", __func__); -#if 1 + if (rtw_mi_check_status(padapter, MI_LINKED)) { ch = rtw_mi_get_union_chan(padapter); bw = rtw_mi_get_union_bw(padapter); @@ -4838,13 +5099,6 @@ int rtw_suspend_ap_wow(_adapter *padapter) RTW_INFO("back to linked/linking union - ch:%u, bw:%u, offset:%u\n", ch, bw, offset); set_channel_bwmode(padapter, ch, offset, bw); } -#else - if (rtw_mi_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { - RTW_INFO("back to linked/linking union - ch:%u, bw:%u, offset:%u\n", ch, bw, offset); - set_channel_bwmode(padapter, ch, offset, bw); - rtw_mi_update_union_chan_inf(padapter, ch, offset, bw); - } -#endif /*FOR ONE AP - TODO :Multi-AP*/ { @@ -4875,7 +5129,7 @@ int rtw_suspend_ap_wow(_adapter *padapter) RTW_INFO("<== "FUNC_ADPT_FMT" exit....\n", FUNC_ADPT_ARG(padapter)); return ret; } -#endif /* #ifdef CONFIG_AP_WOWLAN */ +#endif /* CONFIG_AP_WOWLAN */ int rtw_suspend_normal(_adapter *padapter) @@ -4924,6 +5178,7 @@ int rtw_suspend_common(_adapter *padapter) struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); #ifdef CONFIG_WOWLAN struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct registry_priv *registry_par = &padapter->registrypriv; #endif int ret = 0; @@ -4966,7 +5221,9 @@ int rtw_suspend_common(_adapter *padapter) if (rtw_mi_check_status(padapter, MI_AP_MODE) == _FALSE) { #ifdef CONFIG_WOWLAN - if (check_fwstate(pmlmepriv, _FW_LINKED) || WOWLAN_IS_STA_MIX_MODE(padapter)) + if (WOWLAN_IS_STA_MIX_MODE(padapter)) + pwrpriv->wowlan_mode = _TRUE; + else if ( registry_par->wowlan_enable && check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) pwrpriv->wowlan_mode = _TRUE; else if (pwrpriv->wowlan_pno_enable == _TRUE) pwrpriv->wowlan_mode |= pwrpriv->wowlan_pno_enable; @@ -5015,6 +5272,7 @@ int rtw_resume_process_wow(_adapter *padapter) struct sta_info *psta = NULL; struct registry_priv *registry_par = &padapter->registrypriv; int ret = _SUCCESS; + u8 en = _FALSE; RTW_INFO("==> "FUNC_ADPT_FMT" entry....\n", FUNC_ADPT_ARG(padapter)); @@ -5050,6 +5308,9 @@ int rtw_resume_process_wow(_adapter *padapter) } #endif /* CONFIG_LPS */ + rtw_write8(padapter, 0x426, psdpriv->lifetime_en); + rtw_write32(padapter, 0x4c0, psdpriv->pkt_lifetime); + pwrpriv->bFwCurrentInPSMode = _FALSE; #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_PCI_HCI) @@ -5081,12 +5342,15 @@ int rtw_resume_process_wow(_adapter *padapter) rtw_clr_drv_stopped(padapter); RTW_INFO("%s: wowmode resuming, DriverStopped:%s\n", __func__, rtw_is_drv_stopped(padapter) ? "True" : "False"); - + + if(registry_par->suspend_type == FW_IPS_WRC) + rtw_hal_set_hwreg(padapter, HW_VAR_VENDOR_WOW_MODE, &en); + rtw_mi_start_drv_threads(padapter); rtw_mi_intf_start(padapter); - if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, _FW_LINKED)) { + if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) { if (!rtw_is_surprise_removed(padapter)) { rtw_hal_deinit(padapter); rtw_hal_init(padapter); @@ -5221,7 +5485,6 @@ int rtw_resume_process_ap_wow(_adapter *padapter) rtw_mi_start_drv_threads(padapter); -#if 1 if (rtw_mi_check_status(padapter, MI_LINKED)) { ch = rtw_mi_get_union_chan(padapter); bw = rtw_mi_get_union_bw(padapter); @@ -5229,13 +5492,6 @@ int rtw_resume_process_ap_wow(_adapter *padapter) RTW_INFO(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", FUNC_ADPT_ARG(padapter), ch, bw, offset); set_channel_bwmode(padapter, ch, offset, bw); } -#else - if (rtw_mi_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { - RTW_INFO(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", FUNC_ADPT_ARG(padapter), ch, bw, offset); - set_channel_bwmode(padapter, ch, offset, bw); - rtw_mi_update_union_chan_inf(padapter, ch, offset, bw); - } -#endif /*FOR ONE AP - TODO :Multi-AP*/ { @@ -5246,7 +5502,7 @@ int rtw_resume_process_ap_wow(_adapter *padapter) for (i = 0; i < dvobj->iface_nums; i++) { iface = dvobj->padapters[i]; if ((iface) && rtw_is_adapter_up(iface)) { - if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE | WIFI_MESH_STATE | _FW_LINKED)) + if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE | WIFI_MESH_STATE | WIFI_ASOC_STATE)) rtw_reset_drv_sw(iface); } } @@ -5307,10 +5563,14 @@ void rtw_mi_resume_process_normal(_adapter *padapter) if (rtw_chk_roam_flags(iface, RTW_ROAM_ON_RESUME)) rtw_roaming(iface, NULL); - } else if (MLME_IS_AP(iface) || MLME_IS_MESH(iface)) { + } +#ifdef CONFIG_AP_MODE + else if (MLME_IS_AP(iface) || MLME_IS_MESH(iface)) { RTW_INFO(FUNC_ADPT_FMT" %s\n", FUNC_ADPT_ARG(iface), MLME_IS_AP(iface) ? "AP" : "MESH"); rtw_ap_restore_network(iface); - } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) + } +#endif + else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_ADHOC_STATE\n", FUNC_ADPT_ARG(iface), get_fwstate(pmlmepriv)); else RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - ???\n", FUNC_ADPT_ARG(iface), get_fwstate(pmlmepriv)); diff --git a/os_dep/linux/recv_linux.c b/os_dep/linux/recv_linux.c index ece18f5..13cd766 100644 --- a/os_dep/linux/recv_linux.c +++ b/os_dep/linux/recv_linux.c @@ -208,8 +208,52 @@ void rtw_os_recv_resource_free(struct recv_priv *precvpriv) } } +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +#if !defined(CONFIG_RTL8822B) && !defined(CONFIG_RTL8822C) +#ifdef CONFIG_SDIO_RX_COPY +static int sdio_init_recvbuf_with_skb(struct recv_priv *recvpriv, struct recv_buf *rbuf, u32 size) +{ +#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER + if (RBUF_IS_PREALLOC(rbuf)) { + rbuf->pskb = rtw_alloc_skb_premem(size); + if (!rbuf->pskb) { + RTW_WARN("%s: Fail to get pre-alloc skb! size=%d\n", __func__, size); + return _FAIL; + } + skb_set_tail_pointer(rbuf->pskb, 0); /* TODO: do this in RTKM */ + } else +#else + { + SIZE_PTR tmpaddr = 0; + SIZE_PTR alignment = 0; + + rbuf->pskb = rtw_skb_alloc(size + RECVBUFF_ALIGN_SZ); + if (!rbuf->pskb) + return _FAIL; + + tmpaddr = (SIZE_PTR)rbuf->pskb->data; + alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1); + skb_reserve(rbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment)); + } +#endif + + rbuf->pskb->dev = recvpriv->adapter->pnetdev; + + /* init recvbuf */ + rbuf->phead = rbuf->pskb->head; + rbuf->pdata = rbuf->pskb->data; + rbuf->ptail = skb_tail_pointer(rbuf->pskb); + rbuf->pend = skb_end_pointer(rbuf->pskb); + rbuf->len = 0; + + return _SUCCESS; +} +#endif /* CONFIG_SDIO_RX_COPY */ +#endif /* !defined(CONFIG_RTL8822B) && !defined(CONFIG_RTL8822C) */ +#endif /* defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) */ + /* alloc os related resource in struct recv_buf */ -int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf) +int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf, u32 size) { int res = _SUCCESS; @@ -235,13 +279,20 @@ int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf) precvbuf->len = 0; #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX - precvbuf->pallocated_buf = rtw_usb_buffer_alloc(pusbd, (size_t)precvbuf->alloc_sz, &precvbuf->dma_transfer_addr); + precvbuf->pallocated_buf = rtw_usb_buffer_alloc(pusbd, (size_t)size, &precvbuf->dma_transfer_addr); precvbuf->pbuf = precvbuf->pallocated_buf; if (precvbuf->pallocated_buf == NULL) return _FAIL; #endif /* CONFIG_USE_USB_BUFFER_ALLOC_RX */ -#endif /* CONFIG_USB_HCI */ +#elif defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + #if !defined(CONFIG_RTL8822B) && !defined(CONFIG_RTL8822C) + #ifdef CONFIG_SDIO_RX_COPY + res = sdio_init_recvbuf_with_skb(&padapter->recvpriv, precvbuf, size); + #endif + #endif + +#endif /* CONFIG_XXX_HCI */ return res; } @@ -282,9 +333,9 @@ int rtw_os_recvbuf_resource_free(_adapter *padapter, struct recv_buf *precvbuf) } -_pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, const u8 *da, const u8 *sa, u8 *msdu ,u16 msdu_len) +_pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, const u8 *da, const u8 *sa + , u8 *msdu ,u16 msdu_len, enum rtw_rx_llc_hdl llc_hdl) { - u16 eth_type; u8 *data_ptr; _pkt *sub_skb; struct rx_pkt_attrib *pattrib; @@ -311,13 +362,7 @@ _pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, const u8 *da, const u8 *s } } - eth_type = RTW_GET_BE16(&sub_skb->data[6]); - - if (sub_skb->len >= 8 - && ((_rtw_memcmp(sub_skb->data, rtw_rfc1042_header, SNAP_SIZE) - && eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) - || _rtw_memcmp(sub_skb->data, rtw_bridge_tunnel_header, SNAP_SIZE)) - ) { + if (llc_hdl) { /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ skb_pull(sub_skb, SNAP_SIZE); _rtw_memcpy(skb_push(sub_skb, ETH_ALEN), sa, ETH_ALEN); @@ -354,12 +399,13 @@ static int napi_recv(_adapter *padapter, int budget) rx_ok = _FALSE; #ifdef CONFIG_RTW_GRO - if (pregistrypriv->en_gro) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)) - if (rtw_napi_gro_receive(&padapter->napi, pskb) != GRO_MERGED_FREE) -#else + /* + cloned SKB use dataref to avoid kernel release it. + But dataref changed in napi_gro_receive. + So, we should prevent cloned SKB go into napi_gro_receive. + */ + if (pregistrypriv->en_gro && !skb_cloned(pskb)) { if (rtw_napi_gro_receive(&padapter->napi, pskb) != GRO_DROP) -#endif rx_ok = _TRUE; goto next; } @@ -437,52 +483,8 @@ void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, union recv_frame *r DBG_COUNTER(padapter->rx_logs.os_indicate); - if (MLME_IS_AP(padapter) && !pmlmepriv->ap_isolate) { - _pkt *pskb2 = NULL; - struct sta_info *psta = NULL; - struct sta_priv *pstapriv = &padapter->stapriv; - int bmcast = IS_MCAST(ehdr->h_dest); - - /* RTW_INFO("bmcast=%d\n", bmcast); */ - - if (_rtw_memcmp(ehdr->h_dest, adapter_mac_addr(padapter), ETH_ALEN) == _FALSE) { - /* RTW_INFO("not ap psta=%p, addr=%pM\n", psta, ehdr->h_dest); */ - - if (bmcast) { - psta = rtw_get_bcmc_stainfo(padapter); - pskb2 = rtw_skb_clone(pkt); - } else - psta = rtw_get_stainfo(pstapriv, ehdr->h_dest); - - if (psta) { - struct net_device *pnetdev = (struct net_device *)padapter->pnetdev; - - /* RTW_INFO("directly forwarding to the rtw_xmit_entry\n"); */ - - /* skb->ip_summed = CHECKSUM_NONE; */ - pkt->dev = pnetdev; - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) - skb_set_queue_mapping(pkt, rtw_recv_select_queue(pkt)); - #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) */ - - _rtw_xmit_entry(pkt, pnetdev); - - if (bmcast && (pskb2 != NULL)) { - pkt = pskb2; - DBG_COUNTER(padapter->rx_logs.os_indicate_ap_mcast); - } else { - DBG_COUNTER(padapter->rx_logs.os_indicate_ap_forward); - return; - } - } - } else { /* to APself */ - /* RTW_INFO("to APSelf\n"); */ - DBG_COUNTER(padapter->rx_logs.os_indicate_ap_self); - } - } - #ifdef CONFIG_BR_EXT - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) { + if (!adapter_use_wds(padapter) && check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) { /* Insert NAT2.5 RX here! */ #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) br_port = padapter->pnetdev->br_port; @@ -639,20 +641,15 @@ void rtw_hostapd_mlme_rx(_adapter *padapter, union recv_frame *precv_frame) } #endif /* CONFIG_HOSTAPD_MLME */ +#ifdef CONFIG_WIFI_MONITOR +/* + precv_frame: impossible to be NULL + precv_frame: free by caller + */ int rtw_recv_monitor(_adapter *padapter, union recv_frame *precv_frame) { int ret = _FAIL; - struct recv_priv *precvpriv; - _queue *pfree_recv_queue; _pkt *skb; - struct rx_pkt_attrib *pattrib; - - if (NULL == precv_frame) - goto _recv_drop; - - pattrib = &precv_frame->u.hdr.attrib; - precvpriv = &(padapter->recvpriv); - pfree_recv_queue = &(precvpriv->free_recv_queue); skb = precv_frame->u.hdr.pkt; if (skb == NULL) { @@ -667,6 +664,7 @@ int rtw_recv_monitor(_adapter *padapter, union recv_frame *precv_frame) skb->pkt_type = PACKET_OTHERHOST; skb->protocol = htons(0x0019); /* ETH_P_80211_RAW */ + /* send to kernel */ rtw_netif_rx(padapter->pnetdev, skb); /* pointers to NULL before rtw_free_recvframe() */ @@ -675,14 +673,9 @@ int rtw_recv_monitor(_adapter *padapter, union recv_frame *precv_frame) ret = _SUCCESS; _recv_drop: - - /* enqueue back to free_recv_queue */ - if (precv_frame) - rtw_free_recvframe(precv_frame, pfree_recv_queue); - return ret; - } +#endif /* CONFIG_WIFI_MONITOR */ inline void rtw_rframe_set_os_pkt(union recv_frame *rframe) { diff --git a/os_dep/linux/rtw_android.c b/os_dep/linux/rtw_android.c index 9150f9d..10f8f23 100644 --- a/os_dep/linux/rtw_android.c +++ b/os_dep/linux/rtw_android.c @@ -371,7 +371,7 @@ int rtw_android_get_rssi(struct net_device *net, char *command, int total_len) struct wlan_network *pcur_network = &pmlmepriv->cur_network; int bytes_written = 0; - if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) { bytes_written += snprintf(&command[bytes_written], total_len, "%s rssi %d", pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi); } @@ -828,11 +828,13 @@ int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) break; #ifdef CONFIG_IOCTL_CFG80211 + #ifdef CONFIG_AP_MODE case ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE: { int skip = strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE]) + 3; bytes_written = rtw_cfg80211_set_mgnt_wpsp2pie(net, command + skip, priv_cmd.total_len - skip, *(command + skip - 2) - '0'); break; } + #endif #endif /* CONFIG_IOCTL_CFG80211 */ #ifdef CONFIG_WFD @@ -1148,6 +1150,7 @@ extern PADAPTER g_test_adapter; static void shutdown_card(void) { + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(g_test_adapter); u32 addr; u8 tmp8, cnt = 0; @@ -1164,7 +1167,7 @@ static void shutdown_card(void) #ifdef CONFIG_GPIO_WAKEUP /*default wake up pin change to BT*/ RTW_INFO("%s:default wake up pin change to BT\n", __FUNCTION__); - rtw_hal_switch_gpio_wl_ctrl(g_test_adapter, WAKEUP_GPIO_IDX, _FALSE); + rtw_hal_switch_gpio_wl_ctrl(g_test_adapter, pwrpriv->wowlan_gpio_index, _FALSE); #endif /* CONFIG_GPIO_WAKEUP */ #endif /* CONFIG_WOWLAN */ diff --git a/os_dep/linux/rtw_cfgvendor.c b/os_dep/linux/rtw_cfgvendor.c index e497b14..53153ba 100644 --- a/os_dep/linux/rtw_cfgvendor.c +++ b/os_dep/linux/rtw_cfgvendor.c @@ -37,6 +37,10 @@ #include +#ifndef MIN +#define MIN(x,y) (((x) < (y)) ? (x) : (y)) +#endif + #ifdef DBG_MEM_ALLOC extern bool match_mstat_sniff_rules(const enum mstat_f flags, const size_t size); struct sk_buff *dbg_rtw_cfg80211_vendor_event_alloc(struct wiphy *wiphy, struct wireless_dev *wdev, int len, int event_id, gfp_t gfp @@ -171,7 +175,7 @@ struct sk_buff *rtw_cfg80211_vendor_event_alloc( int rtw_cfgvendor_send_async_event(struct wiphy *wiphy, struct net_device *dev, int event_id, const void *data, int len) { - u16 kflags; + gfp_t kflags; struct sk_buff *skb; kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; @@ -236,6 +240,10 @@ static int rtw_cfgvendor_send_cmd_reply(struct wiphy *wiphy, #define WIFI_FEATURE_CONTROL_ROAMING 0x800000 // Enable/Disable firmware roaming #define WIFI_FEATURE_IE_WHITELIST 0x1000000 // Support Probe IE white listing #define WIFI_FEATURE_SCAN_RAND 0x2000000 // Support MAC & Probe Sequence Number randomization +#define WIFI_FEATURE_SET_TX_POWER_LIMIT 0x4000000 // Support Tx Power Limit setting +#define WIFI_FEATURE_USE_BODY_HEAD_SAR 0x8000000 // Support Using Body/Head Proximity for SAR +#define WIFI_FEATURE_SET_LATENCY_MODE 0x40000000 // Support Latency mode setting +#define WIFI_FEATURE_P2P_RAND_MAC 0x80000000 // Support Support P2P MAC randomization // Add more features here #define MAX_FEATURE_SET_CONCURRRENT_GROUPS 3 @@ -258,11 +266,11 @@ int rtw_dev_get_feature_set(struct net_device *dev) feature_set |= WIFI_FEATURE_SOFT_AP; feature_set |= WIFI_FEATURE_ADDITIONAL_STA; -#ifdef CONFIG_RTW_CFGVEDNOR_LLSTATS +#ifdef CONFIG_RTW_CFGVENDOR_LLSTATS feature_set |= WIFI_FEATURE_LINK_LAYER_STATS; -#endif /* CONFIG_RTW_CFGVEDNOR_LLSTATS */ +#endif /* CONFIG_RTW_CFGVENDOR_LLSTATS */ -#ifdef CONFIG_RTW_CFGVEDNOR_RSSIMONITOR +#ifdef CONFIG_RTW_CFGVENDOR_RSSIMONITOR feature_set |= WIFI_FEATURE_RSSI_MONITOR; #endif @@ -272,7 +280,9 @@ int rtw_dev_get_feature_set(struct net_device *dev) #ifdef CONFIG_RTW_WIFI_HAL feature_set |= WIFI_FEATURE_CONFIG_NDO; +#if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND) feature_set |= WIFI_FEATURE_SCAN_RAND; +#endif #endif return feature_set; @@ -1135,7 +1145,7 @@ exit: #endif /* RTT_SUPPORT */ -#ifdef CONFIG_RTW_CFGVEDNOR_LLSTATS +#ifdef CONFIG_RTW_CFGVENDOR_LLSTATS enum { LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START, LSTATS_SUBCMD_SET_INFO, @@ -1162,7 +1172,7 @@ static void LinkLayerStats(_adapter *padapter) pwrpriv->on_time = rtw_get_passing_time_ms(pwrpriv->radio_on_start_time); - if (rtw_mi_check_fwstate(padapter, _FW_LINKED)) { + if (rtw_mi_check_fwstate(padapter, WIFI_ASOC_STATE)) { if ( pwrpriv->bpower_saving == _TRUE ) { pwrpriv->pwr_saving_time += rtw_get_passing_time_ms(pwrpriv->pwr_saving_start_time); pwrpriv->pwr_saving_start_time = rtw_get_current_time(); @@ -1292,8 +1302,8 @@ static int rtw_cfgvendor_lstats_clear_info(struct wiphy *wiphy, RTW_INFO("%s\n", __func__); return err; } -#endif /* CONFIG_RTW_CFGVEDNOR_LLSTATS */ -#ifdef CONFIG_RTW_CFGVEDNOR_RSSIMONITOR +#endif /* CONFIG_RTW_CFGVENDOR_LLSTATS */ +#ifdef CONFIG_RTW_CFGVENDOR_RSSIMONITOR static int rtw_cfgvendor_set_rssi_monitor(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) { @@ -1338,7 +1348,7 @@ void rtw_cfgvendor_rssi_monitor_evt(_adapter *padapter) { rssi_monitor_evt data ; s8 rssi = precvpriv->rssi; - if (pwdev_priv->rssi_monitor_enable == 0 || check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE) + if (pwdev_priv->rssi_monitor_enable == 0 || check_fwstate(pmlmepriv, WIFI_ASOC_STATE) != _TRUE) return; if (rssi < pwdev_priv->rssi_monitor_max || rssi > pwdev_priv->rssi_monitor_min) @@ -1364,7 +1374,7 @@ void rtw_cfgvendor_rssi_monitor_evt(_adapter *padapter) { exit: return; } -#endif /* CONFIG_RTW_CFGVEDNOR_RSSIMONITR */ +#endif /* CONFIG_RTW_CFGVENDOR_RSSIMONITR */ #ifdef CONFIG_RTW_CFGVENDOR_WIFI_LOGGER static int rtw_cfgvendor_logger_start_logging(struct wiphy *wiphy, @@ -1589,21 +1599,6 @@ void rtw_hal_pno_random_gen_mac_addr(PADAPTER adapter) #endif } -void rtw_hal_set_hw_mac_addr(PADAPTER adapter, u8 *mac_addr) -{ - rtw_ps_deny(adapter, PS_DENY_IOCTL); - LeaveAllPowerSaveModeDirect(adapter); - -#ifdef CONFIG_MI_WITH_MBSSID_CAM - rtw_hal_change_macaddr_mbid(adapter, mac_addr); -#else - rtw_hal_set_hwreg(adapter, HW_VAR_MAC_ADDR, mac_addr); -#endif -#ifdef CONFIG_RTW_DEBUG - rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter); -#endif - rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL); -} static int rtw_cfgvendor_set_rand_mac_oui(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) @@ -1660,9 +1655,47 @@ static int rtw_cfgvendor_set_rand_mac_oui(struct wiphy *wiphy, return err; } - #endif +#if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND) +void rtw_hal_set_hw_mac_addr(PADAPTER adapter, u8 *mac_addr) +{ + rtw_ps_deny(adapter, PS_DENY_IOCTL); + LeaveAllPowerSaveModeDirect(adapter); + +#ifdef CONFIG_MI_WITH_MBSSID_CAM + rtw_hal_change_macaddr_mbid(adapter, mac_addr); +#else + rtw_hal_set_hwreg(adapter, HW_VAR_MAC_ADDR, mac_addr); +#endif +#ifdef CONFIG_RTW_DEBUG + rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter); +#endif + rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL); +} +#endif + +#ifdef CONFIG_RTW_CFGVENDOR_WIFI_OFFLOAD +static int rtw_cfgvendor_start_mkeep_alive(struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int len) +{ + int ret = WIFI_SUCCESS; + + RTW_INFO("%s : TODO\n", __func__); + + return ret; +} + +static int rtw_cfgvendor_stop_mkeep_alive(struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int len) +{ + int ret = WIFI_SUCCESS; + + RTW_INFO("%s : TODO\n", __func__); + + return ret; +} +#endif static int rtw_cfgvendor_set_nodfs_flag(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) @@ -1843,13 +1876,16 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .doit = rtw_cfgvendor_rtt_get_capability }, #endif /* RTT_SUPPORT */ -#ifdef CONFIG_RTW_CFGVEDNOR_LLSTATS +#ifdef CONFIG_RTW_CFGVENDOR_LLSTATS { { .vendor_id = OUI_GOOGLE, .subcmd = LSTATS_SUBCMD_GET_INFO }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_lstats_get_info }, { @@ -1858,6 +1894,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LSTATS_SUBCMD_SET_INFO }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_lstats_set_info }, { @@ -1866,19 +1905,25 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LSTATS_SUBCMD_CLEAR_INFO }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_lstats_clear_info }, -#endif /* CONFIG_RTW_CFGVEDNOR_LLSTATS */ -#ifdef CONFIG_RTW_CFGVEDNOR_RSSIMONITOR +#endif /* CONFIG_RTW_CFGVENDOR_LLSTATS */ +#ifdef CONFIG_RTW_CFGVENDOR_RSSIMONITOR { { .vendor_id = OUI_GOOGLE, .subcmd = WIFI_SUBCMD_SET_RSSI_MONITOR }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_set_rssi_monitor }, -#endif /* CONFIG_RTW_CFGVEDNOR_RSSIMONITOR */ +#endif /* CONFIG_RTW_CFGVENDOR_RSSIMONITOR */ #ifdef CONFIG_RTW_CFGVENDOR_WIFI_LOGGER { { @@ -1886,6 +1931,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_START_LOGGING }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_start_logging }, { @@ -1894,6 +1942,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_GET_FEATURE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_get_feature }, { @@ -1902,6 +1953,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_GET_VER }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_get_version }, { @@ -1910,6 +1964,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_GET_RING_STATUS }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_get_ring_status }, { @@ -1918,6 +1975,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_GET_RING_DATA }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_get_ring_data }, { @@ -1926,6 +1986,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_TRIGGER_MEM_DUMP }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_get_firmware_memory_dump }, { @@ -1934,6 +1997,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_START_PKT_FATE_MONITORING }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_start_pkt_fate_monitoring }, { @@ -1942,6 +2008,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_GET_TX_PKT_FATES }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_get_tx_pkt_fates }, { @@ -1950,6 +2019,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_GET_RX_PKT_FATES }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_get_rx_pkt_fates }, #endif /* CONFIG_RTW_CFGVENDOR_WIFI_LOGGER */ @@ -1961,8 +2033,35 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_set_rand_mac_oui }, +#endif +#ifdef CONFIG_RTW_CFGVENDOR_WIFI_OFFLOAD + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif + .doit = rtw_cfgvendor_start_mkeep_alive + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif + .doit = rtw_cfgvendor_stop_mkeep_alive + }, #endif { { @@ -1970,6 +2069,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = WIFI_SUBCMD_NODFS_SET }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_set_nodfs_flag }, @@ -1979,6 +2081,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_set_country }, { @@ -1987,6 +2092,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = WIFI_SUBCMD_CONFIG_ND_OFFLOAD }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_set_nd_offload }, #endif /* CONFIG_RTW_WIFI_HAL */ @@ -1996,6 +2104,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = WIFI_SUBCMD_GET_FEATURE_SET }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_get_feature_set }, { @@ -2004,6 +2115,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = WIFI_SUBCMD_GET_FEATURE_SET_MATRIX }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_get_feature_set_matrix } }; @@ -2019,9 +2133,9 @@ static const struct nl80211_vendor_cmd_info rtw_vendor_events[] = { { OUI_GOOGLE, RTT_EVENT_COMPLETE }, #endif /* RTT_SUPPORT */ -#ifdef CONFIG_RTW_CFGVEDNOR_RSSIMONITOR +#ifdef CONFIG_RTW_CFGVENDOR_RSSIMONITOR { OUI_GOOGLE, GOOGLE_RSSI_MONITOR_EVENT }, -#endif /* RTW_CFGVEDNOR_RSSIMONITR */ +#endif /* RTW_CFGVENDOR_RSSIMONITR */ #if defined(GSCAN_SUPPORT) && 0 { OUI_GOOGLE, GSCAN_EVENT_COMPLETE_SCAN }, diff --git a/os_dep/linux/rtw_cfgvendor.h b/os_dep/linux/rtw_cfgvendor.h index af423fc..3fefa27 100644 --- a/os_dep/linux/rtw_cfgvendor.h +++ b/os_dep/linux/rtw_cfgvendor.h @@ -137,6 +137,9 @@ enum rtw_vendor_subcmd { LOGGER_GET_TX_PKT_FATES, LOGGER_GET_RX_PKT_FATES, + WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE = ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START, + WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE, + VENDOR_SUBCMD_MAX }; @@ -380,7 +383,7 @@ typedef struct { // monotonously increasing integer } wifi_ring_buffer_status; -#ifdef CONFIG_RTW_CFGVEDNOR_LLSTATS +#ifdef CONFIG_RTW_CFGVENDOR_LLSTATS #define STATS_MAJOR_VERSION 1 #define STATS_MINOR_VERSION 0 #define STATS_MICRO_VERSION 0 @@ -606,7 +609,7 @@ typedef struct { #define WIFI_STATS_IFACE_AC 0x00000040 // all ac statistics (within interface statistics) #define WIFI_STATS_IFACE_CONTENTION 0x00000080 // all contention (min, max, avg) statistics (within ac statisctics) -#endif /* CONFIG_RTW_CFGVEDNOR_LLSTATS */ +#endif /* CONFIG_RTW_CFGVENDOR_LLSTATS */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT) @@ -620,12 +623,14 @@ extern int rtw_cfgvendor_send_hotlist_event(struct wiphy *wiphy, #endif #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT) */ -#ifdef CONFIG_RTW_CFGVEDNOR_RSSIMONITOR +#ifdef CONFIG_RTW_CFGVENDOR_RSSIMONITOR void rtw_cfgvendor_rssi_monitor_evt(_adapter *padapter); #endif #ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI void rtw_hal_pno_random_gen_mac_addr(PADAPTER adapter); +#endif +#if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND) void rtw_hal_set_hw_mac_addr(PADAPTER adapter, u8 *mac_addr); #endif diff --git a/os_dep/linux/rtw_proc.c b/os_dep/linux/rtw_proc.c index f69c5de..e055f05 100644 --- a/os_dep/linux/rtw_proc.c +++ b/os_dep/linux/rtw_proc.c @@ -173,11 +173,13 @@ static int proc_get_chplan_id_list(struct seq_file *m, void *v) return 0; } +#ifdef CONFIG_RTW_DEBUG static int proc_get_chplan_test(struct seq_file *m, void *v) { dump_chplan_test(m); return 0; } +#endif static int proc_get_chplan_ver(struct seq_file *m, void *v) { @@ -185,6 +187,20 @@ static int proc_get_chplan_ver(struct seq_file *m, void *v) return 0; } +static int proc_get_global_op_class(struct seq_file *m, void *v) +{ + dump_global_op_class(m); + return 0; +} + +#ifdef CONFIG_RTW_DEBUG +static int proc_get_hw_rate_map_test(struct seq_file *m, void *v) +{ + dump_hw_rate_map_test(m); + return 0; +} +#endif + #ifdef RTW_HALMAC extern void rtw_halmac_get_version(char *str, u32 len); @@ -213,8 +229,14 @@ const struct rtw_proc_hdl drv_proc_hdls[] = { #endif /* DBG_MEM_ALLOC */ RTW_PROC_HDL_SSEQ("country_chplan_map", proc_get_country_chplan_map, NULL), RTW_PROC_HDL_SSEQ("chplan_id_list", proc_get_chplan_id_list, NULL), +#ifdef CONFIG_RTW_DEBUG RTW_PROC_HDL_SSEQ("chplan_test", proc_get_chplan_test, NULL), +#endif RTW_PROC_HDL_SSEQ("chplan_ver", proc_get_chplan_ver, NULL), + RTW_PROC_HDL_SSEQ("global_op_class", proc_get_global_op_class, NULL), +#ifdef CONFIG_RTW_DEBUG + RTW_PROC_HDL_SSEQ("hw_rate_map_test", proc_get_hw_rate_map_test, NULL), +#endif #ifdef RTW_HALMAC RTW_PROC_HDL_SSEQ("halmac_info", proc_get_halmac_info, NULL), #endif /* RTW_HALMAC */ @@ -440,6 +462,100 @@ static int proc_get_sdio_card_info(struct seq_file *m, void *v) return 0; } +#ifdef CONFIG_SDIO_RECVBUF_AGGREGATION +int proc_get_sdio_recvbuf_aggregation(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = GET_PRIMARY_ADAPTER((_adapter *)rtw_netdev_priv(dev)); + struct recv_priv *recvpriv = &adapter->recvpriv; + + RTW_PRINT_SEL(m, "%d\n", recvpriv->recvbuf_agg); + + return 0; +} + +ssize_t proc_set_sdio_recvbuf_aggregation(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = GET_PRIMARY_ADAPTER((_adapter *)rtw_netdev_priv(dev)); + struct recv_priv *recvpriv = &adapter->recvpriv; + + char tmp[32]; + u8 enable; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhu", &enable); + + if (num >= 1) + recvpriv->recvbuf_agg = enable ? 1 : 0; + } + + return count; +} +#endif /* CONFIG_SDIO_RECVBUF_AGGREGATION */ + +#ifdef CONFIG_SDIO_RECVBUF_PWAIT +int proc_get_sdio_recvbuf_pwait(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = GET_PRIMARY_ADAPTER((_adapter *)rtw_netdev_priv(dev)); + struct recv_priv *recvpriv = &adapter->recvpriv; + + dump_recvbuf_pwait_conf(m, recvpriv); + + return 0; +} + +ssize_t proc_set_sdio_recvbuf_pwait(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ +#ifdef CONFIG_SDIO_RECVBUF_PWAIT_RUNTIME_ADJUST + struct net_device *dev = data; + _adapter *adapter = GET_PRIMARY_ADAPTER((_adapter *)rtw_netdev_priv(dev)); + struct recv_priv *recvpriv = &adapter->recvpriv; + + char tmp[64]; + char type[64]; + s32 time; + s32 cnt_lmt; + + if (count < 3) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%s %d %d", type, &time, &cnt_lmt); + int i; + + if (num < 3) + return -EINVAL; + + for (i = 0; i < RTW_PWAIT_TYPE_NUM; i++) + if (strncmp(_rtw_pwait_type_str[i], type, strlen(_rtw_pwait_type_str[i])) == 0) + break; + + if (i < RTW_PWAIT_TYPE_NUM && recvbuf_pwait_config_req(recvpriv, i, time, cnt_lmt) != _SUCCESS) + return -EINVAL; + } + return count; +#else + return -EFAULT; +#endif /* CONFIG_SDIO_RECVBUF_PWAIT_RUNTIME_ADJUST */ +} +#endif /* CONFIG_SDIO_RECVBUF_PWAIT */ + #ifdef DBG_SDIO static int proc_get_sdio_dbg(struct seq_file *m, void *v) { @@ -737,6 +853,46 @@ ssize_t proc_set_ap_isolate(struct file *file, const char __user *buffer, size_t return count; } + +#if CONFIG_RTW_AP_DATA_BMC_TO_UC +static int proc_get_ap_b2u_flags(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = rtw_netdev_priv(dev); + + if (MLME_IS_AP(adapter)) + dump_ap_b2u_flags(m, adapter); + + return 0; +} + +static ssize_t proc_set_ap_b2u_flags(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = rtw_netdev_priv(dev); + char tmp[32]; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + u8 src, fwd; + int num = sscanf(tmp, "%hhx %hhx", &src, &fwd); + + if (num >= 1) + adapter->b2u_flags_ap_src = src; + if (num >= 2) + adapter->b2u_flags_ap_fwd = fwd; + } + + return count; +} +#endif /* CONFIG_RTW_AP_DATA_BMC_TO_UC */ #endif /* CONFIG_AP_MODE */ static int proc_get_dump_tx_rate_bmp(struct seq_file *m, void *v) @@ -1340,7 +1496,6 @@ static int proc_get_chan_plan(struct seq_file *m, void *v) _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); dump_cur_chset(m, adapter_to_rfctl(adapter)); - return 0; } @@ -1418,6 +1573,111 @@ exit: return count; } +static int cap_spt_op_class_ch_detail = 0; + +static int proc_get_cap_spt_op_class_ch(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_cap_spt_op_class_ch(m , adapter_to_rfctl(adapter), cap_spt_op_class_ch_detail); + return 0; +} + +static ssize_t proc_set_cap_spt_op_class_ch(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + int num; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (!buffer || copy_from_user(tmp, buffer, count)) + goto exit; + + num = sscanf(tmp, "%d", &cap_spt_op_class_ch_detail); + +exit: + return count; +} + +static int reg_spt_op_class_ch_detail = 0; + +static int proc_get_reg_spt_op_class_ch(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_reg_spt_op_class_ch(m , adapter_to_rfctl(adapter), reg_spt_op_class_ch_detail); + return 0; +} + +static ssize_t proc_set_reg_spt_op_class_ch(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + int num; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (!buffer || copy_from_user(tmp, buffer, count)) + goto exit; + + num = sscanf(tmp, "%d", ®_spt_op_class_ch_detail); + +exit: + return count; +} + +static int cur_spt_op_class_ch_detail = 0; + +static int proc_get_cur_spt_op_class_ch(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_cur_spt_op_class_ch(m , adapter_to_rfctl(adapter), cur_spt_op_class_ch_detail); + return 0; +} + +static ssize_t proc_set_cur_spt_op_class_ch(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + int num; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (!buffer || copy_from_user(tmp, buffer, count)) + goto exit; + + num = sscanf(tmp, "%d", &cur_spt_op_class_ch_detail); + +exit: + return count; +} + #if CONFIG_RTW_MACADDR_ACL static int proc_get_macaddr_acl(struct seq_file *m, void *v) { @@ -1737,6 +1997,7 @@ ssize_t proc_set_update_non_ocp(struct file *file, const char __user *buffer, si char tmp[32]; u8 ch, bw = CHANNEL_WIDTH_20, offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; int ms = -1; + bool updated = 0; if (count < 1) return -EFAULT; @@ -1754,11 +2015,17 @@ ssize_t proc_set_update_non_ocp(struct file *file, const char __user *buffer, si goto exit; if (bw == CHANNEL_WIDTH_20) - rtw_chset_update_non_ocp_ms(rfctl->channel_set + updated = rtw_chset_update_non_ocp_ms(rfctl->channel_set , ch, bw, HAL_PRIME_CHNL_OFFSET_DONT_CARE, ms); else - rtw_chset_update_non_ocp_ms(rfctl->channel_set + updated = rtw_chset_update_non_ocp_ms(rfctl->channel_set , ch, bw, offset, ms); + + if (updated) { + u8 cch = rtw_get_center_ch(ch, bw, offset); + + rtw_nlrtw_nop_start_event(adapter, cch, bw); + } } exit: @@ -1795,6 +2062,47 @@ exit: return count; } +static int proc_get_dfs_ch_sel_e_flags(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + RTW_PRINT_SEL(m, "0x%02x\n", rfctl->dfs_ch_sel_e_flags); + + return 0; +} + +static ssize_t proc_set_dfs_ch_sel_e_flags(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + char tmp[32]; + u8 e_flags; + int num; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (!buffer || copy_from_user(tmp, buffer, count)) + goto exit; + + num = sscanf(tmp, "%hhx", &e_flags); + if (num != 1) + goto exit; + + rfctl->dfs_ch_sel_e_flags = e_flags; + +exit: + return count; +} + static int proc_get_dfs_ch_sel_d_flags(struct seq_file *m, void *v) { struct net_device *dev = m->private; @@ -2180,6 +2488,7 @@ static int proc_get_sec_cam_cache(struct seq_file *m, void *v) return 0; } +#ifdef CONFIG_AP_MODE static ssize_t proc_set_change_bss_chbw(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) { struct net_device *dev = data; @@ -2227,6 +2536,7 @@ static ssize_t proc_set_change_bss_chbw(struct file *file, const char __user *bu exit: return count; } +#endif #if CONFIG_TX_AC_LIFETIME static int proc_get_tx_aclt_force_val(struct seq_file *m, void *v) @@ -2469,6 +2779,92 @@ static int proc_get_tx_power_limit(struct seq_file *m, void *v) } #endif /* CONFIG_TXPWR_LIMIT */ +static int proc_get_tpc_settings(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_txpwr_tpc_settings(m, adapter); + + return 0; +} + +static ssize_t proc_set_tpc_settings(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + char tmp[32] = {0}; + u8 mode; + u16 m_constraint; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhu %hu", &mode, &m_constraint); + + if (num < 1) + return count; + + if (mode >= TPC_MODE_INVALID) + return count; + + if (mode == TPC_MODE_MANUAL && num >= 2) + rfctl->tpc_manual_constraint = rtw_min(m_constraint, TPC_MANUAL_CONSTRAINT_MAX); + rfctl->tpc_mode = mode; + + if (rtw_get_hw_init_completed(adapter)) + rtw_run_in_thread_cmd_wait(adapter, ((void *)(rtw_hal_update_txpwr_level)), adapter, 2000); + } + + return count; +} + +static int proc_get_antenna_gain(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_txpwr_antenna_gain(m, adapter); + + return 0; +} + +static ssize_t proc_set_antenna_gain(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + char tmp[32] = {0}; + s16 gain; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hd", &gain); + + if (num < 1) + return count; + + rfctl->antenna_gain = gain; + + if (rtw_get_hw_init_completed(adapter)) + rtw_run_in_thread_cmd_wait(adapter, ((void *)(rtw_hal_update_txpwr_level)), adapter, 2000); + } + + return count; +} + static int proc_get_tx_power_ext_info(struct seq_file *m, void *v) { struct net_device *dev = m->private; @@ -2730,7 +3126,7 @@ static int proc_get_kfree_bb_gain(struct seq_file *m, void *v) { struct net_device *dev = m->private; _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); - HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); struct kfree_data_t *kfree_data = GET_KFREE_DATA(adapter); u8 i, j; @@ -2757,7 +3153,7 @@ static int proc_get_kfree_bb_gain(struct seq_file *m, void *v) break; } #endif - for (j = 0; j < hal_data->NumTotalRFPath; j++) + for (j = 0; j < hal_spec->rf_reg_path_num; j++) _RTW_PRINT_SEL(m, "%d ", kfree_data->bb_gain[i][j]); _RTW_PRINT_SEL(m, "\n"); } @@ -3689,6 +4085,406 @@ static int proc_get_dynamic_agg_enable(struct seq_file *m, void *v) return 0; } +#ifdef CONFIG_RTW_WDS +static int proc_get_wds_en(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = rtw_netdev_priv(dev); + + if (MLME_STATE(adapter) & (WIFI_AP_STATE | WIFI_STATION_STATE)) + RTW_PRINT_SEL(m, "%d\n", adapter_use_wds(adapter)); + + return 0; +} + +static ssize_t proc_set_wds_en(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = rtw_netdev_priv(dev); + char tmp[32]; + + if (!(MLME_STATE(adapter) & (WIFI_AP_STATE | WIFI_STATION_STATE))) + return -EFAULT; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + u8 enable; + int num = sscanf(tmp, "%hhu", &enable); + + if (num >= 1) + adapter_set_use_wds(adapter, enable); + } + + return count; +} + +static ssize_t proc_set_sta_wds_en(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = rtw_netdev_priv(dev); + char tmp[32]; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + u8 enable; + u8 addr[ETH_ALEN]; + struct sta_info *sta; + int num = sscanf(tmp, "%hhu "MAC_SFMT, &enable, MAC_SARG(addr)); + + if (num != 7) + return -EINVAL; + + if (IS_MCAST(addr) || _rtw_memcmp(adapter_mac_addr(adapter), addr, ETH_ALEN)) + return -EINVAL; + + sta = rtw_get_stainfo(&adapter->stapriv, addr); + if (!sta) + return -EINVAL; + + if (enable) + sta->flags |= WLAN_STA_WDS; + else + sta->flags &= ~WLAN_STA_WDS; + } + + return count; +} + +static int proc_get_wds_gptr(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = rtw_netdev_priv(dev); + + if (MLME_IS_STA(adapter) && MLME_IS_ASOC(adapter)) + dump_wgptr(m, adapter); + + return 0; +} + +#ifdef CONFIG_AP_MODE +static int proc_get_wds_path(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = rtw_netdev_priv(dev); + + if (MLME_IS_AP(adapter) && MLME_IS_ASOC(adapter)) + dump_wpath(m, adapter); + + return 0; +} +#endif /* CONFIG_AP_MODE */ +#endif /* CONFIG_RTW_WDS */ + +#ifdef CONFIG_RTW_MULTI_AP +static int proc_get_multi_ap_opmode(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = rtw_netdev_priv(dev); + + if (MLME_STATE(adapter) & (WIFI_AP_STATE | WIFI_STATION_STATE)) + RTW_PRINT_SEL(m, "0x%02x\n", adapter->multi_ap); + + return 0; +} + +static ssize_t proc_set_multi_ap_opmode(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = rtw_netdev_priv(dev); + char tmp[32]; + + if (!(MLME_STATE(adapter) & (WIFI_AP_STATE | WIFI_STATION_STATE))) + return -EFAULT; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + u8 mode; + int num = sscanf(tmp, "%hhx", &mode); + + if (num >= 1) { + if (MLME_IS_AP(adapter)) + adapter->multi_ap = mode & (MULTI_AP_FRONTHAUL_BSS | MULTI_AP_BACKHAUL_BSS); + else + adapter->multi_ap = mode & MULTI_AP_BACKHAUL_STA; + if (adapter->multi_ap & (MULTI_AP_BACKHAUL_BSS | MULTI_AP_BACKHAUL_STA)) + adapter_set_use_wds(adapter, 1); + } + } + + return count; +} + +static int proc_get_unassoc_sta(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = GET_PRIMARY_ADAPTER(rtw_netdev_priv(dev)); + + dump_unassoc_sta(m, adapter); + + return 0; +} + +ssize_t proc_set_unassoc_sta(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = GET_PRIMARY_ADAPTER(rtw_netdev_priv(dev)); + char tmp[17 * 10 + 32] = {0}; + char cmd[32]; + u8 mode; + u8 stype = 0; + u8 addr[ETH_ALEN]; + +#define UNASOC_STA_CMD_MODE 0 +#define UNASOC_STA_CMD_ADD 1 +#define UNASOC_STA_CMD_DEL 2 +#define UNASOC_STA_CMD_CLR 3 +#define UNASOC_STA_CMD_UNINT 4 +#define UNASOC_STA_CMD_NUM 5 + + static const char * const unasoc_sta_cmd_str[] = { + "mode", + "add", + "del", + "clr", + "uninterest", + }; + u8 cmd_id = UNASOC_STA_CMD_NUM; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + RTW_WARN(FUNC_ADPT_FMT" input string too long\n", FUNC_ADPT_ARG(adapter)); + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + /* + * mode , + * add [] + * del [] + * clr + */ + char *c, *next; + int i; + u8 is_bcast; + + next = tmp; + c = strsep(&next, " \t"); + if (!c || sscanf(c, "%s", cmd) != 1) + goto exit; + + for (i = 0; i < UNASOC_STA_CMD_NUM; i++) + if (strcmp(unasoc_sta_cmd_str[i], cmd) == 0) + cmd_id = i; + + switch (cmd_id) { + case UNASOC_STA_CMD_MODE: + c = strsep(&next, " \t"); + if (!c || sscanf(c, "%hhu,%hhu", &stype, &mode) != 2) { + RTW_WARN(FUNC_ADPT_FMT" invalid arguments of mode cmd\n", FUNC_ADPT_ARG(adapter)); + goto exit; + } + if (stype >= UNASOC_STA_SRC_NUM) { + RTW_WARN(FUNC_ADPT_FMT" invalid stype:%u\n", FUNC_ADPT_ARG(adapter), stype); + goto exit; + } + if (mode >= UNASOC_STA_MODE_NUM) { + RTW_WARN(FUNC_ADPT_FMT" invalid mode:%u\n", FUNC_ADPT_ARG(adapter), mode); + goto exit; + } + rtw_unassoc_sta_set_mode(adapter, stype, mode); + break; + + case UNASOC_STA_CMD_ADD: + case UNASOC_STA_CMD_DEL: + case UNASOC_STA_CMD_UNINT: + /* check for macaddr list */ + c = strsep(&next, " \t"); + while (c != NULL) { + if (sscanf(c, MAC_SFMT, MAC_SARG(addr)) != 6) + break; + + is_bcast = is_broadcast_mac_addr(addr); + if (is_bcast + || rtw_check_invalid_mac_address(addr, 0) == _FALSE + ) { + if (cmd_id == UNASOC_STA_CMD_DEL) { + if (is_bcast) { + rtw_del_unassoc_sta_queue(adapter); + break; + } else + rtw_del_unassoc_sta(adapter, addr); + } else if (cmd_id == UNASOC_STA_CMD_UNINT) { + if (is_bcast) { + rtw_undo_all_interested_unassoc_sta(adapter); + break; + } else + rtw_undo_interested_unassoc_sta(adapter, addr); + } else if (!is_bcast) + rtw_add_interested_unassoc_sta(adapter, addr); + } + + c = strsep(&next, " \t"); + } + break; + + case UNASOC_STA_CMD_CLR: + /* clear sta list */ + rtw_del_unassoc_sta_queue(adapter); + goto exit; + + default: + RTW_WARN(FUNC_ADPT_FMT" invalid cmd:\"%s\"\n", FUNC_ADPT_ARG(adapter), cmd); + goto exit; + } + } + +exit: + return count; +} + +#ifdef CONFIG_IOCTL_CFG80211 +static u8 assoc_req_mac_addr[6]; +int proc_get_sta_assoc_req_frame_body(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + if (MLME_IS_AP(adapter)) { + struct sta_info *psta; + _irqL irqL; + u8 *passoc_req = NULL; + u32 assoc_req_len = 0; + + psta = rtw_get_stainfo(&adapter->stapriv, assoc_req_mac_addr); + if (psta == NULL) { + RTW_PRINT(FUNC_ADPT_FMT" sta("MAC_FMT") not found\n", + FUNC_ADPT_ARG(adapter), MAC_ARG(assoc_req_mac_addr)); + return 0; + } + RTW_PRINT(FUNC_ADPT_FMT" sta("MAC_FMT") found\n", + FUNC_ADPT_ARG(adapter), MAC_ARG(assoc_req_mac_addr)); + _enter_critical_bh(&psta->lock, &irqL); + if (psta->passoc_req && psta->assoc_req_len > 0) { + passoc_req = rtw_zmalloc(psta->assoc_req_len); + if (passoc_req) { + assoc_req_len = psta->assoc_req_len; + _rtw_memcpy(passoc_req, psta->passoc_req, assoc_req_len); + } + } + _exit_critical_bh(&psta->lock, &irqL); + if (passoc_req && assoc_req_len > IEEE80211_3ADDR_LEN) { + u8 *body = passoc_req + IEEE80211_3ADDR_LEN; + u32 body_len = assoc_req_len - IEEE80211_3ADDR_LEN; + u16 i; + + for (i = 0; i < body_len; i++) + _RTW_PRINT_SEL(m, "%02X", body[i]); + _RTW_PRINT_SEL(m, "\n"); + } + if (passoc_req && assoc_req_len > 0) + rtw_mfree(passoc_req, assoc_req_len); + } + + return 0; +} + +ssize_t proc_set_sta_assoc_req_frame_body(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[18] = {0}; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + if (sscanf(tmp, MAC_SFMT, MAC_SARG(assoc_req_mac_addr)) != 6) { + _rtw_memset(assoc_req_mac_addr, 0, 6); + RTW_PRINT(FUNC_ADPT_FMT" Invalid format\n", + FUNC_ADPT_ARG(adapter)); + } + + } + + return count; +} +#endif /* CONFIG_IOCTL_CFG80211 */ + +static int proc_get_ch_util_threshold(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = GET_PRIMARY_ADAPTER(rtw_netdev_priv(dev)); + + RTW_PRINT_SEL(m, "%hhu\n", adapter->ch_util_threshold); + + return 0; +} + +static ssize_t proc_set_ch_util_threshold(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = GET_PRIMARY_ADAPTER(rtw_netdev_priv(dev)); + char tmp[4]; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + u8 threshold; + int num = sscanf(tmp, "%hhu", &threshold); + + if (num == 1) + adapter->ch_util_threshold = threshold; + } + + return count; +} + +static int proc_get_ch_utilization(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + RTW_PRINT_SEL(m, "%hhu\n", rtw_get_ch_utilization(adapter)); + + return 0; +} +#endif /* CONFIG_RTW_MULTI_AP */ + #ifdef CONFIG_RTW_MESH static int proc_get_mesh_peer_sel_policy(struct seq_file *m, void *v) { @@ -4137,6 +4933,57 @@ exit: } #endif /* CONFIG_RTW_MESH */ +#ifdef RTW_BUSY_DENY_SCAN +static int proc_get_scan_interval_thr(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + struct _ADAPTER *adapter= (struct _ADAPTER *)rtw_netdev_priv(dev); + struct registry_priv *rp = &adapter->registrypriv; + + + RTW_PRINT_SEL(m, "scan interval threshold = %u ms\n", + rp->scan_interval_thr); + + return 0; +} + +static ssize_t proc_set_scan_interval_thr(struct file *file, + const char __user *buffer, + size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + struct _ADAPTER *adapter= (struct _ADAPTER *)rtw_netdev_priv(dev); + struct registry_priv *rp = &adapter->registrypriv; + char tmp[12]; + int num = 0; + u32 thr = 0; + + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (!buffer || copy_from_user(tmp, buffer, count)) + goto exit; + + num = sscanf(tmp, "%u", &thr); + if (num != 1) { + RTW_ERR("%s: invalid parameter!\n", __FUNCTION__); + goto exit; + } + + rp->scan_interval_thr = thr; + + RTW_PRINT("%s: scan interval threshold = %u ms\n", + __FUNCTION__, rp->scan_interval_thr); + +exit: + return count; +} + +#endif /* RTW_BUSY_DENY_SCAN */ + static int proc_get_scan_deny(struct seq_file *m, void *v) { struct net_device *dev = m->private; @@ -4320,50 +5167,60 @@ int proc_get_cur_beacon_keys(struct seq_file *m, void *v) return 0; } -#define VHT_2G4_STATUS_STR(adapter) rtw_is_vht_2g4(adapter)?"allow":"deny" - -static int proc_get_vht_2g4(struct seq_file *m, void *v) +static int proc_get_amsdu_mode(struct seq_file *m, void *v) { struct net_device *dev = m->private; - struct _ADAPTER *a = (_adapter *)rtw_netdev_priv(dev); + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; - - RTW_PRINT_SEL(m, "Use VHT rate on 2.4G: %s\n", VHT_2G4_STATUS_STR(a)); + if (pregpriv) { + if (pregpriv->amsdu_mode == RTW_AMSDU_MODE_NON_SPP) + RTW_PRINT_SEL(m, "amsdu mode: NON-SPP\n"); + else if (pregpriv->amsdu_mode == RTW_AMSDU_MODE_SPP) + RTW_PRINT_SEL(m, "amsdu mode: SPP\n"); + else if (pregpriv->amsdu_mode == RTW_AMSDU_MODE_ALL_DROP) + RTW_PRINT_SEL(m, "amsdu mode: ALL DROP\n"); + else + RTW_PRINT_SEL(m, "unexpected amsdu mode\n"); + } return 0; } -static ssize_t proc_set_vht_2g4(struct file *file, const char __user *buffer, - size_t count, loff_t *pos, void *data) +static ssize_t proc_set_amsdu_mode(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) { struct net_device *dev = data; - struct _ADAPTER *a = (_adapter *)rtw_netdev_priv(dev); + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; char tmp[32]; - int num = 0; - int enable = 0; + u32 mode; + u8 bw_2g; + u8 bw_5g; + + if (count < 1) + return -EFAULT; if (count > sizeof(tmp)) { rtw_warn_on(1); return -EFAULT; } - if (!buffer || copy_from_user(tmp, buffer, count)) - goto exit; + if (buffer && !copy_from_user(tmp, buffer, count)) { - num = sscanf(tmp, "%d", &enable); - if (num != 1) { - RTW_ERR("%s: invalid parameter!\n", __FUNCTION__); - goto exit; + int num = sscanf(tmp, "%d", &mode); + + if (mode == RTW_AMSDU_MODE_NON_SPP + || mode == RTW_AMSDU_MODE_SPP + || mode == RTW_AMSDU_MODE_ALL_DROP) { + pregpriv->amsdu_mode = mode; + RTW_INFO("amsdu mode=%u\n", mode); + } else { + RTW_INFO("set unexpected mode = %d, won't apply\n", mode); + } } - RTW_PRINT("%s: Original state of use VHT rate on 2.4G: %s\n", - __FUNCTION__, VHT_2G4_STATUS_STR(a)); - rtw_set_vht_2g4(a, enable); - RTW_PRINT("%s: New state of use VHT rate on 2.4G: %s\n", - __FUNCTION__, VHT_2G4_STATUS_STR(a)); - -exit: return count; + } /* @@ -4422,15 +5279,24 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { RTW_PROC_HDL_SSEQ("roam_param", proc_get_roam_param, proc_set_roam_param), RTW_PROC_HDL_SSEQ("roam_tgt_addr", NULL, proc_set_roam_tgt_addr), #endif /* CONFIG_LAYER2_ROAMING */ - -#ifdef CONFIG_RTW_80211R - RTW_PROC_HDL_SSEQ("ft_flags", proc_get_ft_flags, proc_set_ft_flags), +#ifdef CONFIG_RTW_MBO + RTW_PROC_HDL_SSEQ("non_pref_ch", rtw_mbo_proc_non_pref_chans_get, rtw_mbo_proc_non_pref_chans_set), + RTW_PROC_HDL_SSEQ("cell_data", rtw_mbo_proc_cell_data_get, rtw_mbo_proc_cell_data_set), #endif - +#ifdef CONFIG_RTW_80211R + RTW_PROC_HDL_SSEQ("ft_flags", rtw_ft_proc_flags_get, rtw_ft_proc_flags_set), +#endif + RTW_PROC_HDL_SSEQ("defs_param", proc_get_defs_param, proc_set_defs_param), #ifdef CONFIG_SDIO_HCI RTW_PROC_HDL_SSEQ("sd_f0_reg_dump", proc_get_sd_f0_reg_dump, NULL), RTW_PROC_HDL_SSEQ("sdio_local_reg_dump", proc_get_sdio_local_reg_dump, NULL), RTW_PROC_HDL_SSEQ("sdio_card_info", proc_get_sdio_card_info, NULL), + #ifdef CONFIG_SDIO_RECVBUF_AGGREGATION + RTW_PROC_HDL_SSEQ("sdio_recvbuf_aggregation", proc_get_sdio_recvbuf_aggregation, proc_set_sdio_recvbuf_aggregation), + #endif + #ifdef CONFIG_SDIO_RECVBUF_PWAIT + RTW_PROC_HDL_SSEQ("sdio_recvbuf_pwait", proc_get_sdio_recvbuf_pwait, proc_set_sdio_recvbuf_pwait), + #endif #ifdef DBG_SDIO RTW_PROC_HDL_SSEQ("sdio_dbg", proc_get_sdio_dbg, proc_set_sdio_dbg), #endif /* DBG_SDIO */ @@ -4458,6 +5324,9 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { RTW_PROC_HDL_SSEQ("ap_isolate", proc_get_ap_isolate, proc_set_ap_isolate), RTW_PROC_HDL_SSEQ("all_sta_info", proc_get_all_sta_info, NULL), RTW_PROC_HDL_SSEQ("bmc_tx_rate", proc_get_bmc_tx_rate, proc_set_bmc_tx_rate), + #if CONFIG_RTW_AP_DATA_BMC_TO_UC + RTW_PROC_HDL_SSEQ("ap_b2u_flags", proc_get_ap_b2u_flags, proc_set_ap_b2u_flags), + #endif #endif /* CONFIG_AP_MODE */ #ifdef DBG_MEMORY_LEAK @@ -4482,12 +5351,22 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { RTW_PROC_HDL_SSEQ("rx_ampdu_density", proc_get_rx_ampdu_density, proc_set_rx_ampdu_density), RTW_PROC_HDL_SSEQ("tx_ampdu_density", proc_get_tx_ampdu_density, proc_set_tx_ampdu_density), RTW_PROC_HDL_SSEQ("tx_max_agg_num", proc_get_tx_max_agg_num, proc_set_tx_max_agg_num), + RTW_PROC_HDL_SSEQ("tx_quick_addba_req", proc_get_tx_quick_addba_req, proc_set_tx_quick_addba_req), #ifdef CONFIG_TX_AMSDU RTW_PROC_HDL_SSEQ("tx_amsdu", proc_get_tx_amsdu, proc_set_tx_amsdu), RTW_PROC_HDL_SSEQ("tx_amsdu_rate", proc_get_tx_amsdu_rate, proc_set_tx_amsdu_rate), #endif #endif /* CONFIG_80211N_HT */ +#ifdef CONFIG_80211AC_VHT + RTW_PROC_HDL_SSEQ("vht_24g_enable", proc_get_vht_24g_enable, proc_set_vht_24g_enable), +#endif + + #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT + RTW_PROC_HDL_SSEQ("tx_aval_int_threshold", proc_get_tx_aval_th, proc_set_tx_aval_th), + #endif + + RTW_PROC_HDL_SSEQ("dynamic_rrsr", proc_get_dyn_rrsr, proc_set_dyn_rrsr), RTW_PROC_HDL_SSEQ("en_fwps", proc_get_en_fwps, proc_set_en_fwps), /* RTW_PROC_HDL_SSEQ("path_rssi", proc_get_two_path_rssi, NULL), @@ -4556,6 +5435,7 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { #endif #ifdef CONFIG_WOWLAN + RTW_PROC_HDL_SSEQ("wow_enable", proc_get_wow_enable, proc_set_wow_enable), RTW_PROC_HDL_SSEQ("wow_pattern_info", proc_get_pattern_info, proc_set_pattern_info), RTW_PROC_HDL_SSEQ("wow_wakeup_event", proc_get_wakeup_event, proc_set_wakeup_event), @@ -4563,6 +5443,10 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { #ifdef CONFIG_WOW_PATTERN_HW_CAM RTW_PROC_HDL_SSEQ("wow_pattern_cam", proc_dump_pattern_cam, NULL), #endif +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + RTW_PROC_HDL_SSEQ("wow_keep_alive_info", proc_dump_wow_keep_alive_info, NULL), +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + #endif #ifdef CONFIG_GPIO_WAKEUP @@ -4573,6 +5457,9 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { #endif RTW_PROC_HDL_SSEQ("country_code", proc_get_country_code, proc_set_country_code), RTW_PROC_HDL_SSEQ("chan_plan", proc_get_chan_plan, proc_set_chan_plan), + RTW_PROC_HDL_SSEQ("cap_spt_op_class_ch", proc_get_cap_spt_op_class_ch, proc_set_cap_spt_op_class_ch), + RTW_PROC_HDL_SSEQ("reg_spt_op_class_ch", proc_get_reg_spt_op_class_ch, proc_set_reg_spt_op_class_ch), + RTW_PROC_HDL_SSEQ("cur_spt_op_class_ch", proc_get_cur_spt_op_class_ch, proc_set_cur_spt_op_class_ch), #if CONFIG_RTW_MACADDR_ACL RTW_PROC_HDL_SSEQ("macaddr_acl", proc_get_macaddr_acl, proc_set_macaddr_acl), #endif @@ -4584,6 +5471,7 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { RTW_PROC_HDL_SSEQ("dfs_test_case", proc_get_dfs_test_case, proc_set_dfs_test_case), RTW_PROC_HDL_SSEQ("update_non_ocp", NULL, proc_set_update_non_ocp), RTW_PROC_HDL_SSEQ("radar_detect", NULL, proc_set_radar_detect), + RTW_PROC_HDL_SSEQ("dfs_ch_sel_e_flags", proc_get_dfs_ch_sel_e_flags, proc_set_dfs_ch_sel_e_flags), RTW_PROC_HDL_SSEQ("dfs_ch_sel_d_flags", proc_get_dfs_ch_sel_d_flags, proc_set_dfs_ch_sel_d_flags), #if CONFIG_DFS_SLAVE_WITH_RADAR_DETECT RTW_PROC_HDL_SSEQ("dfs_slave_with_rd", proc_get_dfs_slave_with_rd, proc_set_dfs_slave_with_rd), @@ -4596,7 +5484,9 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { #ifdef DBG_RX_COUNTER_DUMP RTW_PROC_HDL_SSEQ("dump_rx_cnt_mode", proc_get_rx_cnt_dump, proc_set_rx_cnt_dump), #endif +#ifdef CONFIG_AP_MODE RTW_PROC_HDL_SSEQ("change_bss_chbw", NULL, proc_set_change_bss_chbw), +#endif #if CONFIG_TX_AC_LIFETIME RTW_PROC_HDL_SSEQ("tx_aclt_force_val", proc_get_tx_aclt_force_val, proc_set_tx_aclt_force_val), RTW_PROC_HDL_SSEQ("tx_aclt_flags", proc_get_tx_aclt_flags, proc_set_tx_aclt_flags), @@ -4609,6 +5499,8 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { #if CONFIG_TXPWR_LIMIT RTW_PROC_HDL_SSEQ("tx_power_limit", proc_get_tx_power_limit, NULL), #endif + RTW_PROC_HDL_SSEQ("tpc_settings", proc_get_tpc_settings, proc_set_tpc_settings), + RTW_PROC_HDL_SSEQ("antenna_gain", proc_get_antenna_gain, proc_set_antenna_gain), RTW_PROC_HDL_SSEQ("tx_power_ext_info", proc_get_tx_power_ext_info, proc_set_tx_power_ext_info), RTW_PROC_HDL_SEQ("tx_power_idx", &seq_ops_tx_power_idx, proc_set_tx_power_idx_dump), RTW_PROC_HDL_SEQ("txpwr_total_dbm", &seq_ops_txpwr_total_dbm, proc_set_txpwr_total_dbm_dump), @@ -4629,6 +5521,9 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { RTW_PROC_HDL_SSEQ("tdls_enable", proc_get_tdls_enable, proc_set_tdls_enable), #endif RTW_PROC_HDL_SSEQ("monitor", proc_get_monitor, proc_set_monitor), +#ifdef RTW_SIMPLE_CONFIG + RTW_PROC_HDL_SSEQ("rtw_simple_config", proc_get_simple_config, proc_set_simple_config), +#endif #ifdef CONFIG_RTW_ACS RTW_PROC_HDL_SSEQ("acs", proc_get_best_chan, proc_set_acs), @@ -4699,6 +5594,25 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { RTW_PROC_HDL_SSEQ("dynamic_agg_enable", proc_get_dynamic_agg_enable, proc_set_dynamic_agg_enable), RTW_PROC_HDL_SSEQ("fw_offload", proc_get_fw_offload, proc_set_fw_offload), +#ifdef CONFIG_RTW_WDS + RTW_PROC_HDL_SSEQ("wds_en", proc_get_wds_en, proc_set_wds_en), + RTW_PROC_HDL_SSEQ("sta_wds_en", NULL, proc_set_sta_wds_en), + RTW_PROC_HDL_SSEQ("wds_gptr", proc_get_wds_gptr, NULL), + #ifdef CONFIG_AP_MODE + RTW_PROC_HDL_SSEQ("wds_path", proc_get_wds_path, NULL), + #endif +#endif + +#ifdef CONFIG_RTW_MULTI_AP + RTW_PROC_HDL_SSEQ("multi_ap_opmode", proc_get_multi_ap_opmode, proc_set_multi_ap_opmode), + RTW_PROC_HDL_SSEQ("unassoc_sta", proc_get_unassoc_sta, proc_set_unassoc_sta), +#ifdef CONFIG_IOCTL_CFG80211 + RTW_PROC_HDL_SSEQ("sta_assoc_req_frame_body", proc_get_sta_assoc_req_frame_body, proc_set_sta_assoc_req_frame_body), +#endif + RTW_PROC_HDL_SSEQ("ch_util_threshold", proc_get_ch_util_threshold, proc_set_ch_util_threshold), + RTW_PROC_HDL_SSEQ("ch_utilization", proc_get_ch_utilization, NULL), +#endif + #ifdef CONFIG_RTW_MESH #if CONFIG_RTW_MESH_ACNODE_PREVENT RTW_PROC_HDL_SSEQ("mesh_acnode_prevent", proc_get_mesh_acnode_prevent, proc_set_mesh_acnode_prevent), @@ -4737,6 +5651,10 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { RTW_PROC_HDL_SSEQ("smps", proc_get_smps, proc_set_smps), #endif +#ifdef RTW_BUSY_DENY_SCAN + RTW_PROC_HDL_SSEQ("scan_interval_thr", proc_get_scan_interval_thr, \ + proc_set_scan_interval_thr), +#endif RTW_PROC_HDL_SSEQ("scan_deny", proc_get_scan_deny, proc_set_scan_deny), #ifdef CONFIG_RTW_TPT_MODE RTW_PROC_HDL_SSEQ("tpt_mode", proc_get_tpt_mode, proc_set_tpt_mode), @@ -4751,7 +5669,19 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { RTW_PROC_HDL_SSEQ("cur_beacon_keys", proc_get_cur_beacon_keys, NULL), - RTW_PROC_HDL_SSEQ("vht_2g4", proc_get_vht_2g4, proc_set_vht_2g4), +#ifdef CONFIG_WAR_OFFLOAD + RTW_PROC_HDL_SSEQ("war_offload_enable", proc_get_war_offload_enable, proc_set_war_offload_enable), + RTW_PROC_HDL_SSEQ("war_offload_ipv4_addr", NULL, proc_set_war_offload_ipv4_addr), + RTW_PROC_HDL_SSEQ("war_offload_ipv6_addr", NULL, proc_set_war_offload_ipv6_addr), +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) + RTW_PROC_HDL_SSEQ("war_offload_mdns_domain_name", proc_get_war_offload_mdns_domain_name, proc_set_war_offload_mdns_domain_name), + RTW_PROC_HDL_SSEQ("war_offload_mdns_machine_name", proc_get_war_offload_mdns_machine_name, proc_set_war_offload_mdns_machine_name), + RTW_PROC_HDL_SSEQ("war_offload_mdns_service_info", proc_get_war_offload_mdns_service_info, proc_set_war_offload_mdns_service_info), + RTW_PROC_HDL_SSEQ("war_offload_mdns_service_info_txt_rsp", proc_get_war_offload_mdns_txt_rsp, proc_set_war_offload_mdns_txt_rsp), +#endif /* CONFIG_OFFLOAD_MDNS_V4 || CONFIG_OFFLOAD_MDNS_V6 */ +#endif /* CONFIG_WAR_OFFLOAD */ + RTW_PROC_HDL_SSEQ("rtw_amsdu_mode", proc_get_amsdu_mode, proc_set_amsdu_mode), + }; const int adapter_proc_hdls_num = sizeof(adapter_proc_hdls) / sizeof(struct rtw_proc_hdl); diff --git a/os_dep/linux/rtw_rhashtable.c b/os_dep/linux/rtw_rhashtable.c index 2820e7b..df303b2 100644 --- a/os_dep/linux/rtw_rhashtable.c +++ b/os_dep/linux/rtw_rhashtable.c @@ -13,10 +13,10 @@ * *****************************************************************************/ -#ifdef CONFIG_RTW_MESH /* for now, only promised for kernel versions we support mesh */ - #include +#if defined(CONFIG_RTW_WDS) || defined(CONFIG_RTW_MESH) /* for now, only promised for kernel versions we support mesh */ + int rtw_rhashtable_walk_enter(rtw_rhashtable *ht, rtw_rhashtable_iter *iter) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) @@ -73,5 +73,5 @@ void kvfree(const void *addr) #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)) */ -#endif /* CONFIG_RTW_MESH */ +#endif /* defined(CONFIG_RTW_WDS) || defined(CONFIG_RTW_MESH) */ diff --git a/os_dep/linux/rtw_rhashtable.h b/os_dep/linux/rtw_rhashtable.h index 699d5a2..af5ba7e 100644 --- a/os_dep/linux/rtw_rhashtable.h +++ b/os_dep/linux/rtw_rhashtable.h @@ -15,7 +15,7 @@ #ifndef __RTW_RHASHTABLE_H__ #define __RTW_RHASHTABLE_H__ -#ifdef CONFIG_RTW_MESH /* for now, only promised for kernel versions we support mesh */ +#if defined(CONFIG_RTW_WDS) || defined(CONFIG_RTW_MESH) /* for now, only promised for kernel versions we support mesh */ /* directly reference rhashtable in kernel */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) @@ -27,6 +27,14 @@ #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) #define NULLS_MARKER(value) (1UL | (((long)value) << 1)) #endif +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) +static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) +{ + if (size != 0 && n > ULONG_MAX / size) + return NULL; + return __kmalloc(n * size, flags); +} +#endif #include "rhashtable.h" #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)) */ @@ -53,7 +61,7 @@ int rtw_rhashtable_walk_enter(rtw_rhashtable *ht, rtw_rhashtable_iter *iter); #define rtw_rhashtable_lookup_insert_fast(ht, obj, params) rhashtable_lookup_insert_fast((ht), (obj), (params)) #define rtw_rhashtable_remove_fast(ht, obj, params) rhashtable_remove_fast((ht), (obj), (params)) -#endif /* CONFIG_RTW_MESH */ +#endif /* defined(CONFIG_RTW_WDS) || defined(CONFIG_RTW_MESH) */ #endif /* __RTW_RHASHTABLE_H__ */ diff --git a/os_dep/linux/usb_intf.c b/os_dep/linux/usb_intf.c old mode 100755 new mode 100644 index 57b45d2..b1094c7 --- a/os_dep/linux/usb_intf.c +++ b/os_dep/linux/usb_intf.c @@ -62,7 +62,7 @@ static void rtw_dev_shutdown(struct device *dev) #ifdef CONFIG_GPIO_WAKEUP /*default wake up pin change to BT*/ RTW_INFO("%s:default wake up pin change to BT\n", __FUNCTION__); - rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _FALSE); + rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _FALSE); #endif /* CONFIG_GPIO_WAKEUP */ if (pwrctl->wowlan_mode == _TRUE) @@ -70,6 +70,10 @@ static void rtw_dev_shutdown(struct device *dev) else #endif { + #ifdef CONFIG_BT_COEXIST + RTW_INFO("%s call halt notify\n", __FUNCTION__); + rtw_btcoex_HaltNotify(adapter); + #endif rtw_hal_deinit(adapter); rtw_set_surprise_removed(adapter); } @@ -135,6 +139,7 @@ static void rtw_dev_shutdown(struct device *dev) #endif +#define USB_VENDER_ID_EDOMAX 0x7392 #define USB_VENDER_ID_REALTEK 0x0BDA @@ -238,19 +243,8 @@ static struct usb_device_id rtw_usb_id_tbl[] = { {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0xB812, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* Default ID for USB Single-function, WiFi only */ /*=== Customer ID ===*/ {USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* Alpha - Alpha*/ - {USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1841, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* ASUS AC1300 USB-AC55 B1 */ - {USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x184C, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* ASUS U2*/ - {USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x19AA, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* ASUS USB-AC58 */ - {USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xB822, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* Edimax EW-7822ULC */ - {USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xC822, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* Edimax EW-7822UTC */ - {USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xF822, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* Edimax EW-7822UAD */ - {USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331e, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* Dlink - DWA-181*/ - {USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331c, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* Dlink - DWA-182*/ - {USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9055, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* NetGear A6150 */ - {USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012D, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* TP-Link Archer T3U */ - {USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0138, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* TP-Link Archer T3U Plus */ - {USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0115, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* TP-Link Archer T4U V3 */ - {USB_DEVICE_AND_INTERFACE_INFO(0x20F4, 0x808A, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* TRENDnet TEW-808UBM */ + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_EDOMAX, 0xB822, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* Edimax */ + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_EDOMAX, 0xC822, 0xff, 0xff, 0xff), .driver_info = RTL8822B}, /* Edimax */ #endif /* CONFIG_RTL8822B */ #ifdef CONFIG_RTL8723D @@ -273,7 +267,9 @@ static struct usb_device_id rtw_usb_id_tbl[] = { {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0xC82A, 0xff, 0xff, 0xff), .driver_info = RTL8821C}, /* 8821CU */ {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0xC82B, 0xff, 0xff, 0xff), .driver_info = RTL8821C}, /* 8821CU */ {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0xC811, 0xff, 0xff, 0xff), .driver_info = RTL8821C}, /* 8811CU */ - {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x8811, 0xff, 0xff, 0xff), .driver_info = RTL8821C}, /* 8811CU */ + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x8811, 0xff, 0xff, 0xff), .driver_info = RTL8821C}, /* 8811CU */ + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x8731, 0xff, 0xff, 0xff), .driver_info = RTL8821C}, /* 8731AU */ + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0xC80C, 0xff, 0xff, 0xff), .driver_info = RTL8821C}, /* 8821CUH */ /*=== Customer ID ===*/ #endif @@ -285,7 +281,10 @@ static struct usb_device_id rtw_usb_id_tbl[] = { #ifdef CONFIG_RTL8822C /*=== Realtek demoboard ===*/ {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0xC82C, 0xff, 0xff, 0xff), .driver_info = RTL8822C}, /* Default ID for USB multi-function */ + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0xC82E, 0xff, 0xff, 0xff), .driver_info = RTL8822C}, /* Default ID for USB multi-function */ {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0xC812, 0xff, 0xff, 0xff), .driver_info = RTL8822C}, /* Default ID for USB Single-function, WiFi only */ + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0xD820, 0xff, 0xff, 0xff), .driver_info = RTL8822C}, /* 21D USB multi-fuction*/ + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0xD82B, 0xff, 0xff, 0xff), .driver_info = RTL8822C}, /* 21D USB Single-fuction, WiFi only*/ /*=== Customer ID ===*/ {USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff), .driver_info = RTL8822C}, /* Alpha - Alpha*/ #endif /* CONFIG_RTL8822C */ @@ -294,6 +293,10 @@ static struct usb_device_id rtw_usb_id_tbl[] = { /*=== Realtek demoboard ===*/ {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0xB814, 0xff, 0xff, 0xff), .driver_info = RTL8814B}, /* Default ID for USB multi-function */ #endif /* CONFIG_RTL8814B */ +#ifdef CONFIG_RTL8723F + /*=== Realtek IC ===*/ + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0xB733, 0xff, 0xff, 0xff), .driver_info = RTL8723F}, +#endif {} /* Terminating entry */ }; @@ -331,9 +334,6 @@ struct rtw_usb_drv usb_drv = { #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22)) .usbdrv.reset_resume = rtw_resume, #endif -#ifdef CONFIG_AUTOSUSPEND - .usbdrv.supports_autosuspend = 1, -#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)) .usbdrv.drvwrap.driver.shutdown = rtw_dev_shutdown, @@ -500,6 +500,11 @@ static void rtw_decide_chip_type_by_usb_info(struct dvobj_priv *pdvobjpriv, cons if (pdvobjpriv->chip_type == RTL8814B) rtl8814bu_set_hw_type(pdvobjpriv); #endif /* CONFIG_RTL8814B */ + +#ifdef CONFIG_RTL8723F + if (pdvobjpriv->chip_type == RTL8723F) + rtl8723fu_set_hw_type(pdvobjpriv); +#endif /* CONFIG_RTL8723F */ } static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf, const struct usb_device_id *pdid) @@ -777,6 +782,10 @@ u8 rtw_set_hal_ops(_adapter *padapter) rtl8814bu_set_hal_ops(padapter); #endif /* CONFIG_RTL8814B */ +#ifdef CONFIG_RTL8723F + if (rtw_get_chip_type(padapter) == RTL8723F) + rtl8723fu_set_hal_ops(padapter); +#endif /* CONFIG_RTL8723F */ if (_FAIL == rtw_hal_ops_check(padapter)) return _FAIL; @@ -893,8 +902,8 @@ int rtw_hw_suspend(_adapter *padapter) /* rtw_indicate_disconnect(padapter); */ { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - _clr_fwstate_(pmlmepriv, _FW_LINKED); + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) { + _clr_fwstate_(pmlmepriv, WIFI_ASOC_STATE); rtw_led_control(padapter, LED_CTL_NO_LINK); rtw_os_indicate_disconnect(padapter, 0, _FALSE); @@ -980,21 +989,6 @@ static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) goto exit; } - if ((padapter->bup) || !rtw_is_drv_stopped(padapter) || !rtw_is_surprise_removed(padapter)) { -#ifdef CONFIG_AUTOSUSPEND - if (pwrpriv->bInternalAutoSuspend) { - -#ifdef SUPPORT_HW_RFOFF_DETECTED - /* The FW command register update must after MAC and FW init ready. */ - if ((GET_HAL_DATA(padapter)->bFWReady) && (pwrpriv->bHWPwrPindetect) && (padapter->registrypriv.usbss_enable)) { - u8 bOpen = _TRUE; - rtw_interface_ps_func(padapter, HAL_USB_SELECT_SUSPEND, &bOpen); - } -#endif/* SUPPORT_HW_RFOFF_DETECTED */ - } -#endif/* CONFIG_AUTOSUSPEND */ - } - ret = rtw_suspend_common(padapter); exit: @@ -1004,9 +998,6 @@ exit: int rtw_resume_process(_adapter *padapter) { int ret; -#if defined(CONFIG_BT_COEXIST) && defined(CONFIG_AUTOSUSPEND) - int pm_cnt = 0; -#endif struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); struct dvobj_priv *pdvobj = padapter->dvobj; struct debug_priv *pdbgpriv = &pdvobj->drv_dbg; @@ -1018,24 +1009,6 @@ int rtw_resume_process(_adapter *padapter) return -1; } -#if defined(CONFIG_BT_COEXIST) && defined(CONFIG_AUTOSUSPEND) /* add by amy for 8723as-vau */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)) - RTW_INFO("%s...pm_usage_cnt(%d) pwrpriv->bAutoResume=%x. ....\n", __func__, atomic_read(&(adapter_to_dvobj(padapter)->pusbintf->pm_usage_cnt)), pwrpriv->bAutoResume); - pm_cnt = atomic_read(&(adapter_to_dvobj(padapter)->pusbintf->pm_usage_cnt)); -#else /* kernel < 2.6.32 */ - RTW_INFO("...pm_usage_cnt(%d).....\n", adapter_to_dvobj(padapter)->pusbintf->pm_usage_cnt); - pm_cnt = adapter_to_dvobj(padapter)->pusbintf->pm_usage_cnt; -#endif /* kernel < 2.6.32 */ - - RTW_INFO("pwrpriv->bAutoResume (%x)\n", pwrpriv->bAutoResume); - if (_TRUE == pwrpriv->bAutoResume) { - pwrpriv->bInternalAutoSuspend = _FALSE; - pwrpriv->bAutoResume = _FALSE; - RTW_INFO("pwrpriv->bAutoResume (%x) pwrpriv->bInternalAutoSuspend(%x)\n", pwrpriv->bAutoResume, pwrpriv->bInternalAutoSuspend); - - } -#endif /* #ifdef CONFIG_BT_COEXIST &CONFIG_AUTOSUSPEND& */ - /* * Due to usb wow suspend flow will cancel read/write port via intf_stop and * bReadPortCancel and bWritePortCancel are set _TRUE in intf_stop. @@ -1047,31 +1020,6 @@ int rtw_resume_process(_adapter *padapter) ret = rtw_resume_common(padapter); -#ifdef CONFIG_AUTOSUSPEND - if (pwrpriv->bInternalAutoSuspend) { -#ifdef SUPPORT_HW_RFOFF_DETECTED - /* The FW command register update must after MAC and FW init ready. */ - if ((GET_HAL_DATA(padapter)->bFWReady) && (pwrpriv->bHWPwrPindetect) && (padapter->registrypriv.usbss_enable)) { - u8 bOpen = _FALSE; - rtw_interface_ps_func(padapter, HAL_USB_SELECT_SUSPEND, &bOpen); - } -#endif -#ifdef CONFIG_BT_COEXIST /* for 8723as-vau */ - RTW_INFO("pwrpriv->bAutoResume (%x)\n", pwrpriv->bAutoResume); - if (_TRUE == pwrpriv->bAutoResume) { - pwrpriv->bInternalAutoSuspend = _FALSE; - pwrpriv->bAutoResume = _FALSE; - RTW_INFO("pwrpriv->bAutoResume (%x) pwrpriv->bInternalAutoSuspend(%x)\n", pwrpriv->bAutoResume, pwrpriv->bInternalAutoSuspend); - } - -#else /* #ifdef CONFIG_BT_COEXIST */ - pwrpriv->bInternalAutoSuspend = _FALSE; -#endif /* #ifdef CONFIG_BT_COEXIST */ - pwrpriv->brfoffbyhw = _FALSE; - } -#endif/* CONFIG_AUTOSUSPEND */ - - return ret; } @@ -1094,30 +1042,24 @@ static int rtw_resume(struct usb_interface *pusb_intf) RTW_INFO("==> %s (%s:%d)\n", __FUNCTION__, current->comm, current->pid); pdbgpriv->dbg_resume_cnt++; - #ifdef CONFIG_AUTOSUSPEND - if (pwrpriv->bInternalAutoSuspend) + + if (pwrpriv->wowlan_mode || pwrpriv->wowlan_ap_mode) { + rtw_resume_lock_suspend(); ret = rtw_resume_process(padapter); - else - #endif - { - if (pwrpriv->wowlan_mode || pwrpriv->wowlan_ap_mode) { + rtw_resume_unlock_suspend(); + } else { +#ifdef CONFIG_RESUME_IN_WORKQUEUE + rtw_resume_in_workqueue(pwrpriv); +#else + if (rtw_is_earlysuspend_registered(pwrpriv)) { + /* jeff: bypass resume here, do in late_resume */ + rtw_set_do_late_resume(pwrpriv, _TRUE); + } else { rtw_resume_lock_suspend(); ret = rtw_resume_process(padapter); rtw_resume_unlock_suspend(); - } else { -#ifdef CONFIG_RESUME_IN_WORKQUEUE - rtw_resume_in_workqueue(pwrpriv); -#else - if (rtw_is_earlysuspend_registered(pwrpriv)) { - /* jeff: bypass resume here, do in late_resume */ - rtw_set_do_late_resume(pwrpriv, _TRUE); - } else { - rtw_resume_lock_suspend(); - ret = rtw_resume_process(padapter); - rtw_resume_unlock_suspend(); - } -#endif } +#endif } pmlmeext->last_scan_time = rtw_get_current_time(); @@ -1127,124 +1069,6 @@ static int rtw_resume(struct usb_interface *pusb_intf) } - -#ifdef CONFIG_AUTOSUSPEND -void autosuspend_enter(_adapter *padapter) -{ - struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); - struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); - - RTW_INFO("==>autosuspend_enter...........\n"); - - pwrpriv->bInternalAutoSuspend = _TRUE; - pwrpriv->bips_processing = _TRUE; - - if (rf_off == pwrpriv->change_rfpwrstate) { -#ifndef CONFIG_BT_COEXIST -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) - usb_enable_autosuspend(dvobj->pusbdev); -#else - dvobj->pusbdev->autosuspend_disabled = 0;/* autosuspend disabled by the user */ -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) - usb_autopm_put_interface(dvobj->pusbintf); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)) - usb_autopm_enable(dvobj->pusbintf); -#else - usb_autosuspend_device(dvobj->pusbdev, 1); -#endif -#else /* #ifndef CONFIG_BT_COEXIST */ - if (1 == pwrpriv->autopm_cnt) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) - usb_enable_autosuspend(dvobj->pusbdev); -#else - dvobj->pusbdev->autosuspend_disabled = 0;/* autosuspend disabled by the user */ -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) - usb_autopm_put_interface(dvobj->pusbintf); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)) - usb_autopm_enable(dvobj->pusbintf); -#else - usb_autosuspend_device(dvobj->pusbdev, 1); -#endif - pwrpriv->autopm_cnt--; - } else - RTW_INFO("0!=pwrpriv->autopm_cnt[%d] didn't usb_autopm_put_interface\n", pwrpriv->autopm_cnt); - -#endif /* #ifndef CONFIG_BT_COEXIST */ - } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)) - RTW_INFO("...pm_usage_cnt(%d).....\n", atomic_read(&(dvobj->pusbintf->pm_usage_cnt))); -#else - RTW_INFO("...pm_usage_cnt(%d).....\n", dvobj->pusbintf->pm_usage_cnt); -#endif - -} - -int autoresume_enter(_adapter *padapter) -{ - int result = _SUCCESS; - struct security_priv *psecuritypriv = &(padapter->securitypriv); - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); - struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); - - RTW_INFO("====> autoresume_enter\n"); - - if (rf_off == pwrpriv->rf_pwrstate) { - pwrpriv->ps_flag = _FALSE; -#ifndef CONFIG_BT_COEXIST -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) - if (usb_autopm_get_interface(dvobj->pusbintf) < 0) { - RTW_INFO("can't get autopm: %d\n", result); - result = _FAIL; - goto error_exit; - } -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)) - usb_autopm_disable(dvobj->pusbintf); -#else - usb_autoresume_device(dvobj->pusbdev, 1); -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)) - RTW_INFO("...pm_usage_cnt(%d).....\n", atomic_read(&(dvobj->pusbintf->pm_usage_cnt))); -#else - RTW_INFO("...pm_usage_cnt(%d).....\n", dvobj->pusbintf->pm_usage_cnt); -#endif -#else /* #ifndef CONFIG_BT_COEXIST */ - pwrpriv->bAutoResume = _TRUE; - if (0 == pwrpriv->autopm_cnt) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) - if (usb_autopm_get_interface(dvobj->pusbintf) < 0) { - RTW_INFO("can't get autopm: %d\n", result); - result = _FAIL; - goto error_exit; - } -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)) - usb_autopm_disable(dvobj->pusbintf); -#else - usb_autoresume_device(dvobj->pusbdev, 1); -#endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)) - RTW_INFO("...pm_usage_cnt(%d).....\n", atomic_read(&(dvobj->pusbintf->pm_usage_cnt))); -#else - RTW_INFO("...pm_usage_cnt(%d).....\n", dvobj->pusbintf->pm_usage_cnt); -#endif - pwrpriv->autopm_cnt++; - } else - RTW_INFO("0!=pwrpriv->autopm_cnt[%d] didn't usb_autopm_get_interface\n", pwrpriv->autopm_cnt); -#endif /* #ifndef CONFIG_BT_COEXIST */ - } - RTW_INFO("<==== autoresume_enter\n"); -error_exit: - - return result; -} -#endif - #ifdef CONFIG_PLATFORM_RTD2880B extern void rtd2885_wlan_netlink_sendMsg(char *action_string, char *name); #endif @@ -1327,33 +1151,6 @@ _adapter *rtw_usb_primary_adapter_init(struct dvobj_priv *dvobj, RTW_INFO("pwrctrlpriv.bSupportRemoteWakeup~~~[%d]~~~\n", device_may_wakeup(&pusb_intf->dev)); } #endif -#endif - -#ifdef CONFIG_AUTOSUSPEND - if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE) { - if (padapter->registrypriv.usbss_enable) { /* autosuspend (2s delay) */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) - dvobj->pusbdev->dev.power.autosuspend_delay = 0 * HZ;/* 15 * HZ; idle-delay time */ -#else - dvobj->pusbdev->autosuspend_delay = 0 * HZ;/* 15 * HZ; idle-delay time */ -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) - usb_enable_autosuspend(dvobj->pusbdev); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)) - padapter->bDisableAutosuspend = dvobj->pusbdev->autosuspend_disabled ; - dvobj->pusbdev->autosuspend_disabled = 0;/* autosuspend disabled by the user */ -#endif - - /* usb_autopm_get_interface(adapter_to_dvobj(padapter)->pusbintf ); */ /* init pm_usage_cnt ,let it start from 1 */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)) - RTW_INFO("%s...pm_usage_cnt(%d).....\n", __FUNCTION__, atomic_read(&(dvobj->pusbintf->pm_usage_cnt))); -#else - RTW_INFO("%s...pm_usage_cnt(%d).....\n", __FUNCTION__, dvobj->pusbintf->pm_usage_cnt); -#endif - } - } #endif /* 2012-07-11 Move here to prevent the 8723AS-VAU BT auto suspend influence */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) @@ -1406,7 +1203,7 @@ static void rtw_usb_primary_adapter_deinit(_adapter *padapter) RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); - if (check_fwstate(pmlmepriv, _FW_LINKED)) + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) rtw_disassoc_cmd(padapter, 0, RTW_CMDF_DIRECTLY); #ifdef CONFIG_AP_MODE @@ -1641,6 +1438,10 @@ static int __init rtw_drv_entry(void) usb_drv.drv_registered = _TRUE; rtw_suspend_lock_init(); rtw_drv_proc_init(); + rtw_nlrtw_init(); +#ifdef CONFIG_PLATFORM_CMAP_INTFS + cmap_intfs_init(); +#endif rtw_ndev_notifier_register(); rtw_inetaddr_notifier_register(); @@ -1650,6 +1451,10 @@ static int __init rtw_drv_entry(void) usb_drv.drv_registered = _FALSE; rtw_suspend_lock_uninit(); rtw_drv_proc_deinit(); + rtw_nlrtw_deinit(); +#ifdef CONFIG_PLATFORM_CMAP_INTFS + cmap_intfs_deinit(); +#endif rtw_ndev_notifier_unregister(); rtw_inetaddr_notifier_unregister(); goto exit; @@ -1672,6 +1477,10 @@ static void __exit rtw_drv_halt(void) rtw_suspend_lock_uninit(); rtw_drv_proc_deinit(); + rtw_nlrtw_deinit(); +#ifdef CONFIG_PLATFORM_CMAP_INTFS + cmap_intfs_deinit(); +#endif rtw_ndev_notifier_unregister(); rtw_inetaddr_notifier_unregister(); diff --git a/os_dep/linux/usb_ops_linux.c b/os_dep/linux/usb_ops_linux.c index 9672597..a1cea6a 100644 --- a/os_dep/linux/usb_ops_linux.c +++ b/os_dep/linux/usb_ops_linux.c @@ -410,11 +410,12 @@ void usb_read_port_cancel(struct intf_hdl *pintfhdl) int i; struct recv_buf *precvbuf; _adapter *padapter = pintfhdl->padapter; + struct registry_priv *regsty = adapter_to_regsty(padapter); precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf; RTW_INFO("%s\n", __func__); - for (i = 0; i < NR_RECVBUFF ; i++) { + for (i = 0; i < regsty->recvbuf_nr ; i++) { if (precvbuf->purb) { /* RTW_INFO("usb_read_port_cancel : usb_kill_urb\n"); */ diff --git a/os_dep/linux/wifi_regd.c b/os_dep/linux/wifi_regd.c index c4bfc00..81e1dc7 100644 --- a/os_dep/linux/wifi_regd.c +++ b/os_dep/linux/wifi_regd.c @@ -16,13 +16,10 @@ #include #ifdef CONFIG_IOCTL_CFG80211 -void rtw_regd_apply_flags(struct wiphy *wiphy) +static void rtw_regd_overide_flags(struct wiphy *wiphy, struct rf_ctl_t *rfctl) { - struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy); - struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); RT_CHANNEL_INFO *channel_set = rfctl->channel_set; u8 max_chan_nums = rfctl->max_chan_nums; - struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; unsigned int i, j; @@ -47,13 +44,15 @@ void rtw_regd_apply_flags(struct wiphy *wiphy) channel = channel_set[i].ChannelNum; freq = rtw_ch2freq(channel); ch = ieee80211_get_channel(wiphy, freq); - if (!ch) + if (!ch) { + rtw_warn_on(1); continue; + } /* enable */ ch->flags = 0; - if (channel_set[i].dfs) { + if (channel_set[i].flags & RTW_CHF_DFS) { /* * before integrating with nl80211 flow * bypass IEEE80211_CHAN_RADAR when configured with radar detection @@ -63,7 +62,7 @@ void rtw_regd_apply_flags(struct wiphy *wiphy) ch->flags |= IEEE80211_CHAN_RADAR; } - if (channel_set[i].ScanType == SCAN_PASSIVE) { + if (channel_set[i].flags & RTW_CHF_NO_IR) { #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) ch->flags |= IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_PASSIVE_SCAN; #else @@ -73,26 +72,313 @@ void rtw_regd_apply_flags(struct wiphy *wiphy) } } -static void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) +#ifdef CONFIG_REGD_SRC_FROM_OS +static void rtw_regd_apply_dfs_flags(struct rf_ctl_t *rfctl) { - switch (request->initiator) { - case NL80211_REGDOM_SET_BY_DRIVER: - RTW_INFO("%s: %s\n", __func__, "NL80211_REGDOM_SET_BY_DRIVER"); - break; - case NL80211_REGDOM_SET_BY_CORE: - RTW_INFO("%s: %s\n", __func__, "NL80211_REGDOM_SET_BY_CORE"); - break; - case NL80211_REGDOM_SET_BY_USER: - RTW_INFO("%s: %s alpha2:%c%c\n", __func__, "NL80211_REGDOM_SET_BY_USER" - , request->alpha2[0], request->alpha2[1]); - rtw_set_country(wiphy_to_adapter(wiphy), request->alpha2); - break; - case NL80211_REGDOM_SET_BY_COUNTRY_IE: - RTW_INFO("%s: %s\n", __func__, "NL80211_REGDOM_SET_BY_COUNTRY_IE"); - break; + RT_CHANNEL_INFO *channel_set = rfctl->channel_set; + u8 max_chan_nums = rfctl->max_chan_nums; + unsigned int i; + struct ieee80211_channel *chan; + + /* channels apply by channel plans. */ + for (i = 0; i < max_chan_nums; i++) { + chan = channel_set[i].os_chan; + if (channel_set[i].flags & RTW_CHF_DFS) { + /* + * before integrating with nl80211 flow + * clear IEEE80211_CHAN_RADAR when configured with radar detection + * to prevent from hostapd blocking DFS channels + */ + if (!rtw_rfctl_dfs_domain_unknown(rfctl)) + chan->flags &= ~IEEE80211_CHAN_RADAR; + } + } +} +#endif + +void rtw_regd_apply_flags(struct wiphy *wiphy) +{ + struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy); + struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); + + if (rfctl->regd_src == REGD_SRC_RTK_PRIV) + rtw_regd_overide_flags(wiphy, rfctl); +#ifdef CONFIG_REGD_SRC_FROM_OS + else if (rfctl->regd_src == REGD_SRC_OS) + rtw_regd_apply_dfs_flags(rfctl); +#endif + else + rtw_warn_on(1); +} + +#ifdef CONFIG_REGD_SRC_FROM_OS +/* init_channel_set_from_wiphy */ +u8 rtw_os_init_channel_set(_adapter *padapter, RT_CHANNEL_INFO *channel_set) +{ + struct wiphy *wiphy = adapter_to_wiphy(padapter); + struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); + struct registry_priv *regsty = adapter_to_regsty(padapter); + struct ieee80211_channel *chan; + u8 chanset_size = 0; + int i, j; + + _rtw_memset(channel_set, 0, sizeof(RT_CHANNEL_INFO) * MAX_CHANNEL_NUM); + + for (i = NL80211_BAND_2GHZ; i <= NL80211_BAND_5GHZ; i++) { + if (!wiphy->bands[i]) + continue; + for (j = 0; j < wiphy->bands[i]->n_channels; j++) { + chan = &wiphy->bands[i]->channels[j]; + if (chan->flags & IEEE80211_CHAN_DISABLED) + continue; + if (rtw_regsty_is_excl_chs(regsty, chan->hw_value)) + continue; + + if (chanset_size >= MAX_CHANNEL_NUM) { + RTW_WARN("chset size can't exceed MAX_CHANNEL_NUM(%u)\n", MAX_CHANNEL_NUM); + i = NL80211_BAND_5GHZ + 1; + break; + } + + channel_set[chanset_size].ChannelNum = chan->hw_value; + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) + if (chan->flags & (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_PASSIVE_SCAN)) + #else + if (chan->flags & IEEE80211_CHAN_NO_IR) + #endif + channel_set[chanset_size].flags |= RTW_CHF_NO_IR; + if (chan->flags & IEEE80211_CHAN_RADAR) + channel_set[chanset_size].flags |= RTW_CHF_DFS; + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) + if (chan->flags & IEEE80211_CHAN_NO_HT40PLUS) + channel_set[chanset_size].flags |= RTW_CHF_NO_HT40U; + if (chan->flags & IEEE80211_CHAN_NO_HT40MINUS) + channel_set[chanset_size].flags |= RTW_CHF_NO_HT40L; + #endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) + if (chan->flags & IEEE80211_CHAN_NO_80MHZ) + channel_set[chanset_size].flags |= RTW_CHF_NO_80MHZ; + if (chan->flags & IEEE80211_CHAN_NO_160MHZ) + channel_set[chanset_size].flags |= RTW_CHF_NO_160MHZ; + #endif + channel_set[chanset_size].os_chan = chan; + chanset_size++; + } } - rtw_regd_apply_flags(wiphy); +#if CONFIG_IEEE80211_BAND_5GHZ + #ifdef CONFIG_DFS_MASTER + for (i = 0; i < chanset_size; i++) + channel_set[i].non_ocp_end_time = rtw_get_current_time(); + #endif +#endif /* CONFIG_IEEE80211_BAND_5GHZ */ + + if (chanset_size) + RTW_INFO(FUNC_ADPT_FMT" ch num:%d\n" + , FUNC_ADPT_ARG(padapter), chanset_size); + else + RTW_WARN(FUNC_ADPT_FMT" final chset has no channel\n" + , FUNC_ADPT_ARG(padapter)); + + return chanset_size; +} + +s16 rtw_os_get_total_txpwr_regd_lmt_mbm(_adapter *adapter, u8 cch, enum channel_width bw) +{ + struct wiphy *wiphy = adapter_to_wiphy(adapter); + s16 mbm = UNSPECIFIED_MBM; + u8 *op_chs; + u8 op_ch_num; + u8 i; + u32 freq; + struct ieee80211_channel *ch; + + if (!rtw_get_op_chs_by_cch_bw(cch, bw, &op_chs, &op_ch_num)) + goto exit; + + for (i = 0; i < op_ch_num; i++) { + freq = rtw_ch2freq(op_chs[i]); + ch = ieee80211_get_channel(wiphy, freq); + if (!ch) { + rtw_warn_on(1); + continue; + } + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) + mbm = rtw_min(mbm, ch->max_reg_power * MBM_PDBM); + #else + /* require max_power == 0 (therefore orig_mpwr set to 0) when wiphy registration */ + mbm = rtw_min(mbm, ch->max_power * MBM_PDBM); + #endif + } + +exit: + return mbm; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) +static enum rtw_dfs_regd nl80211_dfs_regions_to_rtw_dfs_region(enum nl80211_dfs_regions region) +{ + switch (region) { + case NL80211_DFS_FCC: + return RTW_DFS_REGD_FCC; + case NL80211_DFS_ETSI: + return RTW_DFS_REGD_ETSI; + case NL80211_DFS_JP: + return RTW_DFS_REGD_MKK; + case NL80211_DFS_UNSET: + default: + return RTW_DFS_REGD_NONE; + } +}; +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) */ +#endif /* CONFIG_REGD_SRC_FROM_OS */ + +#ifdef CONFIG_RTW_DEBUG +static const char *nl80211_reg_initiator_str(enum nl80211_reg_initiator initiator) +{ + switch (initiator) { + case NL80211_REGDOM_SET_BY_DRIVER: + return "DRIVER"; + case NL80211_REGDOM_SET_BY_CORE: + return "CORE"; + case NL80211_REGDOM_SET_BY_USER: + return "USER"; + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + return "COUNTRY_IE"; + } + rtw_warn_on(1); + return "UNKNOWN"; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) +static const char *nl80211_user_reg_hint_type_str(enum nl80211_user_reg_hint_type type) +{ + switch (type) { + case NL80211_USER_REG_HINT_USER: + return "USER"; + case NL80211_USER_REG_HINT_CELL_BASE: + return "CELL_BASE"; + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)) + case NL80211_USER_REG_HINT_INDOOR: + return "INDOOR"; + #endif + } + rtw_warn_on(1); + return "UNKNOWN"; +} +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) +static const char *nl80211_dfs_regions_str(enum nl80211_dfs_regions region) +{ + switch (region) { + case NL80211_DFS_UNSET: + return "UNSET"; + case NL80211_DFS_FCC: + return "FCC"; + case NL80211_DFS_ETSI: + return "ETSI"; + case NL80211_DFS_JP: + return "JP"; + } + rtw_warn_on(1); + return "UNKNOWN"; +}; +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) */ + +static const char *environment_cap_str(enum environment_cap cap) +{ + switch (cap) { + case ENVIRON_ANY: + return "ANY"; + case ENVIRON_INDOOR: + return "INDOOR"; + case ENVIRON_OUTDOOR: + return "OUTDOOR"; + } + rtw_warn_on(1); + return "UNKNOWN"; +} + +static void dump_requlatory_request(void *sel, struct regulatory_request *request) +{ + u8 alpha2_len; + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)) + alpha2_len = 3; + #else + alpha2_len = 2; + #endif + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + RTW_PRINT_SEL(sel, "initiator:%s, wiphy_idx:%d, type:%s\n" + , nl80211_reg_initiator_str(request->initiator) + , request->wiphy_idx + , nl80211_user_reg_hint_type_str(request->user_reg_hint_type)); + #else + RTW_PRINT_SEL(sel, "initiator:%s, wiphy_idx:%d\n" + , nl80211_reg_initiator_str(request->initiator) + , request->wiphy_idx); + #endif + + RTW_PRINT_SEL(sel, "alpha2:%.*s\n", alpha2_len, request->alpha2); + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) + RTW_PRINT_SEL(sel, "dfs_region:%s\n", nl80211_dfs_regions_str(request->dfs_region)); + #endif + + RTW_PRINT_SEL(sel, "intersect:%d\n", request->intersect); + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) + RTW_PRINT_SEL(sel, "processed:%d\n", request->processed); + #endif + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)) + RTW_PRINT_SEL(sel, "country_ie_checksum:0x%08x\n", request->country_ie_checksum); + #endif + + RTW_PRINT_SEL(sel, "country_ie_env:%s\n", environment_cap_str(request->country_ie_env)); +} +#endif /* CONFIG_RTW_DEBUG */ + +static void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) +{ + struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy); + struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); + struct registry_priv *regsty = dvobj_to_regsty(dvobj); + +#ifdef CONFIG_RTW_DEBUG + if (rtw_drv_log_level >= _DRV_INFO_) { + RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy)); + dump_requlatory_request(RTW_DBGDUMP, request); + } +#endif + +#ifdef CONFIG_REGD_SRC_FROM_OS + if (REGSTY_REGD_SRC_FROM_OS(regsty)) { + enum rtw_dfs_regd dfs_region = RTW_DFS_REGD_NONE; + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) + dfs_region = nl80211_dfs_regions_to_rtw_dfs_region(request->dfs_region); + #endif + + /* trigger command to sync regulatory form OS */ + rtw_sync_os_regd_cmd(wiphy_to_adapter(wiphy), RTW_CMDF_WAIT_ACK, request->alpha2, dfs_region); + } else +#endif + { + /* use alpha2 as input to select the corresponding channel plan settings defined by Realtek */ + switch (request->initiator) { + case NL80211_REGDOM_SET_BY_DRIVER: + break; + case NL80211_REGDOM_SET_BY_CORE: + break; + case NL80211_REGDOM_SET_BY_USER: + rtw_set_country(wiphy_to_adapter(wiphy), request->alpha2); + break; + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + break; + } + + rtw_regd_apply_flags(wiphy); + } } #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)) @@ -112,16 +398,16 @@ int rtw_regd_init(struct wiphy *wiphy) #endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) - wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY; wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS; #else - wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS; #endif - rtw_regd_apply_flags(wiphy); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) + wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; +#endif return 0; } diff --git a/os_dep/linux/wifi_regd.h b/os_dep/linux/wifi_regd.h index 94c16a3..4e147fc 100644 --- a/os_dep/linux/wifi_regd.h +++ b/os_dep/linux/wifi_regd.h @@ -17,6 +17,11 @@ #define __WIFI_REGD_H__ void rtw_regd_apply_flags(struct wiphy *wiphy); +#ifdef CONFIG_REGD_SRC_FROM_OS +struct _RT_CHANNEL_INFO; +u8 rtw_os_init_channel_set(_adapter *padapter, struct _RT_CHANNEL_INFO *channel_set); +s16 rtw_os_get_total_txpwr_regd_lmt_mbm(_adapter *adapter, u8 cch, enum channel_width bw); +#endif int rtw_regd_init(struct wiphy *wiphy); #endif /* __WIFI_REGD_H__ */ diff --git a/os_dep/linux/xmit_linux.c b/os_dep/linux/xmit_linux.c index c7d087a..f4f508e 100644 --- a/os_dep/linux/xmit_linux.c +++ b/os_dep/linux/xmit_linux.c @@ -199,13 +199,13 @@ void dump_os_queue(void *sel, _adapter *padapter) #define WMM_XMIT_THRESHOLD (NR_XMITFRAME*2/5) -static inline bool rtw_os_need_wake_queue(_adapter *padapter, u16 qidx) +static inline bool rtw_os_need_wake_queue(_adapter *padapter, u16 os_qid) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) struct xmit_priv *pxmitpriv = &padapter->xmitpriv; if (padapter->registrypriv.wifi_spec) { - if (pxmitpriv->hwxmits[qidx].accnt < WMM_XMIT_THRESHOLD) + if (pxmitpriv->hwxmits[os_qid].accnt < WMM_XMIT_THRESHOLD) return _TRUE; #ifdef DBG_CONFIG_ERROR_DETECT #ifdef DBG_CONFIG_ERROR_RESET @@ -236,13 +236,13 @@ static inline bool rtw_os_need_wake_queue(_adapter *padapter, u16 qidx) #endif } -static inline bool rtw_os_need_stop_queue(_adapter *padapter, u16 qidx) +static inline bool rtw_os_need_stop_queue(_adapter *padapter, u16 os_qid) { struct xmit_priv *pxmitpriv = &padapter->xmitpriv; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) if (padapter->registrypriv.wifi_spec) { /* No free space for Tx, tx_worker is too slow */ - if (pxmitpriv->hwxmits[qidx].accnt > WMM_XMIT_THRESHOLD) + if (pxmitpriv->hwxmits[os_qid].accnt > WMM_XMIT_THRESHOLD) return _TRUE; } else { if (pxmitpriv->free_xmitframe_cnt <= 4) @@ -257,23 +257,6 @@ static inline bool rtw_os_need_stop_queue(_adapter *padapter, u16 qidx) void rtw_os_pkt_complete(_adapter *padapter, _pkt *pkt) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) - u16 qidx; - - qidx = skb_get_queue_mapping(pkt); - if (rtw_os_need_wake_queue(padapter, qidx)) { - if (DBG_DUMP_OS_QUEUE_CTL) - RTW_INFO(FUNC_ADPT_FMT": netif_wake_subqueue[%d]\n", FUNC_ADPT_ARG(padapter), qidx); - netif_wake_subqueue(padapter->pnetdev, qidx); - } -#else - if (rtw_os_need_wake_queue(padapter, 0)) { - if (DBG_DUMP_OS_QUEUE_CTL) - RTW_INFO(FUNC_ADPT_FMT": netif_wake_queue\n", FUNC_ADPT_ARG(padapter)); - netif_wake_queue(padapter->pnetdev); - } -#endif - rtw_skb_free(pkt); } @@ -323,24 +306,39 @@ void rtw_os_xmit_schedule(_adapter *padapter) #endif } -static bool rtw_check_xmit_resource(_adapter *padapter, _pkt *pkt) +void rtw_os_check_wakup_queue(_adapter *adapter, u16 os_qid) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) + if (rtw_os_need_wake_queue(adapter, os_qid)) { + if (DBG_DUMP_OS_QUEUE_CTL) + RTW_INFO(FUNC_ADPT_FMT": netif_wake_subqueue[%d]\n", FUNC_ADPT_ARG(adapter), os_qid); + netif_wake_subqueue(adapter->pnetdev, os_qid); + } +#else + if (rtw_os_need_wake_queue(adapter, 0)) { + if (DBG_DUMP_OS_QUEUE_CTL) + RTW_INFO(FUNC_ADPT_FMT": netif_wake_queue\n", FUNC_ADPT_ARG(adapter)); + netif_wake_queue(adapter->pnetdev); + } +#endif +} + +bool rtw_os_check_stop_queue(_adapter *adapter, u16 os_qid) { bool busy = _FALSE; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) - u16 qidx; - qidx = skb_get_queue_mapping(pkt); - if (rtw_os_need_stop_queue(padapter, qidx)) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) + if (rtw_os_need_stop_queue(adapter, os_qid)) { if (DBG_DUMP_OS_QUEUE_CTL) - RTW_INFO(FUNC_ADPT_FMT": netif_stop_subqueue[%d]\n", FUNC_ADPT_ARG(padapter), qidx); - netif_stop_subqueue(padapter->pnetdev, qidx); + RTW_INFO(FUNC_ADPT_FMT": netif_stop_subqueue[%d]\n", FUNC_ADPT_ARG(adapter), os_qid); + netif_stop_subqueue(adapter->pnetdev, os_qid); busy = _TRUE; } #else - if (rtw_os_need_stop_queue(padapter, 0)) { + if (rtw_os_need_stop_queue(adapter, 0)) { if (DBG_DUMP_OS_QUEUE_CTL) - RTW_INFO(FUNC_ADPT_FMT": netif_stop_queue\n", FUNC_ADPT_ARG(padapter)); - rtw_netif_stop_queue(padapter->pnetdev); + RTW_INFO(FUNC_ADPT_FMT": netif_stop_queue\n", FUNC_ADPT_ARG(adapter)); + rtw_netif_stop_queue(adapter->pnetdev); busy = _TRUE; } #endif @@ -373,97 +371,16 @@ void rtw_os_wake_queue_at_free_stainfo(_adapter *padapter, int *qcnt_freed) #endif } -#ifdef CONFIG_TX_MCAST2UNI -int rtw_mlcst2unicst(_adapter *padapter, struct sk_buff *skb) -{ - struct sta_priv *pstapriv = &padapter->stapriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - _irqL irqL; - _list *phead, *plist; - struct sk_buff *newskb; - struct sta_info *psta = NULL; - u8 chk_alive_num = 0; - char chk_alive_list[NUM_STA]; - u8 bc_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - u8 null_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - int i; - s32 res; - - DBG_COUNTER(padapter->tx_logs.os_tx_m2u); - - _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); - phead = &pstapriv->asoc_list; - plist = get_next(phead); - - /* free sta asoc_queue */ - while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) { - int stainfo_offset; - psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); - plist = get_next(plist); - - stainfo_offset = rtw_stainfo_offset(pstapriv, psta); - if (stainfo_offset_valid(stainfo_offset)) - chk_alive_list[chk_alive_num++] = stainfo_offset; - } - _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); - - for (i = 0; i < chk_alive_num; i++) { - psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]); - if (!(psta->state & _FW_LINKED)) { - DBG_COUNTER(padapter->tx_logs.os_tx_m2u_ignore_fw_linked); - continue; - } - - /* avoid come from STA1 and send back STA1 */ - if (_rtw_memcmp(psta->cmn.mac_addr, &skb->data[6], ETH_ALEN) == _TRUE - || _rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN) == _TRUE - || _rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) == _TRUE - ) { - DBG_COUNTER(padapter->tx_logs.os_tx_m2u_ignore_self); - continue; - } - - DBG_COUNTER(padapter->tx_logs.os_tx_m2u_entry); - - newskb = rtw_skb_copy(skb); - - if (newskb) { - _rtw_memcpy(newskb->data, psta->cmn.mac_addr, ETH_ALEN); - res = rtw_xmit(padapter, &newskb); - if (res < 0) { - DBG_COUNTER(padapter->tx_logs.os_tx_m2u_entry_err_xmit); - RTW_INFO("%s()-%d: rtw_xmit() return error! res=%d\n", __FUNCTION__, __LINE__, res); - pxmitpriv->tx_drop++; - rtw_skb_free(newskb); - } - } else { - DBG_COUNTER(padapter->tx_logs.os_tx_m2u_entry_err_skb); - RTW_INFO("%s-%d: rtw_skb_copy() failed!\n", __FUNCTION__, __LINE__); - pxmitpriv->tx_drop++; - /* rtw_skb_free(skb); */ - return _FALSE; /* Caller shall tx this multicast frame via normal way. */ - } - } - - rtw_skb_free(skb); - return _TRUE; -} -#endif /* CONFIG_TX_MCAST2UNI */ - - int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev) { _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; -#ifdef CONFIG_TX_MCAST2UNI - extern int rtw_mc2u_disable; -#endif /* CONFIG_TX_MCAST2UNI */ #ifdef CONFIG_TCP_CSUM_OFFLOAD_TX struct sk_buff *skb = pkt; struct sk_buff *segs, *nskb; netdev_features_t features = padapter->pnetdev->features; #endif + u16 os_qid = 0; s32 res = 0; if (padapter->registrypriv.mp_mode) { @@ -472,7 +389,11 @@ int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev) } DBG_COUNTER(padapter->tx_logs.os_tx); - if (rtw_if_up(padapter) == _FALSE) { + if ((rtw_if_up(padapter) == _FALSE) +#ifdef CONFIG_LAYER2_ROAMING + &&(!padapter->mlmepriv.roam_network) +#endif + ){ DBG_COUNTER(padapter->tx_logs.os_tx_err_up); #ifdef DBG_TX_DROP_FRAME RTW_INFO("DBG_TX_DROP_FRAME %s if_up fail\n", __FUNCTION__); @@ -480,30 +401,9 @@ int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev) goto drop_packet; } - rtw_check_xmit_resource(padapter, pkt); - -#ifdef CONFIG_TX_MCAST2UNI - if (!rtw_mc2u_disable - && MLME_IS_AP(padapter) - && (IP_MCAST_MAC(pkt->data) - || ICMPV6_MCAST_MAC(pkt->data) - #ifdef CONFIG_TX_BCAST2UNI - || is_broadcast_mac_addr(pkt->data) - #endif - ) - && (padapter->registrypriv.wifi_spec == 0) - ) { - if (pxmitpriv->free_xmitframe_cnt > (NR_XMITFRAME / 4)) { - res = rtw_mlcst2unicst(padapter, pkt); - if (res == _TRUE) - goto exit; - } else { - /* RTW_INFO("Stop M2U(%d, %d)! ", pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmitbuf_cnt); */ - /* RTW_INFO("!m2u ); */ - DBG_COUNTER(padapter->tx_logs.os_tx_m2u_stop); - } - } -#endif /* CONFIG_TX_MCAST2UNI */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) + os_qid = skb_get_queue_mapping(pkt); +#endif #ifdef CONFIG_TCP_CSUM_OFFLOAD_TX if (skb_shinfo(skb)->gso_size) { @@ -518,7 +418,7 @@ int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev) segs = segs->next; nskb->next = NULL; rtw_mstat_update( MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, nskb->truesize); - res = rtw_xmit(padapter, &nskb); + res = rtw_xmit(padapter, &nskb, os_qid); if (res < 0) { #ifdef DBG_TX_DROP_FRAME RTW_INFO("DBG_TX_DROP_FRAME %s rtw_xmit fail\n", __FUNCTION__); @@ -532,7 +432,7 @@ int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev) } #endif - res = rtw_xmit(padapter, &pkt); + res = rtw_xmit(padapter, &pkt, os_qid); if (res < 0) { #ifdef DBG_TX_DROP_FRAME RTW_INFO("DBG_TX_DROP_FRAME %s rtw_xmit fail\n", __FUNCTION__); @@ -614,11 +514,11 @@ fail: } #endif -inline netdev_tx_t rtw_xmit_entry(struct sk_buff *pkt, struct net_device *pnetdev) +int rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev) { _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - netdev_tx_t ret = 0; + int ret = 0; if (pkt) { #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL diff --git a/os_dep/osdep_service.c b/os_dep/osdep_service.c index d3cb908..160a152 100644 --- a/os_dep/osdep_service.c +++ b/os_dep/osdep_service.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2019 Realtek Corporation. + * Copyright(c) 2007 - 2017 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -970,6 +970,24 @@ int _rtw_memcmp(const void *dst, const void *src, u32 sz) +} + +int _rtw_memcmp2(const void *dst, const void *src, u32 sz) +{ + const unsigned char *p1 = dst, *p2 = src; + + if (sz == 0) + return 0; + + while (*p1 == *p2) { + p1++; + p2++; + sz--; + if (sz == 0) + return 0; + } + + return *p1 - *p2; } void _rtw_memset(void *pbuf, int c, u32 sz) @@ -1261,20 +1279,12 @@ u32 _rtw_down_sema(_sema *sema) { #ifdef PLATFORM_LINUX -#if 0 + if (down_interruptible(sema)) return _FAIL; else return _SUCCESS; -#else - int res; - res = down_interruptible(sema); - if (res) - RTW_ERR("%s: unexpected interrupted! res=%d\n", - __FUNCTION__, res); - return _SUCCESS; -#endif #endif #ifdef PLATFORM_FREEBSD sema_wait(sema); @@ -1618,6 +1628,231 @@ inline bool _rtw_time_after(systime a, systime b) #endif } +sysptime rtw_sptime_get(void) +{ + /* CLOCK_MONOTONIC */ +#ifdef PLATFORM_LINUX + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) + struct timespec64 cur; + + ktime_get_ts64(&cur); + return timespec64_to_ktime(cur); + #else + struct timespec cur; + + ktime_get_ts(&cur); + return timespec_to_ktime(cur); + #endif +#else + #error "TBD\n" +#endif +} + +sysptime rtw_sptime_set(s64 secs, const u32 nsecs) +{ +#ifdef PLATFORM_LINUX + return ktime_set(secs, nsecs); +#else + #error "TBD\n" +#endif +} + +sysptime rtw_sptime_zero(void) +{ +#ifdef PLATFORM_LINUX + return ktime_set(0, 0); +#else + #error "TBD\n" +#endif +} + +/* + * cmp1 < cmp2: return <0 + * cmp1 == cmp2: return 0 + * cmp1 > cmp2: return >0 + */ +int rtw_sptime_cmp(const sysptime cmp1, const sysptime cmp2) +{ +#ifdef PLATFORM_LINUX + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) + return ktime_compare(cmp1, cmp2); + #else + if (cmp1.tv64 < cmp2.tv64) + return -1; + if (cmp1.tv64 > cmp2.tv64) + return 1; + return 0; + #endif +#else + #error "TBD\n" +#endif +} + +bool rtw_sptime_eql(const sysptime cmp1, const sysptime cmp2) +{ +#ifdef PLATFORM_LINUX + return rtw_sptime_cmp(cmp1, cmp2) == 0; +#else + #error "TBD\n" +#endif +} + +bool rtw_sptime_is_zero(const sysptime sptime) +{ +#ifdef PLATFORM_LINUX + return rtw_sptime_cmp(sptime, rtw_sptime_zero()) == 0; +#else + #error "TBD\n" +#endif +} + +/* + * sub = lhs - rhs, in normalized form + */ +sysptime rtw_sptime_sub(const sysptime lhs, const sysptime rhs) +{ +#ifdef PLATFORM_LINUX + return ktime_sub(lhs, rhs); +#else + #error "TBD\n" +#endif +} + +/* + * add = lhs + rhs, in normalized form + */ +sysptime rtw_sptime_add(const sysptime lhs, const sysptime rhs) +{ +#ifdef PLATFORM_LINUX + return ktime_add(lhs, rhs); +#else + #error "TBD\n" +#endif +} + +s64 rtw_sptime_to_ms(const sysptime sptime) +{ +#ifdef PLATFORM_LINUX + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) + return ktime_to_ms(sptime); + #else + struct timeval tv = ktime_to_timeval(sptime); + + return (s64) tv.tv_sec * MSEC_PER_SEC + tv.tv_usec / USEC_PER_MSEC; + #endif +#else + #error "TBD\n" +#endif +} + +sysptime rtw_ms_to_sptime(u64 ms) +{ +#ifdef PLATFORM_LINUX + return ns_to_ktime(ms * NSEC_PER_MSEC); +#else + #error "TBD\n" +#endif +} + +s64 rtw_sptime_to_us(const sysptime sptime) +{ +#ifdef PLATFORM_LINUX + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)) + return ktime_to_us(sptime); + #else + struct timeval tv = ktime_to_timeval(sptime); + + return (s64) tv.tv_sec * USEC_PER_SEC + tv.tv_usec; + #endif +#else + #error "TBD\n" +#endif +} + +sysptime rtw_us_to_sptime(u64 us) +{ +#ifdef PLATFORM_LINUX + return ns_to_ktime(us * NSEC_PER_USEC); +#else + #error "TBD\n" +#endif +} + +s64 rtw_sptime_to_ns(const sysptime sptime) +{ +#ifdef PLATFORM_LINUX + return ktime_to_ns(sptime); +#else + #error "TBD\n" +#endif +} + +sysptime rtw_ns_to_sptime(u64 ns) +{ +#ifdef PLATFORM_LINUX + return ns_to_ktime(ns); +#else + #error "TBD\n" +#endif +} + +s64 rtw_sptime_diff_ms(const sysptime start, const sysptime end) +{ + sysptime diff; + + diff = rtw_sptime_sub(end, start); + + return rtw_sptime_to_ms(diff); +} + +s64 rtw_sptime_pass_ms(const sysptime start) +{ + sysptime cur, diff; + + cur = rtw_sptime_get(); + diff = rtw_sptime_sub(cur, start); + + return rtw_sptime_to_ms(diff); +} + +s64 rtw_sptime_diff_us(const sysptime start, const sysptime end) +{ + sysptime diff; + + diff = rtw_sptime_sub(end, start); + + return rtw_sptime_to_us(diff); +} + +s64 rtw_sptime_pass_us(const sysptime start) +{ + sysptime cur, diff; + + cur = rtw_sptime_get(); + diff = rtw_sptime_sub(cur, start); + + return rtw_sptime_to_us(diff); +} + +s64 rtw_sptime_diff_ns(const sysptime start, const sysptime end) +{ + sysptime diff; + + diff = rtw_sptime_sub(end, start); + + return rtw_sptime_to_ns(diff); +} + +s64 rtw_sptime_pass_ns(const sysptime start) +{ + sysptime cur, diff; + + cur = rtw_sptime_get(); + diff = rtw_sptime_sub(cur, start); + + return rtw_sptime_to_ns(diff); +} + void rtw_sleep_schedulable(int ms) { @@ -1812,6 +2047,46 @@ void rtw_yield_os(void) #endif } +const char *_rtw_pwait_type_str[] = { + [RTW_PWAIT_TYPE_MSLEEP] = "MS", + [RTW_PWAIT_TYPE_USLEEP] = "US", + [RTW_PWAIT_TYPE_YIELD] = "Y", + [RTW_PWAIT_TYPE_MDELAY] = "MD", + [RTW_PWAIT_TYPE_UDELAY] = "UD", + [RTW_PWAIT_TYPE_NUM] = "unknown", +}; + +static void rtw_pwctx_yield(int us) +{ + rtw_yield_os(); +} + +static void (*const rtw_pwait_hdl[])(int)= { + [RTW_PWAIT_TYPE_MSLEEP] = rtw_msleep_os, + [RTW_PWAIT_TYPE_USLEEP] = rtw_usleep_os, + [RTW_PWAIT_TYPE_YIELD] = rtw_pwctx_yield, + [RTW_PWAIT_TYPE_MDELAY] = rtw_mdelay_os, + [RTW_PWAIT_TYPE_UDELAY] = rtw_udelay_os, +}; + +int rtw_pwctx_config(struct rtw_pwait_ctx *pwctx, enum rtw_pwait_type type, s32 time, s32 cnt_lmt) +{ + int ret = _FAIL; + + if (!RTW_PWAIT_TYPE_VALID(type)) + goto exit; + + pwctx->conf.type = type; + pwctx->conf.wait_time = time; + pwctx->conf.wait_cnt_lmt = cnt_lmt; + pwctx->wait_hdl = rtw_pwait_hdl[type]; + + ret = _SUCCESS; + +exit: + return ret; +} + bool rtw_macaddr_is_larger(const u8 *a, const u8 *b) { u32 va, vb; @@ -2286,7 +2561,9 @@ static int retriveFromFile(const char *path, u8 *buf, u32 sz) set_fs(get_ds()); #endif #endif + ret = readFile(fp, buf, sz); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) set_fs(oldfs); #endif @@ -2331,7 +2608,9 @@ static int storeToFile(const char *path, u8 *buf, u32 sz) set_fs(get_ds()); #endif #endif + ret = writeFile(fp, buf, sz); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) set_fs(oldfs); #endif @@ -2526,65 +2805,6 @@ RETURN: return; } -int rtw_change_ifname(_adapter *padapter, const char *ifname) -{ - struct dvobj_priv *dvobj; - struct net_device *pnetdev; - struct net_device *cur_pnetdev; - struct rereg_nd_name_data *rereg_priv; - int ret; - u8 rtnl_lock_needed; - - if (!padapter) - goto error; - - dvobj = adapter_to_dvobj(padapter); - cur_pnetdev = padapter->pnetdev; - rereg_priv = &padapter->rereg_nd_name_priv; - - /* free the old_pnetdev */ - if (rereg_priv->old_pnetdev) { - free_netdev(rereg_priv->old_pnetdev); - rereg_priv->old_pnetdev = NULL; - } - - rtnl_lock_needed = rtw_rtnl_lock_needed(dvobj); - - if (rtnl_lock_needed) - unregister_netdev(cur_pnetdev); - else - unregister_netdevice(cur_pnetdev); - - rereg_priv->old_pnetdev = cur_pnetdev; - - pnetdev = rtw_init_netdev(padapter); - if (!pnetdev) { - ret = -1; - goto error; - } - - SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter))); - - rtw_init_netdev_name(pnetdev, ifname); - - _rtw_memcpy(pnetdev->dev_addr, adapter_mac_addr(padapter), ETH_ALEN); - - if (rtnl_lock_needed) - ret = register_netdev(pnetdev); - else - ret = register_netdevice(pnetdev); - - if (ret != 0) { - goto error; - } - - return 0; - -error: - - return -1; - -} #endif #ifdef PLATFORM_FREEBSD @@ -2939,6 +3159,7 @@ exit: return val; } +#ifdef CONFIG_RTW_MESH int rtw_blacklist_add(_queue *blist, const u8 *addr, u32 timeout_ms) { struct blacklist_ent *ent; @@ -3096,6 +3317,7 @@ void dump_blacklist(void *sel, _queue *blist, const char *title) } exit_critical_bh(&blist->lock); } +#endif /** * is_null - @@ -3226,3 +3448,30 @@ int hexstr2bin(const char *hex, u8 *buf, size_t len) return 0; } +/** + * hwaddr_aton - Convert ASCII string to MAC address + * @txt: MAC address as a string (e.g., "00:11:22:33:44:55") + * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) + * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) + */ +int hwaddr_aton_i(const char *txt, u8 *addr) +{ + int i; + + for (i = 0; i < 6; i++) { + int a, b; + + a = hex2num_i(*txt++); + if (a < 0) + return -1; + b = hex2num_i(*txt++); + if (b < 0) + return -1; + *addr++ = (a << 4) | b; + if (i < 5 && *txt++ != ':') + return -1; + } + + return 0; +} + diff --git a/platform/custom_country_chplan.h b/platform/custom_country_chplan.h index f8cc13b..67f621f 100644 --- a/platform/custom_country_chplan.h +++ b/platform/custom_country_chplan.h @@ -17,6 +17,6 @@ #error "Before removing these error notifications, please make sure regulatory certification requirements of your target markets" static const struct country_chplan CUSTOMIZED_country_chplan_map[] = { - COUNTRY_CHPLAN_ENT("TW", 0x76, 1, 0x3FF), /* Taiwan */ + COUNTRY_CHPLAN_ENT("TW", 0x76, 1), /* Taiwan */ }; diff --git a/platform/platform_rockchips_sdio.c b/platform/platform_rockchips_sdio.c deleted file mode 100644 index 73bd404..0000000 --- a/platform/platform_rockchips_sdio.c +++ /dev/null @@ -1,53 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2019 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - *****************************************************************************/ -#ifdef CONFIG_PLATFORM_OPS -#include /* msleep() */ -#include /* rockchip_wifi_xxx() */ - - -/* - * Return: - * 0: power on successfully - * others: power on failed - */ -int platform_wifi_power_on(void) -{ - int ret = 0; - - - printk("\n"); - printk("=======================================================\n"); - printk("==== Launching Wi-Fi driver! (Powered by Rockchip) ====\n"); - printk("=======================================================\n"); - printk("Realtek SDIO WiFi driver (Powered by Rockchip) init.\n"); - rockchip_wifi_power(1); - msleep(100); - rockchip_wifi_set_carddetect(1); - - return ret; -} - -void platform_wifi_power_off(void) -{ - printk("\n"); - printk("=======================================================\n"); - printk("=== Dislaunching Wi-Fi driver! (Powered by Rockchip) ==\n"); - printk("=======================================================\n"); - printk("Realtek SDIO WiFi driver (Powered by Rockchip) init.\n"); - rockchip_wifi_set_carddetect(0); - msleep(100); - rockchip_wifi_power(0); -} -#endif /* !CONFIG_PLATFORM_OPS */