From 2a2b4745970772b983eef1ec1a6990a38c07fba7 Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Tue, 19 Apr 2022 14:46:37 +0800 Subject: [PATCH] mxm_wifiex: update to mxm5x17322 release New Additions/Removals/Improvements: ------------------------------------ 1. WSW-18868: Improve FW download time after suspend/resume cycle 2. WSFD-484: WIFI 6E support 3. WSW-17954: Enable turbo mode command for mlanutl 4. WSW-19363: Add debug prints to WLAN driver regarding WPA_supplicant 5. WSW-19307: Support robust btc related commands [0x00e0] in mlanutl 6. WSW-16429: Disabling of WEP/TKIP on all V16 devices 7. Use CFG80211_VERSION_CODE to control cfg80211 related code 8. Enabled these new commands for mlanutl: min_ba_threshold, stop_su and ed_mac_ctrl_v3 9. WSFD-386: FW and VHAL Implementation for WOWLAN by adding code for MDNS wakeup Driver Bug Fixes: ----------------- 1. WSW-18708: Setting domain info fails for W8801 Murata M.2 Module (2DS) 2. WSW-18541: Debug logs not seen if drvdbg is part of wifi_mod_para.conf 3. WSW-19136: Command 0x107 timeout is seen radomly during connect-disconnect test 4. WSW-18865: VHT80 TCP-tx throughput only run about 170Mbps, both STA and MMH mode 5. WSW-17923: 4K Video Stoppage Issue, Wi-Fi throughput drops to lower than 20Mbps without recovery 6. WSW-17925: NO_IR flags are not cleared for ch 12,13 and 14 if country is changed to JP in runtime 7. WCSWREL-251: There is "mlan0: Failed to initialize driver interface" during stress load/unload testing 8. WSW-18431: UAP beacon (in 1x1 mode) not reporting correct values for tx_highest_rate and rx_highest_rate in VhtCap IE 9. WSW-18116: TCP Keep alive packets are not seen after starting cloud keep alive 10. WSW-18690: STAUT is advertising support of MCS-0 to 9 only in HE-IE in Probe Request 11. WCSWREL-266: Fix L5.16 build errors and warnings Signed-off-by: Sherry Sun --- mxm_wifiex/wlan_src/Makefile | 40 +- mxm_wifiex/wlan_src/README_MLAN | 17 +- mxm_wifiex/wlan_src/mapp/mlanconfig/Makefile | 46 - .../mapp/mlanconfig/config/coex_int_api.conf | 126 + .../mapp/mlanconfig/config/robust_btc_MM.conf | 43 + .../mapp/mlanconfig/config/wifi_mod_para.conf | 26 + mxm_wifiex/wlan_src/mapp/mlanutl/Android.mk | 54 - mxm_wifiex/wlan_src/mapp/mlanutl/Makefile | 7 +- mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.c | 80 +- mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.h | 77 +- mxm_wifiex/wlan_src/mapp/mlanutl/mlanwls.c | 1747 +++++++++++++ mxm_wifiex/wlan_src/mapp/mlanutl/mlanwls.h | 375 +++ mxm_wifiex/wlan_src/mlan/mlan.h | 2 +- mxm_wifiex/wlan_src/mlan/mlan_11ac.c | 46 +- mxm_wifiex/wlan_src/mlan/mlan_11ax.c | 176 +- mxm_wifiex/wlan_src/mlan/mlan_11ax.h | 11 +- mxm_wifiex/wlan_src/mlan/mlan_11d.c | 90 +- mxm_wifiex/wlan_src/mlan/mlan_11h.c | 132 +- mxm_wifiex/wlan_src/mlan/mlan_11h.h | 8 +- mxm_wifiex/wlan_src/mlan/mlan_11n.c | 23 +- mxm_wifiex/wlan_src/mlan/mlan_11n.h | 4 +- mxm_wifiex/wlan_src/mlan/mlan_11n_aggr.h | 2 +- mxm_wifiex/wlan_src/mlan/mlan_11n_rxreorder.h | 2 +- mxm_wifiex/wlan_src/mlan/mlan_cfp.c | 333 ++- mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c | 668 ++++- mxm_wifiex/wlan_src/mlan/mlan_decl.h | 172 +- mxm_wifiex/wlan_src/mlan/mlan_fw.h | 449 ++-- mxm_wifiex/wlan_src/mlan/mlan_ieee.h | 208 +- mxm_wifiex/wlan_src/mlan/mlan_init.c | 25 +- mxm_wifiex/wlan_src/mlan/mlan_init.h | 15 +- mxm_wifiex/wlan_src/mlan/mlan_ioctl.h | 442 +++- mxm_wifiex/wlan_src/mlan/mlan_join.c | 16 +- mxm_wifiex/wlan_src/mlan/mlan_join.h | 2 +- mxm_wifiex/wlan_src/mlan/mlan_main.h | 158 +- mxm_wifiex/wlan_src/mlan/mlan_meas.c | 2 +- mxm_wifiex/wlan_src/mlan/mlan_meas.h | 2 +- mxm_wifiex/wlan_src/mlan/mlan_misc.c | 261 +- mxm_wifiex/wlan_src/mlan/mlan_module.c | 2 +- mxm_wifiex/wlan_src/mlan/mlan_pcie.c | 129 +- mxm_wifiex/wlan_src/mlan/mlan_pcie.h | 2 +- mxm_wifiex/wlan_src/mlan/mlan_scan.c | 210 +- mxm_wifiex/wlan_src/mlan/mlan_sdio.c | 42 +- mxm_wifiex/wlan_src/mlan/mlan_shim.c | 46 +- mxm_wifiex/wlan_src/mlan/mlan_sta_cmd.c | 642 ++++- mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c | 170 +- mxm_wifiex/wlan_src/mlan/mlan_sta_event.c | 44 +- mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c | 178 +- mxm_wifiex/wlan_src/mlan/mlan_sta_rx.c | 138 +- mxm_wifiex/wlan_src/mlan/mlan_sta_tx.c | 33 +- mxm_wifiex/wlan_src/mlan/mlan_uap.h | 2 +- mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c | 88 +- mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c | 89 +- mxm_wifiex/wlan_src/mlan/mlan_uap_txrx.c | 49 + mxm_wifiex/wlan_src/mlan/mlan_usb.c | 22 +- mxm_wifiex/wlan_src/mlan/mlan_wmm.c | 32 +- mxm_wifiex/wlan_src/mlinux/mlan.h | 2 +- mxm_wifiex/wlan_src/mlinux/mlan_decl.h | 172 +- mxm_wifiex/wlan_src/mlinux/mlan_ieee.h | 208 +- mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h | 442 +++- mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c | 337 ++- mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h | 12 +- .../wlan_src/mlinux/moal_cfg80211_util.c | 664 ++++- .../wlan_src/mlinux/moal_cfg80211_util.h | 72 +- mxm_wifiex/wlan_src/mlinux/moal_debug.c | 2 +- mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c | 2287 ++++++++++++++++- mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h | 39 +- mxm_wifiex/wlan_src/mlinux/moal_init.c | 111 +- mxm_wifiex/wlan_src/mlinux/moal_ioctl.c | 517 +++- mxm_wifiex/wlan_src/mlinux/moal_main.c | 1058 +++++++- mxm_wifiex/wlan_src/mlinux/moal_main.h | 428 ++- mxm_wifiex/wlan_src/mlinux/moal_pcie.c | 152 +- mxm_wifiex/wlan_src/mlinux/moal_pcie.h | 32 +- mxm_wifiex/wlan_src/mlinux/moal_priv.c | 161 +- mxm_wifiex/wlan_src/mlinux/moal_priv.h | 4 +- mxm_wifiex/wlan_src/mlinux/moal_proc.c | 2 +- mxm_wifiex/wlan_src/mlinux/moal_sdio.h | 19 +- mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c | 60 +- mxm_wifiex/wlan_src/mlinux/moal_shim.c | 522 +++- mxm_wifiex/wlan_src/mlinux/moal_shim.h | 3 +- .../wlan_src/mlinux/moal_sta_cfg80211.c | 423 ++- mxm_wifiex/wlan_src/mlinux/moal_uap.c | 160 +- mxm_wifiex/wlan_src/mlinux/moal_uap.h | 14 +- .../wlan_src/mlinux/moal_uap_cfg80211.c | 179 +- .../wlan_src/mlinux/moal_uap_cfg80211.h | 2 +- mxm_wifiex/wlan_src/mlinux/moal_uap_priv.h | 2 +- mxm_wifiex/wlan_src/mlinux/moal_uap_wext.c | 2 +- mxm_wifiex/wlan_src/mlinux/moal_usb.c | 61 +- mxm_wifiex/wlan_src/mlinux/moal_usb.h | 18 +- mxm_wifiex/wlan_src/mlinux/moal_wext.c | 31 +- mxm_wifiex/wlan_src/mlinux/moal_wext.h | 2 +- .../script/wifidirect/start_auto_go.sh | 30 - .../script/wifidirect/start_find_phase.sh | 25 - .../script/wifidirect/start_listen_state.sh | 18 - .../script/wifidirect/stop_auto_go.sh | 8 - .../wifidirect/stop_wifidirect_client.sh | 6 - .../wlan_src/script/wifidirect/update_mac.sh | 16 - 96 files changed, 13870 insertions(+), 2238 deletions(-) delete mode 100644 mxm_wifiex/wlan_src/mapp/mlanconfig/Makefile create mode 100644 mxm_wifiex/wlan_src/mapp/mlanconfig/config/coex_int_api.conf create mode 100644 mxm_wifiex/wlan_src/mapp/mlanconfig/config/robust_btc_MM.conf delete mode 100644 mxm_wifiex/wlan_src/mapp/mlanutl/Android.mk create mode 100644 mxm_wifiex/wlan_src/mapp/mlanutl/mlanwls.c create mode 100644 mxm_wifiex/wlan_src/mapp/mlanutl/mlanwls.h delete mode 100644 mxm_wifiex/wlan_src/script/wifidirect/start_auto_go.sh delete mode 100644 mxm_wifiex/wlan_src/script/wifidirect/start_find_phase.sh delete mode 100644 mxm_wifiex/wlan_src/script/wifidirect/start_listen_state.sh delete mode 100644 mxm_wifiex/wlan_src/script/wifidirect/stop_auto_go.sh delete mode 100644 mxm_wifiex/wlan_src/script/wifidirect/stop_wifidirect_client.sh delete mode 100644 mxm_wifiex/wlan_src/script/wifidirect/update_mac.sh diff --git a/mxm_wifiex/wlan_src/Makefile b/mxm_wifiex/wlan_src/Makefile index 0e2fc62..f3468a7 100644 --- a/mxm_wifiex/wlan_src/Makefile +++ b/mxm_wifiex/wlan_src/Makefile @@ -1,6 +1,6 @@ # File: Makefile # -# Copyright 2008-2021 NXP +# Copyright 2008-2022 NXP # # This software file (the File) is distributed by NXP # under the terms of the GNU General Public License Version 2, June 1991 @@ -21,7 +21,7 @@ ifeq ($(CONFIG_COMPATDIR), y) COMPATDIR=/lib/modules/$(KERNELVERSION_X86)/build/compat-wireless-3.2-rc1-1/include CC ?= $(CROSS_COMPILE)gcc -I$(COMPATDIR) else -CC ?= $(CROSS_COMPILE)gcc +CC ?= $(CROSS_COMPILE)gcc -I$(COMPATDIR) endif LD ?= $(CROSS_COMPILE)ld @@ -52,6 +52,9 @@ CONFIG_PCIE9097=n CONFIG_SD9098=y CONFIG_USB9098=n CONFIG_PCIE9098=y +CONFIG_SDNW62X=n +CONFIG_PCIENW62X=n +CONFIG_USBNW62X=n # Debug Option @@ -81,9 +84,6 @@ CONFIG_MFG_CMD_SUPPORT=y # OpenWrt support CONFIG_OPENWRT_SUPPORT=n -# Big-endian platform -CONFIG_BIG_ENDIAN=n - ifeq ($(CONFIG_DRV_EMBEDDED_SUPPLICANT), y) @@ -125,6 +125,7 @@ ccflags-y += -DLINUX + ARCH ?= arm64 CONFIG_IMX_SUPPORT=y ifeq ($(CONFIG_IMX_SUPPORT),y) @@ -187,10 +188,6 @@ ifeq ($(CONFIG_MFG_CMD_SUPPORT),y) ccflags-y += -DMFG_CMD_SUPPORT endif -ifeq ($(CONFIG_BIG_ENDIAN),y) - ccflags-y += -DBIG_ENDIAN_SUPPORT -endif - ifeq ($(CONFIG_USERSPACE_32BIT_OVER_KERNEL_64BIT),y) ccflags-y += -DUSERSPACE_32BIT_OVER_KERNEL_64BIT endif @@ -249,6 +246,10 @@ ifeq ($(CONFIG_SD9097),y) CONFIG_SDIO=y ccflags-y += -DSD9097 endif +ifeq ($(CONFIG_SDNW62X),y) + CONFIG_SDIO=y + ccflags-y += -DSDNW62X +endif ifeq ($(CONFIG_SD9177),y) CONFIG_SDIO=y ccflags-y += -DSD9177 @@ -281,6 +282,10 @@ ifeq ($(CONFIG_USB9097),y) CONFIG_MUSB=y ccflags-y += -DUSB9097 endif +ifeq ($(CONFIG_USBNW62X),y) + CONFIG_MUSB=y + ccflags-y += -DUSBNW62X +endif ifeq ($(CONFIG_USB9098),y) CONFIG_MUSB=y ccflags-y += -DUSB9098 @@ -301,6 +306,10 @@ ifeq ($(CONFIG_PCIE9098),y) CONFIG_PCIE=y ccflags-y += -DPCIE9098 endif +ifeq ($(CONFIG_PCIENW62X),y) + CONFIG_PCIE=y + ccflags-y += -DPCIENW62X +endif ifeq ($(CONFIG_SDIO),y) ccflags-y += -DSDIO ccflags-y += -DSDIO_MMC @@ -344,7 +353,6 @@ endif #ccflags-y += -Wstringop-truncation #ccflags-y += -Wmisleading-indentation #ccflags-y += -Wunused-const-variable -ccflags-y += -Wno-stringop-truncation ccflags-y += -Wno-array-bounds ############################################################################# # Make Targets @@ -583,6 +591,18 @@ mapp/mlanutl: echo: +appsbuild: + + @if [ ! -d $(BINDIR) ]; then \ + mkdir $(BINDIR); \ + fi + + cp -f README_MLAN $(BINDIR) +ifneq ($(APPDIR),) + $(MAKE) -C mapp/mlanconfig $@ INSTALLDIR=$(BINDIR) + $(MAKE) -C mapp/mlanutl $@ INSTALLDIR=$(BINDIR) +endif + build: echo default @if [ ! -d $(BINDIR) ]; then \ diff --git a/mxm_wifiex/wlan_src/README_MLAN b/mxm_wifiex/wlan_src/README_MLAN index 0570252..7c68005 100644 --- a/mxm_wifiex/wlan_src/README_MLAN +++ b/mxm_wifiex/wlan_src/README_MLAN @@ -1,7 +1,7 @@ =============================================================================== U S E R M A N U A L - Copyright 2008-2021 NXP + Copyright 2008-2022 NXP 1) FOR DRIVER BUILD @@ -63,6 +63,7 @@ fw_name = e.g. copy pcieuart9098_combo_v1.bin to firmware directory, fw_name=nxp/pcieuart9098_combo_v1.bin hw_name = + reg_work=0|1 hw_test=0|1 fw_serial=0|1 req_fw_nowait=0|1 @@ -120,12 +121,15 @@ GoAgeoutTime=0|x multi_dtim=0|x inact_tmo=0|x + roamoffload_in_hs=0|1 uap_max_sta: Maximum number of STA for UAP/GO (default 0, max 64) host_mlme=0|1 for supplicant/authenticator running on host side, WPA3 support is available only in host_mlme mode country_ie_ignore=0|1 beacon_hints=0|1 + chan_track=0|1 for 9098 only + Note: On some platforms (e.g. PXA910/920) double quotation marks ("") need to used for module parameters. insmod sdxxx.ko " ..." @@ -1315,7 +1319,7 @@ hssetpara This command is used to set host sleep parameters. Usage: - mlanutl mlanX hssetpara condition [GPIO# [gap]] (optional)[type ind_GPIO# [level]] (optional)[type event_force_ignore event_use_ext_gap ext_gap [gpio_wave]] (optional)[type hs_wakeup_interval] + mlanutl mlanX hssetpara condition [GPIO# [gap]] (optional)[type ind_GPIO# [level]] (optional)[type event_force_ignore event_use_ext_gap ext_gap [gpio_wave]] (optional)[type hs_wakeup_interval] (optional)[type min_wake_holdoff] This command takes one (condition), two (condition and GPIO#) or three (condition, GPIO# and gap).If more than three parameters, it can set different or multiple features indicating by type. @@ -1382,6 +1386,9 @@ hssetpara where hs_wakeup_interval is used to set host sleep wakeup interval and the type must set to 3 to indicate this feature. And the value will round to the nearest multiple dtim*beacon_interval in fw. The unit is milliseconds. + where min_wake_holdoff is minimum delay between HsActive and HostWake and the type must set to 4 to indicate + this feature. The unit is milliseconds. + Examples: mlanutl mlan0 hssetpara -1 : Cancel host sleep mode mlanutl mlan0 hssetpara 3 : Broadcast and unicast data @@ -1434,6 +1441,12 @@ hssetpara type=3 to set hs_wakeup_interval feature hs_wakeup_interval set to 400ms + mlanutl mlan0 hssetpara 2 1 0xa0 4 800: Unicase data + Use GPIO 1 + Gap 160ms + type=4 to set min_wake_holdoff feature + min_wake_holdoff set to 800ms + Note: The parameters will be saved in the driver and be used when host suspends. The ind_GPIO# and level parameters only work with specific board and firmware. mefcfg diff --git a/mxm_wifiex/wlan_src/mapp/mlanconfig/Makefile b/mxm_wifiex/wlan_src/mapp/mlanconfig/Makefile deleted file mode 100644 index d021571..0000000 --- a/mxm_wifiex/wlan_src/mapp/mlanconfig/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -# -# File : mlanconfig/Makefile -# -# Copyright 2008-2020 NXP - -# Path to the top directory of the mlandriver distribution -PATH_TO_TOP = ../.. - -# Determine how we should copy things to the install directory -ABSPATH := $(filter /%, $(INSTALLDIR)) -RELPATH := $(filter-out /%, $(INSTALLDIR)) -INSTALLPATH := $(ABSPATH) -ifeq ($(strip $(INSTALLPATH)),) -INSTALLPATH := $(PATH_TO_TOP)/$(RELPATH) -endif - -# Override CFLAGS for application sources, remove __ kernel namespace defines -CFLAGS := $(filter-out -D__%, $(ccflags-y)) -# remove KERNEL include dir -CFLAGS := $(filter-out -I$(KERNELDIR)%, $(CFLAGS)) - -# -# List of application executables to create -# -TARGETS := $(exectarget) - -# -# Make target rules -# - -# All rule compiles list of TARGETS using builtin program target from src rule -all : -$(exectarget): $(libobjs) - $(CC) $(CFLAGS) $(libobjs) -o $(exectarget) - -# Update any needed TARGETS and then copy to the install path -build install: $(TARGETS) - @cp -rf config $(INSTALLPATH) - -clean: - @rm -f $(exectarget) - @rm -f *.o - -distclean: clean - @rm -f *~ core - @rm -f tags diff --git a/mxm_wifiex/wlan_src/mapp/mlanconfig/config/coex_int_api.conf b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/coex_int_api.conf new file mode 100644 index 0000000..86fa067 --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/coex_int_api.conf @@ -0,0 +1,126 @@ +# File : coex_int_api.conf + +######################### Coex API command ############### +get_bca_arb_config={ + CmdCode=0x0277 # do NOT change this line + + # BCA Arbitration TLV + BCAArbitrationTLVType:2=0x024B # do NOT change this line + RobustCoexTlvLength:2={ + Version:2=0x1 # Firecrest + Action:2=0 # GET + Arbitration_Enable:1=0x00 # Read-back BCA Arb Settings + Grant_Policy:1=0 # Read-back Grant Policy acc to Ant and Isolation config + Priority_Remap_WLAN:16=0 # Read-back remapped WLAN priority + Priority_Remap_BT:4=0 # Read-back remapped BT priority + Priority_Remap_15_4:4=0 # Read-back remapped 15.4 priority + Priority_Ramap_ExtRadio:4=0 # Read-back remapped External Radio + } +} + +set_en_bca_arb_config={ + CmdCode=0x0277 # do NOT change this line + + # BCA Arbitration TLV + BCAArbitrationTLVType:2=0x024B # do NOT change this line + RobustCoexTlvLength:2={ + Version:2=0x1 # Firecrest + Action:2=1 # SET + Arbitration_Enable:1=0x01 # Set BCA Arb Settings + Grant_Policy:1=0 # Set Grant Policy acc to Ant and Isolation config + Priority_Remap_WLAN:16='0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78' # Set remapped WLAN priority + Priority_Remap_BT:4='0x80,0x88,0x90,0x98' # Set remapped BT priority + Priority_Remap_15_4:4='0xA0,0xA8,0xB0,0xB8' # Set remapped 15.4 priority + } +} + +set_dis_bca_arb_config={ + CmdCode=0x0277 # do NOT change this line + + # BCA Arbitration TLV + BCAArbitrationTLVType:2=0x024B # do NOT change this line + RobustCoexTlvLength:2={ + Version:2=0x1 # Firecrest + Action:2=1 # SET + Arbitration_Enable:1=0x00 # Clear BCA Arb Settings + Grant_Policy:1=0 # Set Grant Policy acc to Ant and Isolation config + Priority_Remap_WLAN:16='0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78' # Set remapped WLAN priority + Priority_Remap_BT:4='0x80,0x88,0x90,0x98' # Set remapped BT priority + Priority_Remap_15_4:4='0xA0,0xA8,0xB0,0xB8' # Set remapped 15.4 priority + } +} + +set_wlan_traffic_priority={ + CmdCode=0x0277 # do NOT change this line + + # COEX WLAN Traffic Priority TLV + BCAArbitrationTLVType:2=0x024C # do NOT change this line + RobustCoexTlvLength:2={ + Version:2=0x1 # Firecrest + Action:2=1 # SET + Mode:1=1 # 1 - Qbased based;0-Packet type based + Mask_1:4=0xffffffff # This value will be read in little endian format in firmware,Tx_Priority_setting[t] t = 0 – 31, set bits to indicate which entry need to update priorities + Mask_2:4=0xffffffff # Tx_Priority_setting[t] t= 32 – 63, set bits to indicate which entry need to update priorities + Mask_3:4=0xffffffff # Rx_Priority_setting[t] t= 0 – 31, set bits to indicate which entry need to update priorities + Mask_4:4=0xffffffff # Rx_Priority_setting[t] t= 32 – 63, set bits to indicate which entry need to update priorities + Tx_Priority_setting:64='0xf,0xf,0xf,0xf,0xf,0xf,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x08,0x08,0x8,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40' # WLAN Tx Traffic priorities + Rx_Priority_setting:64='0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80' # WLAN Rx Traffic priorities + } +} + +get_wlan_traffic_priority={ + CmdCode=0x0277 # do NOT change this line + + # COEX WLAN Traffic Priority TLV + BCAArbitrationTLVType:2=0x024C # do NOT change this line + RobustCoexTlvLength:2={ + Version:2=0x1 # Firecrest + Action:2=0 # GET WLAN Traffic priorities + Mode:1=0 # (Qbased based - 1) or (Packet type based - 0) + Mask_1:4=0 # GET mask 1 + Mask_2:4=0 # GET mask 2 + Mask_3:4=0 # GET mask 3 + Mask_4:4=0 # GET mask 4 + Tx_Priority_setting:64=0 # GET WLAN Tx Traffic priorities + Rx_Priority_setting:64=0 # GET WLAN Rx Traffic priorities + } +} + +get_wlan_stats={ + CmdCode=0x0277 # do NOT change this line + + # BCA Arbitration TLV + BCAArbitrationTLVType:2=0x024F # do NOT change this line + RobustCoexTlvLength:2={ + Version:2=0x1 # Firecrest + Action:2=0 # GET WLAN Statistics + length:4=40 # Length of collected statistics + stats:40=0 # Accumulated Statistics + } +} + +get_15_4_stats={ + CmdCode=0x0277 # do NOT change this line + + # BCA Arbitration TLV + BCAArbitrationTLVType:2=0x024F # do NOT change this line + RobustCoexTlvLength:2={ + Version:2=0x1 # Firecrest + Action:2=1 # GET 15.4 Statistics + length:4=52 # Length of collected statistics + stats:52=0 # Accumulated Statistics + } +} + +get_bt_stats={ + CmdCode=0x0277 # do NOT change this line + + # BCA Arbitration TLV + BCAArbitrationTLVType:2=0x024F # do NOT change this line + RobustCoexTlvLength:2={ + Version:2=0x1 # Firecrest + Action:2=2 # GET BT Statistics + length:4=28 # Length of collected statistics + stats:28=0 # Accumulated Statistics + } +} diff --git a/mxm_wifiex/wlan_src/mapp/mlanconfig/config/robust_btc_MM.conf b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/robust_btc_MM.conf new file mode 100644 index 0000000..cf8a8cd --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/robust_btc_MM.conf @@ -0,0 +1,43 @@ +# File : robust_btc_MM.conf + +######################### Robust Coex command ############### +mode_get={ + CmdCode=0x00e0 # do NOT change this line + Action:2=0 # GET + RSVD:2=0 + + # Robust Coex Mode TLV + RobustCoexTlvType:2=0x0160 + RobustCoexTlvLength:2={ + Enable:1=0x00 # Read-back Coex mode(s) + Reserved:3=0 + } +} + +mode_none={ + CmdCode=0x00e0 # do NOT change this line + Action:2=1 # SET + RSVD:2=0 + + # Robust Coex Mode TLV + RobustCoexTlvType:2=0x0160 + RobustCoexTlvLength:2={ + Enable:1=0 # Concurrent Coex mode. Used for chips which has + # separate antenna for BT + Reserved:3=0 + } +} + +mode_bca={ + CmdCode=0x00e0 # do NOT change this line + Action:2=1 # SET + RSVD:2=0 + + # Robust Coex Mode TLV + RobustCoexTlvType:2=0x0160 + RobustCoexTlvLength:2={ + Enable:1=0x08 # BCA Coex mode. + # Pure HW BCA based WLAN and BT traffic arbitration. + Reserved:3=0 + } +} diff --git a/mxm_wifiex/wlan_src/mapp/mlanconfig/config/wifi_mod_para.conf b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/wifi_mod_para.conf index 6ea3e59..911404d 100644 --- a/mxm_wifiex/wlan_src/mapp/mlanconfig/config/wifi_mod_para.conf +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/wifi_mod_para.conf @@ -67,6 +67,15 @@ SD8997 = { # drv_mode=7 #} +#SD8978 = { +# cfg80211_wext=0xf +# wfd_name=p2p +# hw_name=SDIW416 +# max_vir_bss=1 +# cal_data_cfg=nxp/WlanCalData_ext_8978_QFN_TB.conf +# drv_mode=7 +#} + #SD8987 = { # cfg80211_wext=0xf # wfd_name=p2p @@ -75,6 +84,14 @@ SD8997 = { # drv_mode=7 #} +#SD9177 = { +# cfg80211_wext=0xf +# wfd_name=p2p +# hw_name=SDNW611 +# max_vir_bss=1 +# drv_mode=7 +#} + USB8997 = { cfg80211_wext=0xf wfd_name=p2p @@ -83,6 +100,15 @@ USB8997 = { drv_mode=7 } +#USBIW620 = { +# cfg80211_wext=0xf +# wfd_name=p2p +# hw_name=USBIW620 +# max_vir_bss=1 +# drv_mode=7 +#} + + PCIE8997 = { cfg80211_wext=0xf wfd_name=p2p diff --git a/mxm_wifiex/wlan_src/mapp/mlanutl/Android.mk b/mxm_wifiex/wlan_src/mapp/mlanutl/Android.mk deleted file mode 100644 index f746a6d..0000000 --- a/mxm_wifiex/wlan_src/mapp/mlanutl/Android.mk +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 2021 NXP -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -## http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH := $(my-dir) -include $(CLEAR_VARS) - -# Enable DEBUG Level -DEBUG_LEVEL=1 -ifeq ($(DEBUG_LEVEL),1) -LOCAL_CFLAGS += -DDEBUG_LEVEL1 -endif -ifeq ($(DEBUG_LEVEL),2) -LOCAL_CFLAGS += -DDEBUG_LEVEL1 -LOCAL_CFLAGS += -DDEBUG_LEVEL2 -endif -# Enable STA mode support -CONFIG_STA_SUPPORT=y -ifeq ($(CONFIG_STA_SUPPORT),y) -LOCAL_CFLAGS += -DSTA_SUPPORT -endif -# Enable uAP mode support -CONFIG_UAP_SUPPORT=y -ifeq ($(CONFIG_UAP_SUPPORT),y) -LOCAL_CFLAGS += -DUAP_SUPPORT -endif -CONFIG_WIFI_DIRECT_SUPPORT=y -ifeq ($(CONFIG_WIFI_DIRECT_SUPPORT), y) -LOCAL_CFLAGS += -DWIFI_DIRECT_SUPPORT -endif - -# if 64bit Android is used (e.g. PXA1928) -# Please turn on following compiler flag -CONFIG_USERSPACE_32BIT_OVER_KERNEL_64BIT=y -ifeq ($(CONFIG_USERSPACE_32BIT_OVER_KERNEL_64BIT), y) -LOCAL_CFLAGS += -DUSERSPACE_32BIT_OVER_KERNEL_64BIT -endif - -LOCAL_MODULE := mlanutl -LOCAL_VENDOR_MODULE := true -OBJS = mlanutl.c -LOCAL_SRC_FILES := $(OBJS) -LOCAL_MODULE_TAGS := optional - -include $(BUILD_EXECUTABLE) diff --git a/mxm_wifiex/wlan_src/mapp/mlanutl/Makefile b/mxm_wifiex/wlan_src/mapp/mlanutl/Makefile index 46977f9..121d378 100644 --- a/mxm_wifiex/wlan_src/mapp/mlanutl/Makefile +++ b/mxm_wifiex/wlan_src/mapp/mlanutl/Makefile @@ -1,6 +1,6 @@ # File : mlanutl/Makefile # -# Copyright 2011-2020 NXP +# Copyright 2011-2022 NXP # Path to the top directory of the wlan distribution PATH_TO_TOP = ../.. @@ -21,6 +21,7 @@ CFLAGS := $(filter-out -I$(KERNELDIR)%, $(CFLAGS)) #CFLAGS += -DAP22 -fshort-enums CFLAGS += -Wall +CFLAGS += -Wno-stringop-truncation #ECHO = @ ifeq (,$(findstring ANDROID_KERNEL, $(CFLAGS))) LIBS=-lrt @@ -33,10 +34,12 @@ HEADERS = mlanutl.h + + exectarget=mlanutl TARGET := $(exectarget) -build default: $(TARGET) +build appsbuild default: $(TARGET) @cp -f $(TARGET) $(INSTALLPATH) all : tags default diff --git a/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.c b/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.c index 6a316f4..a49b2ea 100644 --- a/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.c +++ b/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.c @@ -3,7 +3,7 @@ * @brief Program to control parameters in the mlandriver * * - * Copyright 2011-2021 NXP + * Copyright 2011-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -52,6 +52,9 @@ Change log: /** Termination flag */ int terminate_flag = 0; +/** Termination flag */ +boolean mcast_debug_flag = 0; + /******************************************************** Local Variables ********************************************************/ @@ -72,6 +75,25 @@ const char *rateIdStr[] = {"1", "2", "5.5", "11", "--", "6", "9", "12", "M2", "M3", "M4", "M5", "M6", "M7", "H0", "H1", "H2", "H3", "H4", "H5", "H6", "H7"}; +char mod_conv_bg_1x1[10][35] = { + "CCK (1,2,5.5,11 Mbps)", "OFDM_PSK (6,9,12,18 Mbps)", + "OFDM_QAM16 (24,36 Mbps)", "OFDM_QAM64 (48,54 Mbps)", + "HT_20_PSK (MCS 0,1,2)", "HT_20_QAM16 (MCS 3,4)", + "HT_20_QAM64 (MCS 5,6,7)", "HT_40_PSK (MCS 0,1,2)", + "HT_40_QAM16 (MCS 3,4)", "HT_40_QAM64 (MCS 5,6,7)"}; +char mod_conv_a_1x1[6][35] = { + "VHT_20_QAM256 (MCS 8)", "VHT_40_QAM256 (MCS 8,9)", + "VHT_80_PSK (MCS 0,1,2)", "VHT_80_QAM16 (MCS 3,4)", + "VHT_80_QAM64 (MCS 5,6,7)", "VHT_80_QAM256 (MCS 8,9)"}; +char mod_conv_bg_2x2[6][35] = { + "HT2_20_PSK (MCS 8,9,10)", "HT2_20_QAM16 (MCS 11,12)", + "HT2_20_QAM64 (MCS 13,14,15)", "HT2_40_PSK (MCS 8,9,10)", + "HT2_40_QAM16 (MCS 11,12)", "HT2_40_QAM64 (MCS 13,14,15)"}; +char mod_conv_a_2x2[6][35] = { + "VHT2_20_QAM256 (MCS 8)", "VHT2_40_QAM256 (MCS 8,9)", + "VHT2_80_PSK (MCS 0,1,2)", "VHT2_80_QAM16 (MCS 3,4)", + "VHT2_80_QAM64 (MCS 5,6,7)", "VHT2_80_QAM256 (MCS 8,9)"}; + #ifdef DEBUG_LEVEL1 #define MMSG MBIT(0) #define MFATAL MBIT(1) @@ -203,8 +225,7 @@ t_s32 sockfd; char dev_name[IFNAMSIZ + 1]; #define HOSTCMD "hostcmd" -static char *config_get_line(char *s, int size, FILE *stream, int *line, - char **_pos); +char *config_get_line(char *s, int size, FILE *stream, int *line, char **_pos); #define BSSID_FILTER 1 #define SSID_FILTER 2 /******************************************************** @@ -268,7 +289,7 @@ t_void hexdump(char *prompt, t_void *p, t_s32 len, char delim) * @param chr Char * @return Hex integer */ -static t_u8 hexc2bin(char chr) +t_u8 hexc2bin(char chr) { if (chr >= '0' && chr <= '9') chr -= '0'; @@ -286,7 +307,7 @@ static t_u8 hexc2bin(char chr) * @param s A pointer string buffer * @return Hex integer */ -static t_u32 a2hex(char *s) +t_u32 a2hex(char *s) { t_u32 val = 0; @@ -307,7 +328,7 @@ static t_u32 a2hex(char *s) * @param value A pointer to string * @return Integer */ -static t_u32 a2hex_or_atoi(char *value) +t_u32 a2hex_or_atoi(char *value) { if (value[0] == '0' && (value[1] == 'X' || value[1] == 'x')) { return a2hex(value + 2); @@ -667,7 +688,7 @@ int process_host_cmd_resp(char *cmd_name, t_u8 *buf); * @param lineno A pointer to return current line number * @return returns string or NULL */ -static char *mlan_config_get_line(FILE *fp, char *str, t_s32 size, int *lineno) +char *mlan_config_get_line(FILE *fp, char *str, t_s32 size, int *lineno) { char *start, *end; int out, next_line; @@ -763,8 +784,7 @@ static char *mlan_config_get_line(FILE *fp, char *str, t_s32 size, int *lineno) * @param _pos Output string or NULL * @return String or NULL */ -static char *config_get_line(char *s, int size, FILE *stream, int *line, - char **_pos) +char *config_get_line(char *s, int size, FILE *stream, int *line, char **_pos) { *_pos = mlan_config_get_line(stream, s, size, line); return *_pos; @@ -945,7 +965,7 @@ static int prepare_host_cmd_buffer(FILE *fp, char *cmd_name, t_u8 *buf) #define SUBID_OFFSET (S_DS_GEN + 2) static const t_u16 debug_cmd = 0x008b; -static t_u16 supported_cmd[] = {0x0130}; +static t_u16 supported_cmd[] = {0x0130, 0x0016, 0x00e0}; /* If the hostcmd CmdCode is 0x008b (debug cmd), then below SUBIDs will be * allowed */ static t_u16 supported_8b_subcmd[] = {0x104, 0x111, 0x11b, 0x11e, 0x27, 0x101}; @@ -2867,8 +2887,11 @@ static int process_11axcfg(int argc, char *argv[]) (t_u8 *)config_id); snprintf(config_id, sizeof(config_id), "HECap"); - fparse_for_cmd_and_hex(fp, buffer + cmd_header_len + id_len, - (t_u8 *)config_id); + id_len += + fparse_for_cmd_and_hex(fp, + buffer + cmd_header_len + id_len, + (t_u8 *)config_id); + hexdump("Set 11axcfg", buffer + cmd_header_len, sizeof(mlan_ds_11ax_he_cfg), ' '); cmd->used_len = cmd_header_len + sizeof(mlan_ds_11ax_he_cfg); @@ -3659,6 +3682,35 @@ int process_host_cmd_resp(char *cmd_name, t_u8 *buf) wmm_param->ac_params[AC_VO].tx_op_limit)); break; } + case HostCmd_ROBUST_COEX: { + host_RobustCoexLteStats_t *RobustCoexLteStat = + (host_RobustCoexLteStats_t *)(buf + S_DS_GEN); + if (RobustCoexLteStat->ResponseType == + EXT_LTE_RESP_GETSTAT) { + printf("==============LTE COEX STATS================\n"); + printf("Responsetype: %d \n", + RobustCoexLteStat->ResponseType); + printf("Count_LTE_TX_NOTIFY: %d \n", + (unsigned int)le32_to_cpu( + RobustCoexLteStat + ->Count_LTE_TX_NOTIFY)); + printf("Count_LTE_RX_PROTECT: %d \n", + (unsigned int)le32_to_cpu( + RobustCoexLteStat + ->Count_LTE_RX_PROTECT)); + printf("Count_LTE_TX_SUSPEND: %d \n", + (unsigned int)le32_to_cpu( + RobustCoexLteStat + ->Count_LTE_TX_SUSPEND)); + printf("Count_LTE_RX_NOTIFY: %d \n", + (unsigned int)le32_to_cpu( + RobustCoexLteStat + ->Count_LTE_RX_NOTIFY)); + } else if (RobustCoexLteStat->ResponseType == + EXT_LTE_RESP_RSTSTAT) { + printf("LTE STAT Counters cleared \n"); + } + } break; default: printf("HOSTCMD_RESP: CmdCode=%#04x, Size=%#04x," " SeqNum=%#04x, Result=%#04x\n", @@ -4585,7 +4637,7 @@ static int ishexstring(char *s) * MAC_BROADCAST - if broadcast mac * MAC_MULTICAST - if multicast mac */ -static int mac2raw(char *mac, t_u8 *raw) +int mac2raw(char *mac, t_u8 *raw) { unsigned int temp_raw[ETH_ALEN]; int num_tokens = 0; @@ -4635,7 +4687,7 @@ static int atoval(char *buf) * 'args' * @return Number of arguments in the line or EOF */ -static int parse_line(char *line, char *args[], t_u16 args_count) +int parse_line(char *line, char *args[], t_u16 args_count) { int arg_num = 0; int is_start = 0; diff --git a/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.h b/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.h index d2f88b4..5148e38 100644 --- a/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.h +++ b/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.h @@ -3,7 +3,7 @@ * @brief This file contains definitions for application * * - * Copyright 2011-2021 NXP + * Copyright 2011-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -59,16 +59,6 @@ typedef enum { FALSE, TRUE } boolean; (((t_u32)(x)&0xff000000UL) >> 24))) /** Convert to correct endian format */ -#ifdef BIG_ENDIAN_SUPPORT -/** CPU to little-endian convert for 16-bit */ -#define cpu_to_le16(x) swap_byte_16(x) -/** CPU to little-endian convert for 32-bit */ -#define cpu_to_le32(x) swap_byte_32(x) -/** Little-endian to CPU convert for 16-bit */ -#define le16_to_cpu(x) swap_byte_16(x) -/** Little-endian to CPU convert for 32-bit */ -#define le32_to_cpu(x) swap_byte_32(x) -#else /** Do nothing */ #define cpu_to_le16(x) (x) /** Do nothing */ @@ -77,7 +67,6 @@ typedef enum { FALSE, TRUE } boolean; #define le16_to_cpu(x) (x) /** Do nothing */ #define le32_to_cpu(x) (x) -#endif /** TLV header */ #define TLVHEADER /** Tag */ \ @@ -456,28 +445,11 @@ typedef enum _IEEEtypes_ElementId_e { typedef enum _IEEEtypes_Ext_ElementId_e { HE_CAPABILITY = 35, - HE_OPERATION = 36 + HE_OPERATION = 36, + HE_6G_CAPABILITY = 59 } IEEEtypes_Ext_ElementId_e; /** Capability Bit Map*/ -#ifdef BIG_ENDIAN_SUPPORT -typedef struct _IEEEtypes_CapInfo_t { - t_u8 rsrvd1 : 2; - t_u8 dsss_ofdm : 1; - t_u8 rsvrd2 : 2; - t_u8 short_slot_time : 1; - t_u8 rsrvd3 : 1; - t_u8 spectrum_mgmt : 1; - t_u8 chan_agility : 1; - t_u8 pbcc : 1; - t_u8 short_preamble : 1; - t_u8 privacy : 1; - t_u8 cf_poll_rqst : 1; - t_u8 cf_pollable : 1; - t_u8 ibss : 1; - t_u8 ess : 1; -} __ATTRIB_PACK__ IEEEtypes_CapInfo_t, *pIEEEtypes_CapInfo_t; -#else typedef struct _IEEEtypes_CapInfo_t { /** Capability Bit Map : ESS */ t_u8 ess : 1; @@ -510,7 +482,6 @@ typedef struct _IEEEtypes_CapInfo_t { /** Capability Bit Map : Reserved */ t_u8 rsrvd1 : 2; } __ATTRIB_PACK__ IEEEtypes_CapInfo_t, *pIEEEtypes_CapInfo_t; -#endif /* BIG_ENDIAN_SUPPORT */ /** IEEE IE header */ typedef struct _IEEEtypes_Header_t { @@ -595,6 +566,7 @@ typedef struct MrvlIEtypes_Data_t { enum { BAND_2GHZ = 0, BAND_5GHZ = 1, BAND_4GHZ = 2, + BAND_6GHZ = 3, }; /** channel offset */ @@ -612,16 +584,6 @@ enum { CHAN_BW_20MHZ = 0, /** Band_Config_t */ typedef struct _Band_Config_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Channel Selection Mode - (00)=manual, (01)=ACS, (02)=user*/ - t_u8 scanMode : 2; - /** Secondary Channel Offset - (00)=None, (01)=Above, (11)=Below */ - t_u8 chan2Offset : 2; - /** Channel Width - (00)=20MHz, (10)=40MHz, (11)=80MHz */ - t_u8 chanWidth : 2; - /** Band Info - (00)=2.4GHz, (01)=5GHz */ - t_u8 chanBand : 2; -#else /** Band Info - (00)=2.4GHz, (01)=5GHz */ t_u8 chanBand : 2; /** Channel Width - (00)=20MHz, (10)=40MHz, (11)=80MHz */ @@ -630,7 +592,6 @@ typedef struct _Band_Config_t { t_u8 chan2Offset : 2; /** Channel Selection Mode - (00)=manual, (01)=ACS, (02)=Adoption mode*/ t_u8 scanMode : 2; -#endif } __ATTRIB_PACK__ Band_Config_t; /** Maximum length of lines in configuration file */ @@ -879,16 +840,6 @@ typedef struct _mlan_ds_11ax_cmd_cfg { /** Data structure of WMM Aci/Aifsn */ typedef struct _IEEEtypes_WmmAciAifsn_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Reserved */ - t_u8 reserved : 1; - /** Aci */ - t_u8 aci : 2; - /** Acm */ - t_u8 acm : 1; - /** Aifsn */ - t_u8 aifsn : 4; -#else /** Aifsn */ t_u8 aifsn : 4; /** Acm */ @@ -897,22 +848,14 @@ typedef struct _IEEEtypes_WmmAciAifsn_t { t_u8 aci : 2; /** Reserved */ t_u8 reserved : 1; -#endif } __ATTRIB_PACK__ IEEEtypes_WmmAciAifsn_t, *pIEEEtypes_WmmAciAifsn_t; /** Data structure of WMM ECW */ typedef struct _IEEEtypes_WmmEcw_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Maximum Ecw */ - t_u8 ecw_max : 4; - /** Minimum Ecw */ - t_u8 ecw_min : 4; -#else /** Minimum Ecw */ t_u8 ecw_min : 4; /** Maximum Ecw */ t_u8 ecw_max : 4; -#endif } __ATTRIB_PACK__ IEEEtypes_WmmEcw_t, *pIEEEtypes_WmmEcw_t; /** Data structure of WMM AC parameters */ @@ -1244,4 +1187,16 @@ typedef struct _cloud_keep_alive { t_u8 pkt[255]; } __ATTRIB_PACK__ cloud_keep_alive; +#define EXT_LTE_RESP_GETSTAT 0xA5 +#define EXT_LTE_RESP_RSTSTAT 0x5A +/** Host Command ID: ROBUST_COEX */ +#define HostCmd_ROBUST_COEX 0x00e0 +typedef struct _host_RobustCoexLteStats_t { + unsigned int Count_LTE_TX_NOTIFY; + unsigned int Count_LTE_RX_PROTECT; + unsigned int Count_LTE_TX_SUSPEND; + unsigned int Count_LTE_RX_NOTIFY; + unsigned char ResponseType; +} __ATTRIB_PACK__ host_RobustCoexLteStats_t; + #endif /* _MLANUTL_H_ */ diff --git a/mxm_wifiex/wlan_src/mapp/mlanutl/mlanwls.c b/mxm_wifiex/wlan_src/mapp/mlanutl/mlanwls.c new file mode 100644 index 0000000..449cba3 --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanutl/mlanwls.c @@ -0,0 +1,1747 @@ +/** @file mlanwls.c + * + * @brief 11mc/11az Wifi location services application + * + * + * Copyright 2022 NXP + * + * This software file (the File) is distributed by NXP + * under the terms of the GNU General Public License Version 2, June 1991 + * (the License). You may use, redistribute and/or modify the File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + * + */ +/************************************************************************ +Change log: + 01/24/2022: initial version +************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mlanutl.h" +#include "mlanwls.h" + +/** WLS application's version number */ +#define WLS_VER "M1.0" + +/*Command arguments index*/ +#define NXP_ADDR "530 Holgerway SanJose" + +#define PROTO_DOT11AZ 1 +#define PROTO_DOT11MC 0 + +#define FTM_SUBCMD_INDEX 3 +#define FTM_CFG_SET_CMD_LEN 6 +#define FTM_CFG_GET_CMD_LEN 4 +#define FTM_CFG_PROTOCOL_INDEX 4 +#define FTM_CFG_FILE_ARG_INDEX 5 + +#define FTM_SESSION_SUBCMD_LEN 8 +#define FTM_SESSION_SUBCMD_NONSTOP_LEN 7 +#define FTM_SESSION_ACTION_OFFSET 4 +#define FTM_SESSION_CHANNEL_OFFSET 5 +#define FTM_SESSION_PEER_ADDR_OFFSET 6 +#define FTM_SESSION_LOOP_OFFSET 7 + +#define FTM_ACTION_START 1 +#define FTM_ACTION_STOP 2 + +/******************************************************** + Functions Declarations +********************************************************/ + +t_u8 hexc2bin(char chr); +t_u32 a2hex(char *s); +t_u32 a2hex_or_atoi(char *value); +t_void hexdump(char *prompt, t_void *p, t_s32 len, char delim); +extern char *config_get_line(char *s, int size, FILE *stream, int *line, + char **_pos); +int parse_line(char *line, char *args[], t_u16 args_count); +int mac2raw(char *mac, t_u8 *raw); + +static t_void display_help(t_u32 n, char **data); +static int mlanwls_prepare_buffer(t_u8 *buffer, char *cmd, t_u32 num, + char *args[]); +static int mlanwls_send_ioctl(t_u8 *cmd_buf); +static void mlanwls_event_handler(int nl_sk); +static int mlanwls_init(void); +static int mlanwls_read_ftm_config(char *file_name); + +static int process_subcommand(int argc, char *argv[]); +static int process_ftm_session_cfg(int argc, char *argv[], void *param); +static int process_ftm_session_ctrl(int argc, char *argv[], void *param); + +static int process_dot11az_ntb_cfg(int argc, char *argv[], void *param); +static int process_dot11mc_ftm_cfg(int argc, char *argv[], void *param); +static int process_ftm_start(int argc, char *argv[], void *param); +static int process_ftm_stop(int argc, char *argv[], void *param); +static int process_ftm_hostcmd_resp(char *cmd_name, t_u8 *buf); +static int process_ftm_complete_event(t_u8 *buffer, t_u16 size, char *if_name); + +static int get_connstatus(int *data); +static void print_event_drv_connected(t_u8 *buffer, t_u16 size); +static int drv_nlevt_handler(struct nlmsghdr *nlh, int bytes_read, + int *evt_conn); +static int read_event(int nl_sk, struct msghdr *msg, struct timeval *ptv); +static int get_netlink_num(int dev_index); +static int open_netlink(int dev_index); +static t_void mlanwls_terminate_handler(int signal); + +/******************************************************** + Local Variables +********************************************************/ +/** WLS app usage */ +static char *mlanwls_help[] = { + "Usage: ", + " mlanutl mlan0 ftm []", + " where subcommand is,", + " session_cfg [ ]", + " session_ctrl [ ]", + " For help on each subcommand,", + " mlanutl mlan0 ftm -h" + ""}; + +static char *ftm_session_cfg_help[] = { + "Usage: ", + " mlanutl mlan0 ftm session_cfg [] ", + " where,", + " : 0:Dot11mc, 1:Dot11az_ntb", + " : Config file with Dot11mc / dot11az parameters", + "", + " eg: mlanutl mlan0 ftm session_cfg 0 config/ftm.conf - Sets dot11mc FTM session params from config file", + " mlanutl mlan0 ftm session_cfg 1 config/ftm.conf - Sets dot11az ntb session params from donfig file", + " "}; + +static char *ftm_session_ctrl_help[] = { + "Usage: ", + " mlanutl mlan0 ftm session_ctrl [ ] ", + " where,", + " : 1: Start, 2: Stop ", + " : number of ftm sessions to run repeatedly ( default:1, 0:non-stop, n>1: n times)", + " : Channel on which FTM must be started", + " : Mac address of the peer with whom FTM session is required", + " ", + " eg: mlanutl mlan0 ftm session_ctrl 1 6 00:50:43:20:bc:4 - Starts FTM session and runs it once", + " mlanutl mlan0 ftm session_ctrl 1 6 00:50:43:20:bc:4 2 - Starts FTM session and runs it for 2 cycles", + " mlanutl mlan0 ftm session_ctrl 1 6 00:50:43:20:bc:4 0 - Runs FTM session non stop until user terminate", + " mlanutl mlan0 ftm session_ctrl 2 - Stop the FTM session", + " "}; + +/** WLS app command ID */ +enum user_command_id { + FTM_SESSION_CFG_CMD_ID = 0, + FTM_SESSION_CTRL_CMD_ID, +}; + +/** WLS app command table */ +static wls_app_command_table wls_app_command[] = { + {FTM_SESSION_CFG_CMD_ID, "session_cfg", process_ftm_session_cfg, + ftm_session_cfg_help}, + {FTM_SESSION_CTRL_CMD_ID, "session_ctrl", process_ftm_session_ctrl, + ftm_session_ctrl_help}}; + +/** WLS app data*/ +wls_app_data_t gwls_data; + +/**DBG Printf*/ +#define DBG_LOG(x) \ + if (gwls_data.debug_level == 2) { \ + printf(x); \ + } +#define DBG_ERROR(x) \ + if (gwls_data.debug_level >= 0) { \ + printf(x); \ + } +#define PRINT_CFG(x, y) printf(x, y) + +/******************************************************** + Global Variables +********************************************************/ +/**< socket descriptor */ +t_s32 nl_sk = 0; /**< netlink socket descriptor to receive an event */ + +/** Flag: is associated */ +int assoc_flag = FALSE; + +/** terminate flag */ +int mlanwls_terminate_flag = FALSE; + +/******************************************************** + Local Functions +********************************************************/ +/** + * @brief Display help text + * + * @return NA + */ +static t_void display_help(t_u32 n, char **data) +{ + t_u32 i; + for (i = 0; i < n; i++) + fprintf(stderr, "%s\n", data[i]); +} + +/** + * @brief Prepare command buffer + * @param buffer Command buffer to be filled + * @param cmd Command id + * @param num Number of arguments + * @param args Arguments list + * @return MLAN_STATUS_SUCCESS + */ +static int mlanwls_prepare_buffer(t_u8 *buffer, char *cmd, t_u32 num, + char *args[]) +{ + t_u8 *pos = NULL; + unsigned int i = 0; + + memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); + + /* Flag it for our use */ + pos = buffer; + memcpy((char *)pos, CMD_NXP, strlen(CMD_NXP)); + pos += (strlen(CMD_NXP)); + + /* Insert command */ + strncpy((char *)pos, (char *)cmd, strlen(cmd)); + pos += (strlen(cmd)); + + /* Insert arguments */ + for (i = 0; i < num; i++) { + strncpy((char *)pos, args[i], strlen(args[i])); + pos += strlen(args[i]); + if (i < (num - 1)) { + memcpy((char *)pos, " ", strlen(" ")); + pos += 1; + } + } + + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief Process host_cmd response + * + * @param cmd_name The command string + * @param buf A pointer to the response buffer + * + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_ftm_hostcmd_resp(char *cmd_name, t_u8 *buf) +{ + t_u32 hostcmd_size = 0; + HostCmd_DS_GEN *hostcmd = NULL; + int ret = MLAN_STATUS_SUCCESS; + hostcmd_ds_ftm_session_cmd *phostcmd = NULL; + + buf += strlen(CMD_NXP) + strlen(cmd_name); + memcpy((t_u8 *)&hostcmd_size, buf, sizeof(t_u32)); + buf += sizeof(t_u32); + + hostcmd = (HostCmd_DS_GEN *)buf; + hostcmd->command = le16_to_cpu(hostcmd->command); + hostcmd->size = le16_to_cpu(hostcmd->size); + + hostcmd->command &= ~HostCmd_RET_BIT; + + switch (hostcmd->command) { + case HostCmd_CMD_FTM_SESSION_CTRL: + phostcmd = (hostcmd_ds_ftm_session_cmd *)buf; + if (!le16_to_cpu(phostcmd->cmd_hdr.result)) { + if (phostcmd->cmd.ftm_session_ctrl.action == 1) { + printf("[INFO] FTM Session Control Started on %d channel with Peer %02X:%02X:%02X:%02X:%02X:%02X \n", + phostcmd->cmd.ftm_session_ctrl.chan, + phostcmd->cmd.ftm_session_ctrl + .peer_mac[0], + phostcmd->cmd.ftm_session_ctrl + .peer_mac[1], + phostcmd->cmd.ftm_session_ctrl + .peer_mac[2], + phostcmd->cmd.ftm_session_ctrl + .peer_mac[3], + phostcmd->cmd.ftm_session_ctrl + .peer_mac[4], + phostcmd->cmd.ftm_session_ctrl + .peer_mac[5]); + } else if (phostcmd->cmd.ftm_session_ctrl.action == 2) { + printf("[INFO] FTM Session Stopped\n"); + } else { + printf("[ERROR] Hostcmd action not supported\n"); + } + } else { + printf("[ERROR] Hostcmd failed: ReturnCode=%#04x, Result=%#04x\n", + le16_to_cpu(phostcmd->cmd_hdr.command), + le16_to_cpu(phostcmd->cmd_hdr.result)); + ret = MLAN_STATUS_FAILURE; + goto done; + } + break; + + case HostCmd_CMD_FTM_SESSION_CFG: + phostcmd = (hostcmd_ds_ftm_session_cmd *)buf; + if ((le16_to_cpu(phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az + .ntb_tlv.type) == + FTM_NTB_RANGING_CFG_TLV_ID)) { + if (le16_to_cpu(phostcmd->cmd.ftm_session_cfg.action) == + MLAN_ACT_GET) { + /* Get */ + printf("\n\nGet NTB Ranging Parameters: \n"); + } else { + /* Set */ + printf("\n\nSet NTB Ranging Parameters: \n"); + } + printf("---------------------------------\n"); + printf("format_bw:%d \n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az + .ntb_tlv.val.format_bw); + printf("az_measurement_freq:%d \n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az + .ntb_tlv.val.az_measurement_freq); + printf("az_number_of_measurements:%d \n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az + .ntb_tlv.val.az_number_of_measurements); + printf("max_i2r_sts_upto80:%d \n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az + .ntb_tlv.val.max_i2r_sts_upto80); + printf("max_r2i_sts_upto80:%d \n\n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az + .ntb_tlv.val.max_r2i_sts_upto80); + } else if ((le16_to_cpu(phostcmd->cmd.ftm_session_cfg.tlv + .cfg_11mc.sess_tlv.type) == + FTM_SESSION_CFG_INITATOR_TLV_ID)) { + if (le16_to_cpu(phostcmd->cmd.ftm_session_cfg.action) == + MLAN_ACT_GET) { + /* Get */ + printf("\n\nGet dot11mc ftm session config: \n"); + } else { + /* Set */ + printf("\n\nSet dot11mc ftm session config: \n"); + } + printf("---------------------------------\n"); + printf("burst_exponent:%d \n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc + .sess_tlv.val.burst_exponent); + printf("burst_duration:%d \n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc + .sess_tlv.val.burst_duration); + printf("min_delta_FTM:%d \n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc + .sess_tlv.val.min_delta_FTM); + printf("is_ASAP:%d \n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc + .sess_tlv.val.is_ASAP); + printf("per_burst_FTM:%d \n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc + .sess_tlv.val.per_burst_FTM); + printf("channel_spacing:%d \n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc + .sess_tlv.val.channel_spacing); + printf("burst_period:%d \n\n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc + .sess_tlv.val.burst_period); + } else { + printf("[ERROR] Hostcmd failed: Invalid TLV ReturnCode=%#04x, Result=%#04x\n", + le16_to_cpu(phostcmd->cmd_hdr.command), + le16_to_cpu(phostcmd->cmd_hdr.result)); + ret = MLAN_STATUS_FAILURE; + goto done; + } + break; + + default: + ret = MLAN_STATUS_FAILURE; + printf("[ERROR] Invalid Hostcmd %x\n", + phostcmd->cmd_hdr.command); + break; + } + +done: + return ret; +} + +/** + * @brief Send hostcmd IOCTL to driver + * @param cmd_buf pointer to Host Command buffer + * + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ + +static int mlanwls_send_ioctl(t_u8 *cmd_buf) +{ + struct ifreq ifr; + struct eth_priv_cmd *cmd = NULL; + int ret = MLAN_STATUS_SUCCESS; + + /*hexdump((void *) cmd_buf, MRVDRV_SIZE_OF_CMD_BUFFER, ' ');*/ + + if (!cmd_buf) { + printf("ERR:IOCTL Failed due to null cmd buffer!\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR:Cannot allocate buffer for command!\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + /* Fill up buffer */ +#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT + memset(cmd, 0, sizeof(struct eth_priv_cmd)); + memcpy(&cmd->buf, cmd_buf, sizeof(cmd_buf)); +#else + cmd->buf = cmd_buf; +#endif + cmd->used_len = 0; + cmd->total_len = MRVDRV_SIZE_OF_CMD_BUFFER; + + /* Perform IOCTL */ + memset(&ifr, 0, sizeof(struct ifreq)); + strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name)); + ifr.ifr_ifru.ifru_data = (void *)cmd; + + if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) { + perror("mlanwls"); + fprintf(stderr, "IOCTL fail\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + /* Process result */ + ret = process_ftm_hostcmd_resp("hostcmd", cmd_buf); + +done: + if (cmd) + free(cmd); + return ret; +} + +/** + * @brief get connection status + * + * @param data Pointer to the output buffer holding connection status + * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE + */ +static int get_connstatus(int *data) +{ + struct ether_addr apaddr; + struct ether_addr etherzero = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); + if (!buffer) { + DBG_ERROR("[ERROR] Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + /* buffer = CMD_NXP + */ + mlanwls_prepare_buffer(buffer, "getwap", 0, NULL); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + DBG_ERROR("[ERROR] Cannot allocate buffer for command!\n"); + free(buffer); + return MLAN_STATUS_FAILURE; + } + + /* Fill up buffer */ +#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT + memset(cmd, 0, sizeof(struct eth_priv_cmd)); + memcpy(&cmd->buf, &buffer, sizeof(buffer)); +#else + cmd->buf = buffer; +#endif + cmd->used_len = 0; + cmd->total_len = MRVDRV_SIZE_OF_CMD_BUFFER; + + /* Perform IOCTL */ + memset(&ifr, 0, sizeof(struct ifreq)); + strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name)); + ifr.ifr_ifru.ifru_data = (void *)cmd; + + if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) { + DBG_ERROR("[ERROR] mlanwls: getwap fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + memset(&apaddr, 0, sizeof(struct ether_addr)); + memcpy(&apaddr, (struct ether_addr *)(buffer), + sizeof(struct ether_addr)); + memcpy(&gwls_data.ap_mac[0], (t_u8 *)(buffer), + sizeof(gwls_data.ap_mac)); + + if (!memcmp(&apaddr, ðerzero, sizeof(struct ether_addr))) { + /* not associated */ + *data = FALSE; + } else { + /* associated */ + *data = TRUE; + } + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief Parse FTM complete event data + * + * @param buffer Pointer to received event buffer + * @param size Length of the received event data + * @return N/A + */ +static int process_ftm_complete_event(t_u8 *buffer, t_u16 size, char *if_name) +{ + wls_event_t *ftm_event = NULL; + int ret = MLAN_STATUS_SUCCESS; + float distance = 0.0; + + if (!buffer) { + DBG_ERROR("[ERROR] Event buffer null\n"); + return MLAN_STATUS_FAILURE; + } + ftm_event = (wls_event_t *)buffer; + + printf("[INFO] Event received for interface %s\n", if_name); + printf("[INFO] EventID: 0x%x SubeventID:%d\n", ftm_event->event_id, + ftm_event->sub_event_id); + hexdump("EventData:", (void *)buffer, size, ' '); + + switch (ftm_event->sub_event_id) { + case WLS_SUB_EVENT_FTM_COMPLETE: + + printf("\n\nFTM Session Complete:\n"); + printf("=====================\n"); + printf("Average RTT: %d ns\n", + ftm_event->e.ftm_complete.avg_rtt); + printf("Average Clockoffset:%d ns\n", + ftm_event->e.ftm_complete.avg_clk_offset); + + distance = ((ftm_event->e.ftm_complete.avg_clk_offset / 2) * + (0.0003)); + printf("Distance: %f meters\n\n", distance); + + gwls_data.loop_cnt--; + if ((gwls_data.loop_cnt > 0) || (gwls_data.run_nonstop)) { + /*Stop and restart the FTM*/ + process_ftm_start(0, NULL, &gwls_data); + } else { + process_ftm_stop(0, NULL, &gwls_data); + gwls_data.terminate_app = TRUE; + } + + break; + case WLS_SUB_EVENT_RADIO_RECEIVED: + printf("WLS_SUB_EVENT_RADIO_RECEIVED\n"); + break; + case WLS_SUB_EVENT_RADIO_RPT_RECEIVED: + printf("WLS_SUB_EVENT_RADIO_RPT_RECEIVED\n"); + break; + case WLS_SUB_EVENT_ANQP_RESP_RECEIVED: + printf("WLS_SUB_EVENT_ANQP_RESP_RECEIVED\n"); + break; + default: + printf("[ERROR] Unknown sub event\n"); + break; + } + return ret; +} + +/** + * @brief Print connect and disconnect event related information + * + * @param buffer Pointer to received event buffer + * @param size Length of the received event + * + * @return N/A + */ +static void print_event_drv_connected(t_u8 *buffer, t_u16 size) +{ + struct ether_addr *wap; + struct ether_addr etherzero = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + char buf[32]; + + wap = (struct ether_addr *)(buffer + strlen(CUS_EVT_AP_CONNECTED)); + + if (!memcmp(wap, ðerzero, sizeof(struct ether_addr))) { + printf("---< Disconnected from AP >---\n"); + assoc_flag = FALSE; + + } else { + memset(buf, 0, sizeof(buf)); + snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X", + wap->ether_addr_octet[0], wap->ether_addr_octet[1], + wap->ether_addr_octet[2], wap->ether_addr_octet[3], + wap->ether_addr_octet[4], wap->ether_addr_octet[5]); + printf("---< Connected to AP: %s >---\n", buf); + /** set TRUE, if connected */ + assoc_flag = TRUE; + } +} + +/** + * @brief This function parses for NETLINK events + * + * @param nlh Pointer to Netlink message header + * @param bytes_read Number of bytes to be read + * @param evt_conn A pointer to a output buffer. It sets TRUE when it gets + * the event CUS_EVT_OBSS_SCAN_PARAM, otherwise + * FALSE + * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE + */ +static int drv_nlevt_handler(struct nlmsghdr *nlh, int bytes_read, + int *evt_conn) +{ + int len, plen; + t_u8 *buffer = NULL; + t_u32 event_id = 0; + event_header *event = NULL; + char if_name[IFNAMSIZ + 1]; + + /* Initialize receive buffer */ + buffer = (t_u8 *)malloc(NL_MAX_PAYLOAD); + if (!buffer) { + printf("ERR: Could not alloc buffer\n"); + return MLAN_STATUS_FAILURE; + } + memset(buffer, 0, NL_MAX_PAYLOAD); + + *evt_conn = FALSE; + while ((unsigned int)bytes_read >= NLMSG_HDRLEN) { + len = nlh->nlmsg_len; /* Length of message including header */ + plen = len - NLMSG_HDRLEN; + if (len > bytes_read || plen < 0) { + free(buffer); + /* malformed netlink message */ + return MLAN_STATUS_FAILURE; + } + if ((unsigned int)len > NLMSG_SPACE(NL_MAX_PAYLOAD)) { + printf("ERR:Buffer overflow!\n"); + free(buffer); + return MLAN_STATUS_FAILURE; + } + memset(buffer, 0, NL_MAX_PAYLOAD); + memcpy(buffer, NLMSG_DATA(nlh), plen); + + if (NLMSG_OK(nlh, len)) { + memcpy(&event_id, buffer, sizeof(event_id)); + + if (((event_id & 0xFF000000) == 0x80000000) || + ((event_id & 0xFF000000) == 0)) { + event = (event_header *)buffer; + } else { + memset(if_name, 0, IFNAMSIZ + 1); + memcpy(if_name, buffer, IFNAMSIZ); + event = (event_header *)(buffer + IFNAMSIZ); + } + } + + /*Prints the events*/ + if (event) { + switch (event->event_id) { + case EVENT_WLS_FTM_COMPLETE: + process_ftm_complete_event((t_u8 *)event, + bytes_read, if_name); + break; + default: + if (!strncmp(CUS_EVT_AP_CONNECTED, + (char *)event, + strlen(CUS_EVT_AP_CONNECTED))) { + if (strlen(if_name)) + printf("EVENT for interface %s\n", + if_name); + print_event_drv_connected((t_u8 *)event, + bytes_read); + } + break; + } + } + len = NLMSG_ALIGN(len); + bytes_read -= len; + nlh = (struct nlmsghdr *)((char *)nlh + len); + } + free(buffer); + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief Configure and read event data from netlink socket + * + * @param nl_sk Netlink socket handler + * @param msg Pointer to message header + * @param ptv Pointer to struct timeval + * + * @return Number of bytes read or MLAN_STATUS_FAILURE + */ +static int read_event(int nl_sk, struct msghdr *msg, struct timeval *ptv) +{ + int count = -1; + int ret = MLAN_STATUS_FAILURE; + fd_set rfds; + + /* Setup read fds and initialize event buffers */ + FD_ZERO(&rfds); + FD_SET(nl_sk, &rfds); + + /* Wait for reply */ + ret = select(nl_sk + 1, &rfds, NULL, NULL, ptv); + + if (ret == MLAN_STATUS_FAILURE) { + /* Error */ + mlanwls_terminate_flag++; + ptv->tv_sec = DEFAULT_SCAN_INTERVAL; + ptv->tv_usec = 0; + goto done; + } + if (!FD_ISSET(nl_sk, &rfds)) { + /* Unexpected error. Try again */ + ptv->tv_sec = DEFAULT_SCAN_INTERVAL; + ptv->tv_usec = 0; + goto done; + } + /* Success */ + count = recvmsg(nl_sk, msg, 0); + +done: + return count; +} + +/** + * @brief Run the application + * + * @param nl_sk Netlink socket + * + * @return N/A + */ +static void mlanwls_event_handler(int nl_sk) +{ + struct timeval tv; + int bytes_read, evt_conn; + struct msghdr msg; + struct sockaddr_nl dest_addr; + struct nlmsghdr *nlh; + struct iovec iov; + + /* Initialize timeout value */ + tv.tv_sec = DEFAULT_SCAN_INTERVAL; + tv.tv_usec = 0; + + /* Initialize netlink header */ + nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(NL_MAX_PAYLOAD)); + if (!nlh) { + printf("[ERROR] Could not allocate space for netlink header\n"); + goto done; + } + memset(nlh, 0, NLMSG_SPACE(NL_MAX_PAYLOAD)); + /* Fill the netlink message header */ + nlh->nlmsg_len = NLMSG_SPACE(NL_MAX_PAYLOAD); + nlh->nlmsg_pid = getpid(); /* self pid */ + nlh->nlmsg_flags = 0; + + /* Initialize I/O vector */ + memset(&iov, 0, sizeof(struct iovec)); + iov.iov_base = (void *)nlh; + iov.iov_len = nlh->nlmsg_len; + + /* Set destination address */ + memset(&dest_addr, 0, sizeof(struct sockaddr_nl)); + dest_addr.nl_family = AF_NETLINK; + dest_addr.nl_pid = 0; /* Kernel */ + dest_addr.nl_groups = NL_MULTICAST_GROUP; + + /* Initialize message header */ + memset(&msg, 0, sizeof(struct msghdr)); + msg.msg_name = (void *)&dest_addr; + msg.msg_namelen = sizeof(dest_addr); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + while (!gwls_data.terminate_app) { + /* event buffer is received for all the interfaces */ + bytes_read = read_event(nl_sk, &msg, &tv); + /* handle only NETLINK events here */ + drv_nlevt_handler((struct nlmsghdr *)nlh, bytes_read, + &evt_conn); + } + +done: + if (nl_sk > 0) + close(nl_sk); + if (nlh) + free(nlh); + return; +} + +/** + * @brief Process ftm session ntb ranging configuration + * @param argc Number of arguments for the ntb_ranging_cfg command + * @param argv A pointer to start of ntb_ranging_cfg cmd arguments list + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ + +static int process_dot11az_ntb_cfg(int argc, char *argv[], void *param) +{ + int ret = MLAN_STATUS_SUCCESS; + t_u8 *buffer = NULL; + wls_app_data_t *app_data = NULL; + hostcmd_ds_ftm_session_cmd *phostcmd = NULL; + + if (!param) { + ret = MLAN_STATUS_FAILURE; + goto done; + } + app_data = (wls_app_data_t *)param; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); + if (!buffer) { + DBG_ERROR("[ERROR] Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + mlanwls_prepare_buffer(buffer, "hostcmd", 0, NULL); + phostcmd = (hostcmd_ds_ftm_session_cmd *)(buffer + (strlen(CMD_NXP) + + strlen("hostcmd") + + sizeof(t_u32))); + + /*Parse the arguments*/ + phostcmd->cmd_hdr.command = cpu_to_le16(HostCmd_CMD_FTM_SESSION_CFG); + phostcmd->cmd_hdr.size = S_DS_GEN + sizeof(hostcmd_ds_ftm_session_cmd); + phostcmd->cmd_hdr.size = cpu_to_le16(phostcmd->cmd_hdr.size); + phostcmd->cmd.ftm_session_cfg.action = + cpu_to_le16(app_data->hostcmd_action); + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az.ntb_tlv.type = + cpu_to_le16(FTM_NTB_RANGING_CFG_TLV_ID); + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az.ntb_tlv.len = + cpu_to_le16(sizeof(ntb_ranging_cfg_t)); + + if (app_data->hostcmd_action == MLAN_ACT_SET) { + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az.ntb_tlv.val + .format_bw = app_data->ntb_cfg.format_bw; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az.ntb_tlv.val + .max_i2r_sts_upto80 = + app_data->ntb_cfg.max_i2r_sts_upto80; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az.ntb_tlv.val + .max_r2i_sts_upto80 = + app_data->ntb_cfg.max_r2i_sts_upto80; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az.ntb_tlv.val + .az_measurement_freq = + app_data->ntb_cfg.az_measurement_freq; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az.ntb_tlv.val + .az_number_of_measurements = + app_data->ntb_cfg.az_number_of_measurements; + } + /*Perform ioctl and process response*/ + ret = mlanwls_send_ioctl(buffer); + +done: + if (buffer) + free(buffer); + return ret; +} + +/** + * @brief Process dot11mc ftm session configuration + * @param argc Number of arguments for the ntb_ranging_cfg command + * @param argv A pointer to start of ntb_ranging_cfg cmd arguments list + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ + +static int process_dot11mc_ftm_cfg(int argc, char *argv[], void *param) +{ + int ret = MLAN_STATUS_SUCCESS; + t_u8 *buffer = NULL; + wls_app_data_t *app_data = NULL; + hostcmd_ds_ftm_session_cmd *phostcmd = NULL; + + if (!param) { + ret = MLAN_STATUS_FAILURE; + goto done; + } + app_data = (wls_app_data_t *)param; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); + if (!buffer) { + DBG_ERROR("[ERROR] Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + mlanwls_prepare_buffer(buffer, "hostcmd", 0, NULL); + phostcmd = (hostcmd_ds_ftm_session_cmd *)(buffer + (strlen(CMD_NXP) + + strlen("hostcmd") + + sizeof(t_u32))); + + /*Parse the arguments*/ + phostcmd->cmd_hdr.command = cpu_to_le16(HostCmd_CMD_FTM_SESSION_CFG); + phostcmd->cmd_hdr.size = + S_DS_GEN + sizeof(t_u16) + sizeof(dot11mc_ftm_cfg_t); + phostcmd->cmd.ftm_session_cfg.action = + cpu_to_le16(app_data->hostcmd_action); + + if (app_data->hostcmd_action == MLAN_ACT_SET) { + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.sess_tlv.type = + cpu_to_le16(FTM_SESSION_CFG_INITATOR_TLV_ID); + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.sess_tlv.len = + cpu_to_le16(sizeof(ftm_session_cfg_t) + sizeof(t_u16)); + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.sess_tlv.val + .burst_exponent = app_data->session_cfg.burst_exponent; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.sess_tlv.val + .burst_duration = app_data->session_cfg.burst_duration; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.sess_tlv.val + .min_delta_FTM = app_data->session_cfg.min_delta_FTM; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.sess_tlv.val.is_ASAP = + app_data->session_cfg.is_ASAP; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.sess_tlv.val + .per_burst_FTM = app_data->session_cfg.per_burst_FTM; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.sess_tlv.val + .channel_spacing = + app_data->session_cfg.channel_spacing; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.sess_tlv.val + .burst_period = + cpu_to_le16(app_data->session_cfg.burst_period); + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.sess_tlv.civic_req = + app_data->civic_request; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.sess_tlv.lci_req = + app_data->lci_request; + + if (app_data->lci_request) { + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.lci_tlv.type = + cpu_to_le16(FTM_SESSION_CFG_LCI_TLV_ID); + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.lci_tlv.len = + cpu_to_le16(sizeof(lci_cfg_t)); + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.lci_tlv.val + .altitude = app_data->lci_cfg.altitude; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.lci_tlv.val + .alt_unc = app_data->lci_cfg.alt_unc; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.lci_tlv.val + .latitude = app_data->lci_cfg.latitude; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.lci_tlv.val + .lat_unc = app_data->lci_cfg.lat_unc; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.lci_tlv.val + .longitude = app_data->lci_cfg.longitude; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.lci_tlv.val + .long_unc = app_data->lci_cfg.long_unc; + } + + if (app_data->civic_request) { + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.civic_tlv + .type = cpu_to_le16( + FTM_SESSION_CFG_LOCATION_CIVIC_TLV_ID); + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.civic_tlv + .len = cpu_to_le16( + sizeof(civic_loc_cfg_t) + + app_data->civic_cfg.civic_address_length - 1); + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.civic_tlv.val + .civic_address_type = + app_data->civic_cfg.civic_address_type; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.civic_tlv.val + .civic_location_type = + app_data->civic_cfg.civic_location_type; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.civic_tlv.val + .country_code = + cpu_to_le16(app_data->civic_cfg.country_code); + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc.civic_tlv.val + .civic_address_length = + app_data->civic_cfg.civic_address_length; + memcpy(&(phostcmd->cmd.ftm_session_cfg.tlv.cfg_11mc + .civic_tlv.val.civic_address[0]), + &app_data->civic_cfg.civic_address[0], + app_data->civic_cfg.civic_address_length); + phostcmd->cmd_hdr.size += + app_data->civic_cfg + .civic_address_length; /*copy the + variable len + addr size*/ + } + phostcmd->cmd_hdr.size = cpu_to_le16(phostcmd->cmd_hdr.size); + } + /*Perform ioctl and process response*/ + ret = mlanwls_send_ioctl(buffer); + +done: + if (buffer) + free(buffer); + return ret; +} + +/** + * @brief Process 11az/11mc ftm_start command + * @param argc Number of arguments for ftm_start command + * @param argv A pointer to first argument of ftm_start command + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ + +static int process_ftm_start(int argc, char *argv[], void *param) +{ + int ret = MLAN_STATUS_SUCCESS; + t_u8 *buffer = NULL; + wls_app_data_t *app_data = NULL; + hostcmd_ds_ftm_session_cmd *phostcmd = NULL; + + if (!param) { + ret = MLAN_STATUS_FAILURE; + goto done; + } + app_data = (wls_app_data_t *)param; + + /** Get connection status */ + if (get_connstatus(&assoc_flag) == MLAN_STATUS_FAILURE) { + DBG_ERROR("[ERROR] Cannot Start FTM, STA not associated !\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + mlanwls_prepare_buffer(buffer, "hostcmd", 0, NULL); + phostcmd = (hostcmd_ds_ftm_session_cmd *)(buffer + (strlen(CMD_NXP) + + strlen("hostcmd") + + sizeof(t_u32))); + + /*Parse the arguments*/ + phostcmd->cmd_hdr.command = cpu_to_le16(HostCmd_CMD_FTM_SESSION_CTRL); + phostcmd->cmd_hdr.size = S_DS_GEN + sizeof(hostcmd_ftm_session_ctrl); + phostcmd->cmd_hdr.size = cpu_to_le16(phostcmd->cmd_hdr.size); + phostcmd->cmd.ftm_session_ctrl.action = cpu_to_le16(FTM_ACTION_START); + phostcmd->cmd.ftm_session_ctrl.chan = app_data->channel; + memcpy(&phostcmd->cmd.ftm_session_ctrl.peer_mac[0], + &app_data->peer_mac[0], ETH_ALEN); + + /*Perform ioctl and process response*/ + ret = mlanwls_send_ioctl(buffer); + + if (ret == MLAN_STATUS_SUCCESS) { + app_data->ftm_started = TRUE; + + DBG_LOG("[INFO] Wait for session complete event.. \n"); + /** run the application */ + mlanwls_event_handler(nl_sk); + } else { + DBG_ERROR("[ERROR] Starting FTM Session failed\n"); + app_data->ftm_started = FALSE; + } + +done: + if (buffer) + free(buffer); + return ret; +} + +/** + * @brief Handle ftm stop procedure + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ + +static int process_ftm_stop(int argc, char *argv[], void *param) +{ + int ret = MLAN_STATUS_SUCCESS; + t_u8 *buffer = NULL; + wls_app_data_t *app_data = NULL; + hostcmd_ds_ftm_session_cmd *phostcmd = NULL; + + if (!param) { + ret = MLAN_STATUS_FAILURE; + goto done; + } + app_data = (wls_app_data_t *)param; + + if (!app_data->ftm_started) { + DBG_LOG("[INFO] FTM Session already stopped!\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + DBG_ERROR("[ERROR] Cannot allocate buffer for command!\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + mlanwls_prepare_buffer(buffer, "hostcmd", 0, NULL); + phostcmd = (hostcmd_ds_ftm_session_cmd *)(buffer + (strlen(CMD_NXP) + + strlen("hostcmd") + + sizeof(t_u32))); + + /*Parse the arguments*/ + phostcmd->cmd_hdr.command = cpu_to_le16(HostCmd_CMD_FTM_SESSION_CTRL); + phostcmd->cmd_hdr.size = S_DS_GEN + sizeof(hostcmd_ftm_session_ctrl); + phostcmd->cmd_hdr.size = cpu_to_le16(phostcmd->cmd_hdr.size); + phostcmd->cmd.ftm_session_ctrl.action = cpu_to_le16(FTM_ACTION_STOP); + phostcmd->cmd.ftm_session_ctrl.chan = app_data->channel; + memcpy(&phostcmd->cmd.ftm_session_ctrl.peer_mac[0], + &app_data->peer_mac[0], ETH_ALEN); + + /*Perform ioctl and process response*/ + ret = mlanwls_send_ioctl(buffer); + app_data->ftm_started = FALSE; + + if (ret == MLAN_STATUS_FAILURE) { + DBG_ERROR("[ERROR] Hostcmd ftm stop failed\n"); + } + +done: + if (buffer) + free(buffer); + return ret; +} + +/** + * @brief Determine the netlink number + * + * @return Netlink number to use + */ +static int get_netlink_num(int dev_index) +{ + FILE *fp = NULL; + int netlink_num = -1; + char str[64]; + char *srch = "netlink_num"; + char filename[64]; + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + + /* if dev_index is specified by user */ + if (dev_index >= 0) { + /* Try to open old driver proc: /proc/mwlan/configX first */ + if (dev_index == 0) + strcpy(filename, "/proc/mwlan/config"); + else if (dev_index > 0) + sprintf(filename, "/proc/mwlan/config%d", dev_index); + fp = fopen(filename, "r"); + if (!fp) { + /* Try to open multi-adapter driver proc: + * /proc/mwlan/adapterX/config if old proc access fail + */ + snprintf(filename, sizeof(filename), + "/proc/mwlan/adapter%d/config", dev_index); + fp = fopen(filename, "r"); + } + + if (fp) { + while (fgets(str, sizeof(str), fp)) { + if (strncmp(str, srch, strlen(srch)) == 0) { + netlink_num = + atoi(str + strlen(srch) + 1); + break; + } + } + fclose(fp); + } else { + return -1; + } + } else { + /* Start preparing the buffer */ + /* Initialize buffer */ + buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); + if (!buffer) { + DBG_ERROR( + "[ERROR] Cannot allocate buffer for command!\n"); + return -1; + } + /* buffer = CMD_NXP + */ + mlanwls_prepare_buffer(buffer, "getnlnum", 0, NULL); + + cmd = (struct eth_priv_cmd *)malloc( + sizeof(struct eth_priv_cmd)); + if (!cmd) { + DBG_ERROR( + "[ERROR] Cannot allocate buffer for command!\n"); + goto done; + } + + /* Fill up buffer */ +#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT + memset(cmd, 0, sizeof(struct eth_priv_cmd)); + memcpy(&cmd->buf, &buffer, sizeof(buffer)); +#else + cmd->buf = buffer; +#endif + cmd->used_len = 0; + cmd->total_len = MRVDRV_SIZE_OF_CMD_BUFFER; + + /* Perform IOCTL */ + memset(&ifr, 0, sizeof(struct ifreq)); + strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name)); + ifr.ifr_ifru.ifru_data = (void *)cmd; + + if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) { + DBG_ERROR("[ERROR] mlanwls: getnlnum fail\n"); + goto done; + } + netlink_num = *(int *)(buffer); + } + +done: + if (cmd) + free(cmd); + if (buffer) + free(buffer); + printf("[INFO] Netlink number = %d\n", netlink_num); + return netlink_num; +} + +/** + * @brief opens netlink socket to receive NETLINK events + * @return socket id --success, otherwise--MLAN_STATUS_FAILURE + */ +static int open_netlink(int dev_index) +{ + int sk = -1; + struct sockaddr_nl src_addr; + int netlink_num = 0; + + netlink_num = get_netlink_num(dev_index); + if (netlink_num < 0) { + DBG_ERROR( + "[ERROR] Could not get netlink socket. Invalid device number.\n"); + return sk; + } + + /* Open netlink socket */ + sk = socket(PF_NETLINK, SOCK_RAW, netlink_num); + if (sk < 0) { + DBG_ERROR("[ERROR] Could not open netlink socket.\n"); + return sk; + } + + /* Set source address */ + memset(&src_addr, 0, sizeof(src_addr)); + src_addr.nl_family = AF_NETLINK; + src_addr.nl_pid = getpid(); + src_addr.nl_groups = NL_MULTICAST_GROUP; + + /* Bind socket with source address */ + if (bind(sk, (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0) { + DBG_ERROR("[ERROR] Could not bind socket!\n"); + close(sk); + return -1; + } + return sk; +} + +/** + * @brief Terminate signal handler + * @param signal Signal to handle + * @return NA + */ +static t_void mlanwls_terminate_handler(int signal) +{ + printf("[INFO] Stopping application.\n"); +#if DEBUG + printf("Process ID of process killed = %d\n", getpid()); +#endif + gwls_data.run_nonstop = 0; + gwls_data.terminate_app = 1; + process_ftm_stop(0, NULL, &gwls_data); +} + +/** + * @brief Process session ctrl cmd to send hostcmd + * @param param pointer to cmd priv data + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ + +static int process_ftm_session_cfg(int argc, char *argv[], void *param) +{ + int ret = MLAN_STATUS_SUCCESS; + wls_app_data_t *app_data = NULL; + + if (!param) { + ret = MLAN_STATUS_FAILURE; + goto done; + } + app_data = (wls_app_data_t *)param; + + if (app_data->protocol_type == PROTO_DOT11AZ) { + printf("[INFO] Set/Get DOT11AZ Config \n"); + ret = process_dot11az_ntb_cfg(argc, argv, param); + } else { + printf("[INFO] Set/Get DOT11MC (Legacy) Config \n"); + ret = process_dot11mc_ftm_cfg(argc, argv, param); + } + +done: + return ret; +} + +/** + * @brief Process session ctrl cmd to send hostcmd + * @param param pointer to cmd priv data + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_ftm_session_ctrl(int argc, char *argv[], void *param) +{ + int ret = MLAN_STATUS_SUCCESS; + wls_app_data_t *app_data = NULL; + + if (!param) { + ret = MLAN_STATUS_FAILURE; + goto done; + } + app_data = (wls_app_data_t *)param; + + if (app_data->hostcmd_action == FTM_ACTION_START) { + ret = process_ftm_start(argc, argv, param); + } else { + ret = process_ftm_stop(argc, argv, param); + } +done: + return ret; +} + +/** + * @brief Parse the user command and process it + * @param start_idx Start of ftm command argument in user command + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ + +static int process_subcommand(int argc, char *argv[]) +{ + int i, ret; + + /*Parse the user command to update the priv data and call subcommand + * handlers*/ + for (i = 0; wls_app_command[i].cmd; i++) { + if (strncmp(wls_app_command[i].cmd, argv[FTM_SUBCMD_INDEX], + strlen(wls_app_command[i].cmd))) + continue; + if (strlen(wls_app_command[i].cmd) != + strlen(argv[FTM_SUBCMD_INDEX])) + continue; + + switch (wls_app_command[i].cmd_id) { + case FTM_SESSION_CFG_CMD_ID: + if (FTM_CFG_SET_CMD_LEN == argc) { + gwls_data.hostcmd_action = MLAN_ACT_SET; + gwls_data.protocol_type = + atoi(argv[FTM_CFG_PROTOCOL_INDEX]); + mlanwls_read_ftm_config( + argv[FTM_CFG_FILE_ARG_INDEX]); + + } else if (FTM_CFG_GET_CMD_LEN == argc) { + /*ToDo: FW Implemention for GET operation*/ + gwls_data.hostcmd_action = MLAN_ACT_GET; + } else { + DBG_ERROR( + "[ERROR] Invalid number of arguments\n\n"); + display_help(NELEMENTS(ftm_session_cfg_help), + ftm_session_cfg_help); + ret = MLAN_STATUS_FAILURE; + goto done; + } + break; + case FTM_SESSION_CTRL_CMD_ID: + + if (FTM_SESSION_SUBCMD_LEN == (argc) || + (FTM_SESSION_SUBCMD_NONSTOP_LEN == (argc))) { + gwls_data.channel = a2hex_or_atoi( + argv[FTM_SESSION_CHANNEL_OFFSET]); + gwls_data.hostcmd_action = a2hex_or_atoi( + argv[FTM_SESSION_ACTION_OFFSET]); + + ret = mac2raw( + argv[FTM_SESSION_PEER_ADDR_OFFSET], + &(gwls_data.peer_mac[0])); + if (ret != MLAN_STATUS_SUCCESS) { + printf("[ERROR] %s Address \n", + ret == MLAN_STATUS_FAILURE ? + "Invalid MAC" : + ret == MAC_BROADCAST ? + "Broadcast" : + "Multicast"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + if (FTM_SESSION_SUBCMD_LEN == (argc)) { + gwls_data.loop_cnt = a2hex_or_atoi( + argv[FTM_SESSION_LOOP_OFFSET]); + gwls_data.run_nonstop = + (gwls_data.loop_cnt == 0) ? 1 : + 0; + + } else { + gwls_data.loop_cnt = 1; + } + + } else { + DBG_ERROR( + "[ERROR] Invalid number of arguments\n"); + display_help(NELEMENTS(ftm_session_ctrl_help), + ftm_session_ctrl_help); + ret = MLAN_STATUS_FAILURE; + goto done; + } + break; + default: + printf("[ERROR] SubCommand %s is not supported\n", + argv[FTM_SUBCMD_INDEX]); + display_help(NELEMENTS(mlanwls_help), mlanwls_help); + ret = MLAN_STATUS_FAILURE; + goto done; + break; + } + + ret = wls_app_command[i].func(argc, argv, &gwls_data); + printf("[INFO] Command %s processed. Return:%d \n", + wls_app_command[i].cmd, ret); + break; + } + +done: + if (!wls_app_command[i].cmd) + display_help(NELEMENTS(mlanwls_help), mlanwls_help); + return ret; +} + +/** + * @brief Read ftm config param from conf file + * @param file_name config file name + * + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ + +static int mlanwls_read_ftm_config(char *file_name) +{ + int ret = MLAN_STATUS_SUCCESS; + FILE *config_file = NULL; + char *line = NULL; + char *data = NULL; + int arg_num, li; + char *args[30]; + t_u8 param; + + // read config + config_file = fopen(file_name, "r"); + if (config_file == NULL) { + perror("CONFIG"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + line = (char *)malloc(MAX_CONFIG_LINE); + if (!line) { + printf("ERR:Cannot allocate memory for line\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + memset(line, 0, MAX_CONFIG_LINE); + + printf("[INFO] Read FTM config from file %s\n", file_name); + while (config_get_line(line, MAX_CONFIG_LINE, config_file, &li, + &data)) { + arg_num = parse_line(line, args, 30); + + if (arg_num > 1) + param = atoi(args[1]); + + if (gwls_data.protocol_type == PROTO_DOT11MC) { + if (strcmp(args[0], "DOT11MC_CFG") == 0) { + printf("DOT11MC_CFG\n"); + } else if (strcmp(args[0], "BURST_EXP") == 0) { + gwls_data.session_cfg.burst_exponent = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t BURST_EXP=%d\n", param); + } else if (strcmp(args[0], "BURST_DURATION") == 0) { + gwls_data.session_cfg.burst_duration = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t BURST_DURATION=%d\n", param); + } else if (strcmp(args[0], "MIN_DELTA") == 0) { + gwls_data.session_cfg.min_delta_FTM = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t MIN_DELTA=%d\n", param); + } else if (strcmp(args[0], "IS_ASAP") == 0) { + gwls_data.session_cfg.is_ASAP = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t IS_ASAP=%d\n", param); + } else if (strcmp(args[0], "FTM_PER_BURST") == 0) { + gwls_data.session_cfg.per_burst_FTM = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t FTM_PER_BURST=%d\n", param); + } else if (strcmp(args[0], "BW") == 0) { + gwls_data.session_cfg.channel_spacing = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t BW=%d\n", param); + } else if (strcmp(args[0], "BURST_PERIOD") == 0) { + gwls_data.session_cfg.burst_period = + (t_u16)(atoi(args[1])); + PRINT_CFG("\t BURST_PERIOD=%d\n", param); + + } else if (strcmp(args[0], "LCI_REQUEST") == 0) { + gwls_data.lci_request = (t_u8)(atoi(args[1])); + PRINT_CFG("\t LCI_REQUEST=%d\n", param); + + } else if (strcmp(args[0], "LATITIUDE") == 0) { + gwls_data.lci_cfg.latitude = + (double)(atof(args[1])); + PRINT_CFG("\t LATITIUDE=%lf\n", + gwls_data.lci_cfg.latitude); + + } else if (strcmp(args[0], "LONGITUDE") == 0) { + gwls_data.lci_cfg.longitude = + (double)(atof(args[1])); + PRINT_CFG("\t LATITIUDE=%lf\n", + gwls_data.lci_cfg.longitude); + + } else if (strcmp(args[0], "LATITUDE_UNCERTAINITY") == + 0) { + gwls_data.lci_cfg.lat_unc = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t LATITUDE_UNCERTAINITY=%d\n", + param); + + } else if (strcmp(args[0], "LONGITUDE_UNCERTAINITY") == + 0) { + gwls_data.lci_cfg.long_unc = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t LONGITUDE_UNCERTAINITY=%d\n", + param); + + } else if (strcmp(args[0], "ALTITUDE") == 0) { + gwls_data.lci_cfg.altitude = + (double)(atof(args[1])); + PRINT_CFG("\t ALTITUDE=%lf\n", + gwls_data.lci_cfg.altitude); + + } else if (strcmp(args[0], "ALTITUDE_UNCERTAINITY") == + 0) { + gwls_data.lci_cfg.alt_unc = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t ALTITUDE_UNCERTAINITY=%d\n", + param); + + } else if (strcmp(args[0], "CIVIC_LOCATION") == 0) { + gwls_data.civic_request = (t_u8)(atoi(args[1])); + PRINT_CFG("\t CIVIC_LOCATION=%d\n", param); + + } else if (strcmp(args[0], "CIVIC_LOCATION_TYPE") == + 0) { + gwls_data.civic_cfg.civic_location_type = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t CIVIC_LOCATION_TYPE=%d\n", param); + + } else if (strcmp(args[0], "COUNTRY_CODE") == 0) { + gwls_data.civic_cfg.country_code = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t COUNTRY_CODE=%d\n", param); + + } else if (strcmp(args[0], "CIVIC_ADDRESS_TYPE") == 0) { + gwls_data.civic_cfg.civic_address_type = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t CIVIC_ADDRESS_TYPE=%d\n", param); + + } else if (strcmp(args[0], "ADDRESS") == 0) { + memcpy(&(gwls_data.civic_cfg.civic_address[0]), + &args[1], strlen(args[1])); + gwls_data.civic_cfg.civic_address_length = + strlen(args[1]); + PRINT_CFG("\t ADDRESS=%s\n", args[1]); + + } else { + // printf("Invalid line entry\n %s",args[1]); + } + } + + if (gwls_data.protocol_type == PROTO_DOT11AZ) { + if (strcmp(args[0], "DOT11AZ_CFG") == 0) { + printf("DOT11AZ_CFG\n\n"); + } else if (strcmp(args[0], "FORMAT_BW") == 0) { + gwls_data.ntb_cfg.format_bw = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t FORMAT_BW=%d\n", param); + } else if (strcmp(args[0], "MAX_I2R_STS_UPTO80") == 0) { + gwls_data.ntb_cfg.max_i2r_sts_upto80 = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t MAX_I2R_STS_UPTO80=%d\n", param); + } else if (strcmp(args[0], "MAX_R2I_STS_UPTO80") == 0) { + gwls_data.ntb_cfg.max_r2i_sts_upto80 = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t MAX_R2I_STS_UPTO80=%d\n", param); + } else if (strcmp(args[0], "AZ_MEASUREMENT_FREQ") == + 0) { + gwls_data.ntb_cfg.az_measurement_freq = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t AZ_MEASUREMENT_FREQ=%d\n", param); + } else if (strcmp(args[0], + "AZ_NUMBER_OF_MEASUREMENTS") == 0) { + gwls_data.ntb_cfg.az_number_of_measurements = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t AZ_NUMBER_OF_MEASUREMENTS=%d\n", + param); + } else { + // printf("Invalid line entry%s\n",args[1]); + } + } + } + +done: + if (line) + free(line); + if (config_file) + fclose(config_file); + return ret; +} + +/** + * @brief Initialize ftm command private data + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int mlanwls_init(void) +{ + int ret = MLAN_STATUS_SUCCESS; + + memset(&gwls_data, 0, sizeof(wls_app_data_t)); + + /*Initialize app private data with default values*/ + gwls_data.associated = 0; + gwls_data.bss_type = 0; + gwls_data.channel = 0; + gwls_data.loop_cnt = 1; + gwls_data.run_nonstop = 0; + gwls_data.debug_level = 1; + gwls_data.ftm_started = 0; + gwls_data.terminate_app = 0; + gwls_data.protocol_type = 0; + + /*DOT11AZ NTB Ranging default config*/ + gwls_data.ntb_cfg.az_measurement_freq = 1; + gwls_data.ntb_cfg.az_number_of_measurements = 6; + gwls_data.ntb_cfg.format_bw = 2; + gwls_data.ntb_cfg.max_i2r_sts_upto80 = 0; + gwls_data.ntb_cfg.max_r2i_sts_upto80 = 1; + + /*DOT11MC FTM session default config*/ + gwls_data.session_cfg.burst_exponent = 0; + gwls_data.session_cfg.burst_duration = 10; + gwls_data.session_cfg.burst_period = 5; + gwls_data.session_cfg.is_ASAP = 1; + gwls_data.session_cfg.per_burst_FTM = 10; + gwls_data.session_cfg.min_delta_FTM = 10; + gwls_data.session_cfg.channel_spacing = 13; + + /*DOT11MC FTM civic location config*/ + gwls_data.civic_request = 1; + strncpy((char *)&gwls_data.civic_cfg.civic_address[0], NXP_ADDR, + strlen(NXP_ADDR)); + gwls_data.civic_cfg.civic_address_length = strlen(NXP_ADDR); + gwls_data.civic_cfg.civic_address_type = 22; + gwls_data.civic_cfg.civic_location_type = 1; + gwls_data.civic_cfg.country_code = 0; + + /*DOT11MC FTM LCI config*/ + gwls_data.lci_request = 1; + gwls_data.lci_cfg.altitude = 11.2; + gwls_data.lci_cfg.alt_unc = 15; + gwls_data.lci_cfg.latitude = -33.8570095; + gwls_data.lci_cfg.lat_unc = 18; + gwls_data.lci_cfg.longitude = +151.2152005; + gwls_data.lci_cfg.long_unc = 18; + gwls_data.lci_cfg.z_info = 0; + + return ret; +} + +/******************************************************** + Global Functions +********************************************************/ +/** + * @brief Entry function for mlan location service + * @param argc number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +int mlanwls_main(int argc, char *argv[]) +{ + int dev_index = 0; //-1; /** initialise with -1 to open multiple NETLINK + //Sockets */ + int ret = MLAN_STATUS_SUCCESS; + + printf("\n\n---------------------------------------------\n"); + printf("------- NXP Wifi Location Service (WLS)------\n"); + printf("--------------------------------------------------\n\n"); + + if (argc < 4) { + display_help(NELEMENTS(mlanwls_help), mlanwls_help); + return MLAN_STATUS_FAILURE; + } + + /*Initialize private data*/ + printf("[INFO] Initializing App\n"); + ret = mlanwls_init(); + + /*Set the interface*/ + memset(dev_name, 0, sizeof(dev_name)); + strncpy(dev_name, argv[1], strlen(argv[1])); + + /* create a socket */ + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + DBG_ERROR("[ERROR] mlanwls: Cannot open socket.\n"); + goto done; + } + /* create netlink sockets and bind them with app side addr */ + nl_sk = open_netlink(dev_index); + + if (nl_sk < 0) { + DBG_ERROR("[ERROR] mlanwls: Cannot open netlink socket.\n"); + goto done; + } + signal(SIGHUP, mlanwls_terminate_handler); /* catch hangup signal */ + signal(SIGTERM, mlanwls_terminate_handler); /* catch kill signal */ + signal(SIGINT, mlanwls_terminate_handler); /* catch kill signal */ + signal(SIGALRM, mlanwls_terminate_handler); /* catch kill signal */ + + /*Process the wlscmd sub command argument*/ + ret = process_subcommand(argc, argv); + +done: + if (sockfd > 0) + close(sockfd); + if (nl_sk > 0) + close(nl_sk); + + return ret; +} diff --git a/mxm_wifiex/wlan_src/mapp/mlanutl/mlanwls.h b/mxm_wifiex/wlan_src/mapp/mlanutl/mlanwls.h new file mode 100644 index 0000000..843f6be --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanutl/mlanwls.h @@ -0,0 +1,375 @@ +/** @file mlanwls.h + * + * @brief 11mc/11az Wifi location services application + * + * + * Copyright 2022 NXP + * + * This software file (the File) is distributed by NXP + * under the terms of the GNU General Public License Version 2, June 1991 + * (the License). You may use, redistribute and/or modify the File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + * + */ +/************************************************************************ +Change log: + 01/24/2022: initial version +************************************************************************/ +#ifndef _WLS_H_ +#define _WLS_H_ + +/** Size of command buffer */ +#define MRVDRV_SIZE_OF_CMD_BUFFER (3 * 1024) + +/** MAC BROADCAST */ +#define MAC_BROADCAST 0x1FF +/** MAC MULTICAST */ +#define MAC_MULTICAST 0x1FE +/** Default scan interval in second*/ +#define DEFAULT_SCAN_INTERVAL 300 + +/** Netlink protocol number */ +#define NETLINK_NXP (MAX_LINKS - 1) +/** Netlink maximum payload size */ +#define NL_MAX_PAYLOAD 1024 +/** Default wait time in seconds for events */ +#define UAP_RECV_WAIT_DEFAULT 10 +#ifndef NLMSG_HDRLEN +/** NL message header length */ +#define NLMSG_HDRLEN ((int)NLMSG_ALIGN(sizeof(struct nlmsghdr))) +#endif + +/** Host Command ID : FTM session config and control */ +#define HostCmd_CMD_FTM_SESSION_CFG 0x024d +#define HostCmd_CMD_FTM_SESSION_CTRL 0x024E +#define HostCmd_CMD_FTM_FEATURE_CTRL 0x024f +#define HostCmd_CMD_WLS_REQ_FTM_RANGE 0x0250 + +/** Events*/ +#define EVENT_WLS_FTM_COMPLETE 0x00000086 +#define WLS_SUB_EVENT_FTM_COMPLETE 0 +#define WLS_SUB_EVENT_RADIO_RECEIVED 1 +#define WLS_SUB_EVENT_RADIO_RPT_RECEIVED 2 +#define WLS_SUB_EVENT_ANQP_RESP_RECEIVED 3 +#define WLS_SUB_EVENT_RTT_RESULTS 4 + +/** Custom events definitions */ +/** AP connected event */ +#define CUS_EVT_AP_CONNECTED "EVENT=AP_CONNECTED" +/** Custom events definitions end */ + +/*TLVs*/ +/** TLV type ID definition */ +#define PROPRIETARY_TLV_BASE_ID 0x0100 +#define FTM_SESSION_CFG_INITATOR_TLV_ID (PROPRIETARY_TLV_BASE_ID + 273) +#define FTM_NTB_RANGING_CFG_TLV_ID (PROPRIETARY_TLV_BASE_ID + 343) +#define FTM_RANGE_REPORT_TLV_ID \ + (PROPRIETARY_TLV_BASE_ID + 0x10C) /* 0x0100 + 0x10C = 0x20C */ +#define FTM_SESSION_CFG_LCI_TLV_ID (PROPRIETARY_TLV_BASE_ID + 270) +#define FTM_SESSION_CFG_LOCATION_CIVIC_TLV_ID (PROPRIETARY_TLV_BASE_ID + 271) + +/** Structure of command table*/ +typedef struct { + /** User Command ID*/ + int cmd_id; + /** Command name */ + char *cmd; + /** Command function pointer */ + int (*func)(int argc, char *argv[], void *param); + /** Command usuage */ + char **help; +} wls_app_command_table; + +/** Structure of FTM_SESSION_CFG_NTB_RANGING TLV data*/ +typedef struct _ntb_ranging_cfg { + /** Indicates the channel BW for session*/ + /*0: HE20, 1: HE40, 2: HE80, 3: HE80+80, 4: HE160, 5:HE160_SRF*/ + t_u8 format_bw; + /** indicates for bandwidths less than or equal to 80 MHz the maximum + * number of space-time streams to be used in DL/UL NDP frames in the + * session*/ + t_u8 max_i2r_sts_upto80; + /**indicates for bandwidths less than or equal to 80 MHz the maximum + * number of space-time streams to be used in DL/UL NDP frames in the + * session*/ + t_u8 max_r2i_sts_upto80; + /**Specify measurement freq in Hz to calculate measurement interval*/ + t_u8 az_measurement_freq; + /**Indicates the number of measurements to be done for session*/ + t_u8 az_number_of_measurements; + /**Include location civic request (Expect location civic from + * responder)*/ + t_u8 civic_req; + /**Include LCI request (Expect LCI info from responder)*/ + t_u8 lci_req; +} __ATTRIB_PACK__ ntb_ranging_cfg_t; + +/** Structure of FTM_SESSION_CFG TLV data*/ +typedef struct _ftm_session_cfg { + /** Indicates how many burst instances are requested for the FTM + * session*/ + t_u8 burst_exponent; + /** Indicates the duration of a burst instance*/ + t_u8 burst_duration; + /**Minimum time between consecutive FTM frames*/ + t_u8 min_delta_FTM; + /**ASAP/non-ASAP casel*/ + t_u8 is_ASAP; + /**Number of FTMs per burst*/ + t_u8 per_burst_FTM; + /**FTM channel spacing: HT20/HT40/VHT80/…*/ + t_u8 channel_spacing; + /**Indicates the interval between two consecutive burst instances*/ + t_u16 burst_period; +} __ATTRIB_PACK__ ftm_session_cfg_t; + +/** Structure for FTM_SESSION_CFG_LOCATION_CIVIC TLV data*/ +typedef struct _civic_loc_cfg { + /**Civic location type*/ + t_u8 civic_location_type; + /**Country code*/ + t_u16 country_code; + /**Civic address type*/ + t_u8 civic_address_type; + /**Civic address length*/ + t_u8 civic_address_length; + /**Civic Address*/ + t_u8 civic_address[]; +} __ATTRIB_PACK__ civic_loc_cfg_t; + +/** Structure for FTM_SESSION_CFG_LCI TLV data*/ +typedef struct _lci_cfg { + /** known longitude*/ + double longitude; + /** known Latitude*/ + double latitude; + /** known altitude*/ + double altitude; + /** known Latitude uncertainty*/ + t_u8 lat_unc; + /** known Longitude uncertainty*/ + t_u8 long_unc; + /** Known Altitude uncertainty*/ + t_u8 alt_unc; + /** 1 word for additional Z information */ + t_u32 z_info; +} __ATTRIB_PACK__ lci_cfg_t; + +/** Structure for FTM_SESSION_CFG_NTB_RANGING TLV*/ +typedef struct _ntb_ranging_cfg_tlv { + /** Type*/ + t_u16 type; + /** Length*/ + t_u16 len; + /** Value*/ + ntb_ranging_cfg_t val; +} __ATTRIB_PACK__ ntb_ranging_cfg_tlv_t; + +/** Structure for FTM_SESSION_CFG TLV*/ +typedef struct _ftm_session_cfg_tlv { + /** Type*/ + t_u16 type; + /** Length*/ + t_u16 len; + /** Value*/ + ftm_session_cfg_t val; + t_u8 civic_req; + t_u8 lci_req; +} __ATTRIB_PACK__ ftm_session_cfg_tlv_t; + +/** Structure for FTM_SESSION_CFG_LOCATION_CIVIC TLV*/ +typedef struct _civic_loc_tlv { + /** Type*/ + t_u16 type; + /** Length*/ + t_u16 len; + /** Value*/ + civic_loc_cfg_t val; +} __ATTRIB_PACK__ civic_loc_tlv_t; + +/** Structure for FTM_SESSION_CFG_LCI TLV*/ +typedef struct _lci_tlv { + /** Type*/ + t_u16 type; + /** Length*/ + t_u16 len; + /** Value*/ + lci_cfg_t val; +} __ATTRIB_PACK__ lci_tlv_t; + +/** Structure for DOT11MC FTM_SESSION_CFG */ +typedef struct _dot11mc_ftm_cfg { + /** FTM session cfg*/ + ftm_session_cfg_tlv_t sess_tlv; + /** Location Request cfg*/ + lci_tlv_t lci_tlv; + /** Civic location cfg*/ + civic_loc_tlv_t civic_tlv; + +} __ATTRIB_PACK__ dot11mc_ftm_cfg_t; + +/** Structure for DOT11AZ FTM_SESSION_CFG */ +typedef struct _dot11az_ftmcfg_ntb_t { + /** NTB session cfg */ + ntb_ranging_cfg_tlv_t ntb_tlv; +} __ATTRIB_PACK__ dot11az_ftm_cfg_t; + +/** Type definition for hostcmd_ftm_session_cfg */ +typedef struct _hostcmd_ftm_session_cfg { + /** 0:Get, 1:Set */ + t_u16 action; + /** FTM_SESSION_CFG_TLVs*/ + union { + /**11az cfg*/ + dot11az_ftm_cfg_t cfg_11az; + /** 11mc cfg*/ + dot11mc_ftm_cfg_t cfg_11mc; + } tlv; +} __ATTRIB_PACK__ hostcmd_ftm_session_cfg; + +/** Type definition for hostcmd_ftm_session_ctrl */ +typedef struct _hostcmd_ftm_session_ctrl { + /** 0: Not used, 1: Start, 2: Stop*/ + t_u16 action; + /*FTM for ranging*/ + t_u8 for_ranging; + /** Mac address of the peer with whom FTM session is required*/ + t_u8 peer_mac[ETH_ALEN]; + /** Channel on which FTM must be started */ + t_u8 chan; +} __ATTRIB_PACK__ hostcmd_ftm_session_ctrl; + +/** Type definition for generic Hostcmd for 11AZ FTM Session */ +typedef struct _hostcmd_ds_ftm_session_cmd { + /** HostCmd_DS_GEN */ + HostCmd_DS_GEN cmd_hdr; + /** Command Body */ + union { + /** hostcmd for session_ctrl user command */ + hostcmd_ftm_session_ctrl ftm_session_ctrl; + /** hostcmd for session_cfg user command */ + hostcmd_ftm_session_cfg ftm_session_cfg; + } cmd; +} __ATTRIB_PACK__ hostcmd_ds_ftm_session_cmd; + +/** Type definition for FTM Session Events */ + +/** Event ID length */ +#define EVENT_ID_LEN 4 + +/**Structure for RTT results subevent*/ +typedef struct _wls_subevent_rtt_results_t { + /** complete */ + t_u8 complete; + /** tlv buffer */ + /** MrvlIEtypes_RTTResult_t */ + t_u8 tlv_buffer[]; +} __ATTRIB_PACK__ wls_subevent_rtt_results_t; + +/**Structure for FTM complete subevent*/ +typedef struct _wls_subevent_ftm_complete { + /** BSS Number */ + t_u8 bssNum; + /** BSS Type */ + t_u8 bssType; + /** MAC address of the responder */ + t_u8 mac[ETH_ALEN]; + /** Average RTT */ + t_u32 avg_rtt; + /** Average Clock offset */ + t_u32 avg_clk_offset; + /** Measure start timestamp */ + t_u32 meas_start_tsf; +} __ATTRIB_PACK__ wls_subevent_ftm_complete_t; + +/** TLV for FTM Range Report */ +typedef struct _range_report_tlv_t { + /**Type*/ + t_u16 type; + /**Length*/ + t_u16 len; + /** MAC address of the responder */ + t_u8 mac[ETH_ALEN]; + /** Average RTT */ + t_u32 avg_rtt; + /** Average Clock offset */ + t_u32 avg_clk_offset; + /** LCI and Location Civic TLV */ +} __ATTRIB_PACK__ range_report_tlv_t; + +/** Structure for FTM events*/ +typedef struct _wls_event_t { + /** Event ID */ + t_u16 event_id; + /** BSS index number for multiple BSS support */ + t_u8 bss_index; + /** BSS type */ + t_u8 bss_type; + /** sub event id */ + t_u8 sub_event_id; + union { + /** FTM Complete Sub event*/ + wls_subevent_ftm_complete_t ftm_complete; + } e; +} __ATTRIB_PACK__ wls_event_t; + +/*Application Global Data*/ +typedef struct { + /** Average RTT */ + t_u32 avg_rtt; + /** Average Clock offset */ + t_u32 avg_clk_offset; + /*Range*/ + t_s64 range; +} range_results_t; + +/** Structure for ftm command private data*/ +typedef struct _wls_app_data { + /** 0 : 80211mc, 1:80211az*/ + t_u8 protocol_type; + /** num of times to run FTM*/ + t_u8 loop_cnt; + /** flag to run nonstop*/ + t_u8 run_nonstop; + /** flag is associated */ + t_u8 associated; + /** 0 - STA, 1- AP*/ + t_u8 bss_type; + /**flag for ftm started */ + t_u8 ftm_started; + /** flag for app to terminate ftm session*/ + t_u8 terminate_app; + /**flag for debug print level */ + t_u8 debug_level; + /**peer mac address */ + t_u8 peer_mac[ETH_ALEN]; + /**AP mac address */ + t_u8 ap_mac[ETH_ALEN]; + /** Channel number for FTM session*/ + t_u8 channel; + /**SET/GET action */ + t_u8 hostcmd_action; + /**Is LCI data available in cfg*/ + t_u8 lci_request; + /** Is civic data available in cfg*/ + t_u8 civic_request; + /**ntb cfg param*/ + ntb_ranging_cfg_t ntb_cfg; + /** 11mc session cfg param*/ + ftm_session_cfg_t session_cfg; + /** lci cfg data*/ + lci_cfg_t lci_cfg; + /** civic cfg data - this should be last field*/ + civic_loc_cfg_t civic_cfg; +} __ATTRIB_PACK__ wls_app_data_t; + +int mlanwls_main(int argc, char *argv[]); +#endif /* _WLS_H_ */ diff --git a/mxm_wifiex/wlan_src/mlan/mlan.h b/mxm_wifiex/wlan_src/mlan/mlan.h index 566ad50..4d48ce8 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan.h +++ b/mxm_wifiex/wlan_src/mlan/mlan.h @@ -4,7 +4,7 @@ * It also defines the data structures used for APIs between MLAN and MOAL. * * - * Copyright 2008-2020 NXP + * Copyright 2008-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11ac.c b/mxm_wifiex/wlan_src/mlan/mlan_11ac.c index 7ea58f9..0bed1d4 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11ac.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_11ac.c @@ -192,7 +192,7 @@ static t_u8 wlan_get_nss_num_vht_mcs(t_u16 mcs_map_set) * @return N/A */ static void wlan_fill_cap_info(mlan_private *priv, VHT_capa_t *vht_cap, - t_u8 bands) + t_u16 bands) { t_u32 usr_dot_11ac_dev_cap; ENTER(); @@ -228,7 +228,8 @@ static mlan_status wlan_11ac_ioctl_vhtcfg(pmlan_adapter pmadapter, t_u32 hw_value = 0; t_u8 nss = 0; #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(USB9097) || defined(SD9097) + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) t_u16 rx_nss = 0; t_u16 tx_nss = 0; #endif @@ -311,8 +312,10 @@ static mlan_status wlan_11ac_ioctl_vhtcfg(pmlan_adapter pmadapter, /** update the RX MCS map */ if (cfg->param.vht_cfg.txrx & MLAN_RADIO_RX) { #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if (IS_CARD9098(pmadapter->card_type) || + IS_CARDNW62X(pmadapter->card_type) || IS_CARD9097(pmadapter->card_type)) { if (cfg->param.vht_cfg.band == BAND_SELECT_A) { rx_nss = GET_RXMCSSUPP( @@ -343,7 +346,8 @@ static mlan_status wlan_11ac_ioctl_vhtcfg(pmlan_adapter pmadapter, pmadapter->hw_dot_11ac_mcs_support, nss); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if ((rx_nss != 0) && (nss > rx_nss)) cfg_value = NO_NSS_SUPPORT; #endif @@ -370,7 +374,8 @@ static mlan_status wlan_11ac_ioctl_vhtcfg(pmlan_adapter pmadapter, pmadapter->hw_dot_11ac_mcs_support, nss); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if ((tx_nss != 0) && (nss > tx_nss)) cfg_value = NO_NSS_SUPPORT; #endif @@ -795,7 +800,8 @@ void wlan_fill_vht_cap_tlv(mlan_private *priv, MrvlIETypes_VHTCap_t *pvht_cap, t_u16 mcs_resp = 0; t_u16 nss; #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) | defined(USBNW62X) t_u16 rx_nss = 0, tx_nss = 0; #endif ENTER(); @@ -816,8 +822,10 @@ void wlan_fill_vht_cap_tlv(mlan_private *priv, MrvlIETypes_VHTCap_t *pvht_cap, mcs_map_resp = wlan_le16_to_cpu(pvht_cap->vht_cap.mcs_sets.rx_mcs_map); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if (IS_CARD9098(priv->adapter->card_type) || + IS_CARDNW62X(priv->adapter->card_type) || IS_CARD9097(priv->adapter->card_type)) { if (bands & BAND_A) { rx_nss = GET_RXMCSSUPP(priv->adapter->user_htstream >> @@ -840,7 +848,8 @@ void wlan_fill_vht_cap_tlv(mlan_private *priv, MrvlIETypes_VHTCap_t *pvht_cap, mcs_user = GET_VHTNSSMCS(mcs_map_user, nss); mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if ((rx_nss != 0) && (nss > rx_nss)) mcs_user = NO_NSS_SUPPORT; #endif @@ -872,7 +881,8 @@ void wlan_fill_vht_cap_tlv(mlan_private *priv, MrvlIETypes_VHTCap_t *pvht_cap, mcs_user = GET_VHTNSSMCS(mcs_map_user, nss); mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if ((tx_nss != 0) && (nss > tx_nss)) mcs_user = NO_NSS_SUPPORT; #endif @@ -1088,7 +1098,8 @@ t_u8 wlan_is_80_80_support(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc) { t_u8 ret = MFALSE; #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) t_u16 rx_nss = 0, tx_nss = 0; IEEEtypes_VHTCap_t *pvht_cap = pbss_desc->pvht_cap; MrvlIEtypes_He_cap_t *phecap = MNULL; @@ -1098,8 +1109,10 @@ t_u8 wlan_is_80_80_support(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc) ENTER(); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if (!IS_CARD9098(pmpriv->adapter->card_type) && + !IS_CARDNW62X(pmpriv->adapter->card_type) && !IS_CARD9097(pmpriv->adapter->card_type)) return ret; /** check band A */ @@ -1151,7 +1164,8 @@ int wlan_cmd_append_11ac_tlv(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc, int ret_len = 0; t_u8 bw_80p80 = MFALSE; #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(USB9097) || defined(SD9097) + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) t_u16 rx_nss = 0; #endif @@ -1222,8 +1236,10 @@ int wlan_cmd_append_11ac_tlv(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc, /** set default bandwidth:80M*/ SET_OPER_MODE_80M(pmrvl_oper_mode->oper_mode); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if (IS_CARD9098(pmadapter->card_type) || + IS_CARDNW62X(pmadapter->card_type) || IS_CARD9097(pmadapter->card_type)) { if (pbss_desc->bss_band & BAND_A) rx_nss = GET_RXMCSSUPP( @@ -1238,8 +1254,10 @@ int wlan_cmd_append_11ac_tlv(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc, nss = wlan_get_nss_num_vht_mcs(mcs_map_user); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if (IS_CARD9098(pmadapter->card_type) || + IS_CARDNW62X(pmadapter->card_type) || IS_CARD9097(pmadapter->card_type)) { PRINTM(MCMND, "rx_nss=%d nss=%d\n", rx_nss, nss); nss = MIN(rx_nss, nss); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11ax.c b/mxm_wifiex/wlan_src/mlan/mlan_11ax.c index 6a94fcc..b3d4515 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11ax.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_11ax.c @@ -3,7 +3,7 @@ * @brief This file contains the functions for 11ax related features. * * - * Copyright 2018-2021 NXP + * Copyright 2018-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -142,6 +142,140 @@ static void wlan_show_dot11axphycap(pmlan_adapter pmadapter, t_u32 support) return; } #endif + +/** + * @brief This function fills the HE CAP IE w/ output format LE, not CPU + * + * @param priv A pointer to mlan_private structure + * @param hecap_ie A pointer to IEEEtypes_HECap_t structure + * @param band BAND_A (5G), otherwise, 2.4G + * + * @return bytes added to the phe_cap + */ +t_u8 wlan_fill_he_cap_ie(mlan_private *pmpriv, IEEEtypes_HECap_t *hecap_ie, + t_u16 band) +{ + pmlan_adapter pmadapter = pmpriv->adapter; + MrvlIEtypes_He_cap_t *user_hecap_tlv = MNULL; + MrvlIEtypes_He_cap_t *hw_hecap_tlv = MNULL; + IEEEtypes_HeMcsNss_t *he_mcsnss = MNULL; + t_u8 nss = 0; + t_u16 cfg_value = 0; + t_u16 hw_value = 0; + + if (band & BAND_A) { + user_hecap_tlv = (MrvlIEtypes_He_cap_t *)(pmpriv->user_he_cap); + hw_hecap_tlv = (MrvlIEtypes_He_cap_t *)pmadapter->hw_he_cap; + } else { + user_hecap_tlv = + (MrvlIEtypes_He_cap_t *)(pmpriv->user_2g_he_cap); + hw_hecap_tlv = (MrvlIEtypes_He_cap_t *)pmadapter->hw_2g_he_cap; + } + + // include PPE threshold + memcpy_ext(pmadapter, (t_u8 *)hecap_ie + sizeof(IEEEtypes_Header_t), + (t_u8 *)user_hecap_tlv + sizeof(MrvlIEtypesHeader_t), + user_hecap_tlv->len, + sizeof(IEEEtypes_HECap_t) - sizeof(IEEEtypes_Header_t)); + + hecap_ie->ieee_hdr.element_id = EXTENSION; + hecap_ie->ieee_hdr.len = + MIN(user_hecap_tlv->len, + sizeof(IEEEtypes_HECap_t) - sizeof(IEEEtypes_Header_t)); + hecap_ie->ext_id = HE_CAPABILITY; + + he_mcsnss = (IEEEtypes_HeMcsNss_t *)hecap_ie->he_txrx_mcs_support; + + cfg_value = GET_HE_NSSMCS(user_hecap_tlv->rx_mcs_80, nss); + hw_value = GET_HE_NSSMCS(hw_hecap_tlv->rx_mcs_80, nss); + for (nss = 1; nss <= 8; nss++) { + if ((hw_value == NO_NSS_SUPPORT) || + (cfg_value == NO_NSS_SUPPORT)) { + SET_HE_NSSMCS(he_mcsnss->rx_mcs, nss, NO_NSS_SUPPORT); + } else { + SET_HE_NSSMCS(he_mcsnss->rx_mcs, nss, + MIN(cfg_value, hw_value)); + } + } + + cfg_value = GET_HE_NSSMCS(user_hecap_tlv->tx_mcs_80, nss); + hw_value = GET_HE_NSSMCS(hw_hecap_tlv->tx_mcs_80, nss); + for (nss = 1; nss <= 8; nss++) { + if ((hw_value == NO_NSS_SUPPORT) || + (cfg_value == NO_NSS_SUPPORT)) { + SET_HE_NSSMCS(he_mcsnss->tx_mcs, nss, NO_NSS_SUPPORT); + } else { + SET_HE_NSSMCS(he_mcsnss->tx_mcs, nss, + MIN(cfg_value, hw_value)); + } + } + PRINTM(MCMND, + "fill_11ax_ie: HE rx mcs_80 = 0x%08x tx mcs 80 = 0x%08x\n", + he_mcsnss->rx_mcs, he_mcsnss->tx_mcs); + + DBG_HEXDUMP(MCMD_D, "fill_11ax_ie", (t_u8 *)hecap_ie, + hecap_ie->ieee_hdr.len + sizeof(IEEEtypes_Header_t)); + return hecap_ie->ieee_hdr.len; +} + +/** + * @brief This function fills the HE cap tlv out put format is LE, not CPU + * + * @param priv A pointer to mlan_private structure + * @param phe_cap A pointer to IEEEtypes_HECap_t structure + * @param band BAND_A (5G), otherwise, 2.4G + * + * @return bytes added to the phe_cap + */ +t_u8 wlan_fill_he_op_ie(mlan_private *pmpriv, IEEEtypes_HeOp_t *heop_ie) +{ + pmlan_adapter pmadapter = pmpriv->adapter; + BSSDescriptor_t *pbss_desc = &pmpriv->curr_bss_params.bss_descriptor; + IEEEtypes_HeOp_t *bss_heop_ie = MNULL; + + memset(pmadapter, (void *)heop_ie, 0, sizeof(IEEEtypes_HeOp_t)); + + heop_ie->ieee_hdr.element_id = EXTENSION; + heop_ie->ieee_hdr.len = sizeof(IEEEtypes_HeOp_t) - + sizeof(IEEEtypes_Header_t) - + sizeof(heop_ie->option); + heop_ie->ext_id = HE_OPERATION; + + // HE Operation Parameters + heop_ie->he_op_param.default_pe_dur = 7; + heop_ie->he_op_param.twt_req = 0; + heop_ie->he_op_param.txop_dur_rts_threshold = 12; + heop_ie->he_op_param.vht_op_info_present = 0; + heop_ie->he_op_param.co_located_bss = 0; + heop_ie->he_op_param.er_su_disable = 0; + // HE BSS Color Information (following the AP) + if (pbss_desc->phe_oprat) { + bss_heop_ie = (IEEEtypes_HeOp_t *)(pbss_desc->phe_oprat); + heop_ie->bss_color_info.bss_color = + bss_heop_ie->bss_color_info.bss_color; + } else { + // default color + heop_ie->bss_color_info.bss_color = 1; + } + heop_ie->bss_color_info.partial_bss_color = 0; + heop_ie->bss_color_info.bss_color_disabled = 0; + // Rx HE MCS MAP + heop_ie->basic_he_mcs_nss.max_mcs_1ss = 0; +#if defined(SD9177) + heop_ie->basic_he_mcs_nss.max_mcs_2ss = 3; +#else + heop_ie->basic_he_mcs_nss.max_mcs_2ss = 0; +#endif + heop_ie->basic_he_mcs_nss.max_mcs_3ss = 3; + heop_ie->basic_he_mcs_nss.max_mcs_4ss = 3; + heop_ie->basic_he_mcs_nss.max_mcs_5ss = 3; + heop_ie->basic_he_mcs_nss.max_mcs_6ss = 3; + heop_ie->basic_he_mcs_nss.max_mcs_7ss = 3; + heop_ie->basic_he_mcs_nss.max_mcs_8ss = 3; + + return heop_ie->ieee_hdr.len; +} + /** * @brief This function fills the HE cap tlv out put format is LE, not CPU * @@ -153,13 +287,14 @@ static void wlan_show_dot11axphycap(pmlan_adapter pmadapter, t_u32 support) * * @return bytes added to the phe_cap */ -t_u16 wlan_fill_he_cap_tlv(mlan_private *pmpriv, t_u8 band, +t_u16 wlan_fill_he_cap_tlv(mlan_private *pmpriv, t_u16 band, MrvlIEtypes_Extension_t *phe_cap, t_u8 flag) { pmlan_adapter pmadapter = pmpriv->adapter; t_u16 len = 0; #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) t_u16 rx_nss = 0, tx_nss = 0; #endif MrvlIEtypes_He_cap_t *phecap = MNULL; @@ -172,7 +307,7 @@ t_u16 wlan_fill_he_cap_tlv(mlan_private *pmpriv, t_u8 band, LEAVE(); return 0; } - if (band & BAND_A) { + if (band & BAND_AAX) { memcpy_ext(pmadapter, (t_u8 *)phe_cap, pmpriv->user_he_cap, pmpriv->user_hecap_len, sizeof(MrvlIEtypes_He_cap_t)); @@ -188,10 +323,11 @@ t_u16 wlan_fill_he_cap_tlv(mlan_private *pmpriv, t_u8 band, phe_cap->type = wlan_cpu_to_le16(phe_cap->type); phe_cap->len = wlan_cpu_to_le16(phe_cap->len); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if (IS_CARD9098(pmpriv->adapter->card_type) || IS_CARD9097(pmpriv->adapter->card_type)) { - if (band & BAND_A) { + if (band & BAND_AAX) { rx_nss = GET_RXMCSSUPP(pmpriv->adapter->user_htstream >> 8); tx_nss = GET_TXMCSSUPP(pmpriv->adapter->user_htstream >> @@ -209,7 +345,8 @@ t_u16 wlan_fill_he_cap_tlv(mlan_private *pmpriv, t_u8 band, cfg_value = GET_HE_NSSMCS(phecap->rx_mcs_80, nss); hw_value = GET_HE_NSSMCS(phw_hecap->rx_mcs_80, nss); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if ((rx_nss != 0) && (nss > rx_nss)) cfg_value = NO_NSS_SUPPORT; #endif @@ -224,7 +361,8 @@ t_u16 wlan_fill_he_cap_tlv(mlan_private *pmpriv, t_u8 band, cfg_value = GET_HE_NSSMCS(phecap->tx_mcs_80, nss); hw_value = GET_HE_NSSMCS(phw_hecap->tx_mcs_80, nss); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if ((tx_nss != 0) && (nss > tx_nss)) cfg_value = NO_NSS_SUPPORT; #endif @@ -260,7 +398,8 @@ int wlan_cmd_append_11ax_tlv(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc, int len = 0; t_u8 bw_80p80 = MFALSE; #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) t_u16 rx_nss = 0, tx_nss = 0; #endif t_u8 nss = 0; @@ -303,8 +442,10 @@ int wlan_cmd_append_11ax_tlv(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc, phecap->type = wlan_cpu_to_le16(phecap->type); phecap->len = wlan_cpu_to_le16(phecap->len); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if (IS_CARD9098(pmpriv->adapter->card_type) || + IS_CARDNW62X(pmpriv->adapter->card_type) || IS_CARD9097(pmpriv->adapter->card_type)) { if (pbss_desc->bss_band & BAND_A) { rx_nss = GET_RXMCSSUPP(pmpriv->adapter->user_htstream >> @@ -326,7 +467,8 @@ int wlan_cmd_append_11ax_tlv(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc, cfg_value = GET_HE_NSSMCS(phecap->rx_mcs_80, nss); hw_value = GET_HE_NSSMCS(phw_hecap->rx_mcs_80, nss); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if ((rx_nss != 0) && (nss > rx_nss)) cfg_value = NO_NSS_SUPPORT; #endif @@ -341,7 +483,8 @@ int wlan_cmd_append_11ax_tlv(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc, cfg_value = GET_HE_NSSMCS(phecap->tx_mcs_80, nss); hw_value = GET_HE_NSSMCS(phw_hecap->tx_mcs_80, nss); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if ((tx_nss != 0) && (nss > tx_nss)) cfg_value = NO_NSS_SUPPORT; #endif @@ -447,13 +590,15 @@ void wlan_update_11ax_cap(mlan_adapter *pmadapter, * @brief This function check if 11AX is allowed in bandcfg * * @param pmpriv A pointer to mlan_private structure - * @param bss_band bss band + * @param pbss_desc A pointer to BSSDescriptor_t * * @return 0--not allowed, other value allowed */ -t_u16 wlan_11ax_bandconfig_allowed(mlan_private *pmpriv, t_u16 bss_band) +t_u16 wlan_11ax_bandconfig_allowed(mlan_private *pmpriv, + BSSDescriptor_t *pbss_desc) { - if (!IS_FW_SUPPORT_11AX(pmpriv->adapter)) + t_u16 bss_band = pbss_desc->bss_band; + if (pbss_desc->disable_11n) return MFALSE; if (pmpriv->bss_mode == MLAN_BSS_MODE_IBSS) { if (bss_band & BAND_G) @@ -597,7 +742,6 @@ mlan_status wlan_cmd_11ax_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, cmd->size += hecfg->he_cap.len + sizeof(MrvlIEtypesHeader_t); pos += hecfg->he_cap.len + sizeof(MrvlIEtypesHeader_t); } - cmd->size = wlan_cpu_to_le16(cmd->size); LEAVE(); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11ax.h b/mxm_wifiex/wlan_src/mlan/mlan_11ax.h index 8a8c3f9..3125551 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11ax.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_11ax.h @@ -3,7 +3,7 @@ * @brief This file contains the functions for station ioctl. * * - * Copyright 2018-2020 NXP + * Copyright 2018-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -44,13 +44,18 @@ mlan_status wlan_11ax_ioctl_twtcfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); mlan_status wlan_cmd_twt_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, t_void *pdata_buf); -t_u16 wlan_fill_he_cap_tlv(mlan_private *pmpriv, t_u8 band, +t_u8 wlan_fill_he_cap_ie(mlan_private *pmpriv, IEEEtypes_HECap_t *hecap_ie, + t_u16 band); +t_u8 wlan_fill_he_op_ie(mlan_private *pmpriv, IEEEtypes_HeOp_t *heop_ie); +t_u16 wlan_fill_he_cap_tlv(mlan_private *pmpriv, t_u16 band, MrvlIEtypes_Extension_t *phe_cap, t_u8 flag); void wlan_update_11ax_cap(mlan_adapter *pmadapter, MrvlIEtypes_Extension_t *hw_he_cap); + int wlan_cmd_append_11ax_tlv(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc, t_u8 **ppbuffer); -t_u16 wlan_11ax_bandconfig_allowed(mlan_private *pmpriv, t_u16 bss_band); +t_u16 wlan_11ax_bandconfig_allowed(mlan_private *pmpriv, + BSSDescriptor_t *pbss_desc); mlan_status wlan_11ax_cfg_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); mlan_status wlan_11ax_ioctl_cmd(pmlan_adapter pmadapter, diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11d.c b/mxm_wifiex/wlan_src/mlan/mlan_11d.c index a3ef84e..5e57748 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11d.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_11d.c @@ -3,7 +3,7 @@ * @brief This file contains functions for 802.11D. * * - * Copyright 2008-2020 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -119,14 +119,16 @@ static chan_freq_power_t channel_freq_power_UN_AJ[] = { {153, 5765, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}, {157, 5785, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}, {161, 5805, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}, - {165, 5825, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}} + {165, 5825, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}, + {169, 5845, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}, + {173, 5865, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}, + {177, 5885, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}} /* {240, 4920, TX_PWR_DEFAULT}, {244, 4940, TX_PWR_DEFAULT}, {248, 4960, TX_PWR_DEFAULT}, {252, 4980, TX_PWR_DEFAULT}, channels for 11J JP 10M channel gap */ }; - /******************************************************** Global Variables ********************************************************/ @@ -172,7 +174,7 @@ static t_u8 *wlan_11d_code_2_region(pmlan_adapter pmadapter, t_u8 code) * * @return MTRUE or MFALSE */ -static t_u8 wlan_11d_channel_known(pmlan_adapter pmadapter, t_u8 band, +static t_u8 wlan_11d_channel_known(pmlan_adapter pmadapter, t_u16 band, t_u8 chan, parsed_region_chan_11d_t *parsed_region_chan) { @@ -294,6 +296,8 @@ wlan_11d_generate_domain_info(pmlan_adapter pmadapter, /* Should be only place that clear domain_reg (besides init) */ memset(pmadapter, domain_info, 0, sizeof(wlan_802_11d_domain_reg_t)); + domain_info->dfs_region = NXP_DFS_UNKNOWN; + /* Set country code */ memcpy_ext(pmadapter, domain_info->country_code, wlan_11d_code_2_region(pmadapter, @@ -375,7 +379,8 @@ static mlan_status wlan_11d_update_chan_pwr_table(mlan_private *pmpriv, chan = pbss_desc->phy_param_set.ds_param_set.current_chan; - tx_power = wlan_get_txpwr_of_chan_from_cfp(pmpriv, chan); + tx_power = wlan_get_txpwr_of_chan_from_cfp(pmpriv, pbss_desc->bss_band, + chan); if (!tx_power) { PRINTM(MMSG, "11D: Invalid channel\n"); @@ -426,7 +431,7 @@ static mlan_status wlan_11d_update_chan_pwr_table(mlan_private *pmpriv, * * @return MTRUE or MFALSE */ -static t_u8 wlan_11d_get_chan(pmlan_adapter pmadapter, t_u8 band, +static t_u8 wlan_11d_get_chan(pmlan_adapter pmadapter, t_u16 band, t_u8 first_chan, t_u8 no_of_chan, t_u8 *chan) { chan_freq_power_t *cfp = MNULL; @@ -490,7 +495,7 @@ static mlan_status wlan_11d_process_country_info(mlan_private *pmpriv, /* Parse 11D country info */ if (wlan_11d_parse_domain_info(pmadapter, &pbss_desc->country_info, - (t_u8)pbss_desc->bss_band, + pbss_desc->bss_band, ®ion_chan) != MLAN_STATUS_SUCCESS) { LEAVE(); return MLAN_STATUS_FAILURE; @@ -659,13 +664,14 @@ static mlan_status wlan_11d_send_domain_info(mlan_private *pmpriv, * @param country_code Intended country code * @param num_sub_band Count of tuples in list below * @param sub_band_list List of sub_band tuples + * @param dfs_region 0-unset,1-fcc,2-etsi,3-JP, 0xff-unknown * * @return MLAN_STATUS_SUCCESS */ static mlan_status -wlan_11d_set_domain_info(mlan_private *pmpriv, t_u8 band, +wlan_11d_set_domain_info(mlan_private *pmpriv, t_u16 band, t_u8 country_code[COUNTRY_CODE_LEN], t_u8 num_sub_band, - IEEEtypes_SubbandSet_t *sub_band_list) + IEEEtypes_SubbandSet_t *sub_band_list, t_u8 dfs_region) { mlan_adapter *pmadapter = pmpriv->adapter; wlan_802_11d_domain_reg_t *pdomain = &pmadapter->domain_reg; @@ -674,6 +680,7 @@ wlan_11d_set_domain_info(mlan_private *pmpriv, t_u8 band, ENTER(); memset(pmadapter, pdomain, 0, sizeof(wlan_802_11d_domain_reg_t)); + pdomain->dfs_region = dfs_region; memcpy_ext(pmadapter, pdomain->country_code, country_code, COUNTRY_CODE_LEN, COUNTRY_CODE_LEN); pdomain->band = band; @@ -846,13 +853,15 @@ mlan_status wlan_cmd_802_11d_domain_info(mlan_private *pmpriv, &pcmd->params.domain_info; MrvlIEtypes_DomainParamSet_t *domain = &pdomain_info->domain; t_u8 no_of_sub_band = pmadapter->domain_reg.no_of_sub_band; + MrvlIEtypes_Rgn_dom_code_t *rgn = MNULL; t_u8 i; ENTER(); - PRINTM(MCMND, "11D:Country=%c%c band=%d sub-band=5d\n", + PRINTM(MCMND, "11D:Country=%c%c band=%d sub-band=%d dfs_region=%d\n", pmadapter->domain_reg.country_code[0], pmadapter->domain_reg.country_code[1], - pmadapter->domain_reg.band, no_of_sub_band); + pmadapter->domain_reg.band, no_of_sub_band, + pmadapter->domain_reg.dfs_region); for (i = 0; i < no_of_sub_band; i++) { PRINTM(MCMND, "11D: first chan=%d no_of_chan=%d, max_tx_pwr=%d\n", @@ -890,15 +899,25 @@ mlan_status wlan_cmd_802_11d_domain_info(mlan_private *pmpriv, MRVDRV_MAX_SUBBAND_802_11D * sizeof(IEEEtypes_SubbandSet_t)); - pcmd->size = wlan_cpu_to_le16( - sizeof(pdomain_info->action) + domain->header.len + - sizeof(MrvlIEtypesHeader_t) + S_DS_GEN); + pcmd->size = sizeof(pdomain_info->action) + domain->header.len + + sizeof(MrvlIEtypesHeader_t) + S_DS_GEN; + + if (pmadapter->domain_reg.dfs_region != NXP_DFS_UNKNOWN) { + rgn = (MrvlIEtypes_Rgn_dom_code_t + *)((t_u8 *)&pdomain_info->domain + + domain->header.len + + sizeof(MrvlIEtypesHeader_t)); + rgn->header.type = + wlan_cpu_to_le16(TLV_TYPE_REGION_DOMAIN_CODE); + rgn->header.len = 2; + rgn->domain_code = pmadapter->domain_reg.dfs_region; + pcmd->size += sizeof(MrvlIEtypes_Rgn_dom_code_t); + } } else { - pcmd->size = wlan_cpu_to_le16(sizeof(pdomain_info->action) + - S_DS_GEN); + pcmd->size = sizeof(pdomain_info->action) + S_DS_GEN; } domain->header.len = wlan_cpu_to_le16(domain->header.len); - + pcmd->size = wlan_cpu_to_le16(pcmd->size); HEXDUMP("11D: 802_11D_DOMAIN_INFO", (t_u8 *)pcmd, wlan_le16_to_cpu(pcmd->size)); @@ -967,7 +986,7 @@ mlan_status wlan_ret_802_11d_domain_info(mlan_private *pmpriv, * * @return Channel frequency */ -t_u32 wlan_11d_chan_2_freq(pmlan_adapter pmadapter, t_u8 chan, t_u8 band) +t_u32 wlan_11d_chan_2_freq(pmlan_adapter pmadapter, t_u8 chan, t_u16 band) { chan_freq_power_t *cf; t_u16 cnt; @@ -976,15 +995,19 @@ t_u32 wlan_11d_chan_2_freq(pmlan_adapter pmadapter, t_u8 chan, t_u8 band) ENTER(); - /* Get channel-frequency-power trios */ - if (band & (BAND_A | BAND_AN | BAND_AAC)) { - cf = channel_freq_power_UN_AJ; - cnt = NELEMENTS(channel_freq_power_UN_AJ); - } else { + if (band & (BAND_B | BAND_G | BAND_GN | BAND_GAC)) { cf = channel_freq_power_UN_BG; cnt = NELEMENTS(channel_freq_power_UN_BG); } - + /* Get channel-frequency-power trios */ + else if (band & (BAND_A | BAND_AN | BAND_AAC)) { + cf = channel_freq_power_UN_AJ; + cnt = NELEMENTS(channel_freq_power_UN_AJ); + } else { + PRINTM(MERROR, "11D: Wrong Band [%d]\n", band); + LEAVE(); + return 0; + } /* Locate channel and return corresponding frequency */ for (i = 0; i < cnt; i++) { if (chan == cf[i].channel) @@ -1008,7 +1031,7 @@ t_u32 wlan_11d_chan_2_freq(pmlan_adapter pmadapter, t_u8 chan, t_u8 band) */ mlan_status wlan_11d_parse_domain_info( pmlan_adapter pmadapter, IEEEtypes_CountryInfoFullSet_t *country_info, - t_u8 band, parsed_region_chan_11d_t *parsed_region_chan) + t_u16 band, parsed_region_chan_11d_t *parsed_region_chan) { t_u8 no_of_sub_band, no_of_chan; t_u8 last_chan, first_chan, cur_chan = 0; @@ -1096,7 +1119,7 @@ mlan_status wlan_11d_parse_domain_info( * * @return MLAN_STATUS_SUCCESS */ -mlan_status wlan_11d_set_universaltable(mlan_private *pmpriv, t_u8 band) +mlan_status wlan_11d_set_universaltable(mlan_private *pmpriv, t_u16 band) { mlan_adapter *pmadapter = pmpriv->adapter; t_u16 i = 0; @@ -1166,7 +1189,7 @@ mlan_status wlan_11d_set_universaltable(mlan_private *pmpriv, t_u8 band) * @return PASSIVE if chan is unknown; ACTIVE * if chan is known */ -t_u8 wlan_11d_get_scan_type(pmlan_adapter pmadapter, t_u8 band, t_u8 chan, +t_u8 wlan_11d_get_scan_type(pmlan_adapter pmadapter, t_u16 band, t_u8 chan, parsed_region_chan_11d_t *parsed_region_chan) { t_u8 scan_type = MLAN_SCAN_TYPE_PASSIVE; @@ -1218,7 +1241,7 @@ mlan_status wlan_11d_clear_parsedtable(mlan_private *pmpriv) * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ -mlan_status wlan_11d_create_dnld_countryinfo(mlan_private *pmpriv, t_u8 band) +mlan_status wlan_11d_create_dnld_countryinfo(mlan_private *pmpriv, t_u16 band) { mlan_status ret = MLAN_STATUS_SUCCESS; mlan_adapter *pmadapter = pmpriv->adapter; @@ -1342,8 +1365,7 @@ mlan_status wlan_11d_parse_dnld_countryinfo(mlan_private *pmpriv, /* Parse domain info if available */ ret = wlan_11d_parse_domain_info( pmadapter, &pbss_desc->country_info, - (t_u8)pbss_desc->bss_band, - &bssdesc_region_chan); + pbss_desc->bss_band, &bssdesc_region_chan); if (ret == MLAN_STATUS_SUCCESS) { /* Update the channel-power table */ @@ -1514,7 +1536,8 @@ mlan_status wlan_11d_cfg_domain_info(pmlan_adapter pmadapter, pmpriv, domain_info->band, wlan_11d_map_country_code(pmadapter, domain_info->country_code), domain_info->no_of_sub_band, - (IEEEtypes_SubbandSet_t *)domain_info->sub_band); + (IEEEtypes_SubbandSet_t *)domain_info->sub_band, + domain_info->dfs_region); ret = wlan_11d_send_domain_info(pmpriv, pioctl_req); if (ret == MLAN_STATUS_SUCCESS) @@ -1559,7 +1582,7 @@ done: * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ -mlan_status wlan_11d_handle_uap_domain_info(mlan_private *pmpriv, t_u8 band, +mlan_status wlan_11d_handle_uap_domain_info(mlan_private *pmpriv, t_u16 band, t_u8 *domain_tlv, t_void *pioctl_buf) { @@ -1603,7 +1626,8 @@ mlan_status wlan_11d_handle_uap_domain_info(mlan_private *pmpriv, t_u8 band, * Add some checking or merging between STA & UAP domain_info */ wlan_11d_set_domain_info(pmpriv, band, pdomain_tlv->country_code, - num_sub_band, pdomain_tlv->sub_band); + num_sub_band, pdomain_tlv->sub_band, + NXP_DFS_UNKNOWN); ret = wlan_11d_send_domain_info(pmpriv, pioctl_buf); done: diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11h.c b/mxm_wifiex/wlan_src/mlan/mlan_11h.c index dafbffb..5f8671c 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11h.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_11h.c @@ -118,6 +118,8 @@ static const IEEEtypes_SupportChan_Subband_t wlan_11h_unii_mid_upper_band_1 = { /** U-NII sub-band config : Start Channel = 149, NumChans = 5 */ static const IEEEtypes_SupportChan_Subband_t wlan_11h_unii_upper_band = {149, 5}; +/** U-NII sub-band config : Start Channel = 169, NumChans = 3 */ +static const IEEEtypes_SupportChan_Subband_t wlan_11h_unii_4_band = {169, 3}; /** Internally passed structure used to send a CMD_802_11_TPC_INFO command */ typedef struct { @@ -298,7 +300,7 @@ static t_u32 wlan_11h_set_ibss_dfs_ie(mlan_private *priv, * - 0 if returned element is not setup */ static t_u16 -wlan_11h_set_supp_channels_ie(mlan_private *priv, t_u8 band, +wlan_11h_set_supp_channels_ie(mlan_private *priv, t_u16 band, IEEEtypes_SupportedChannels_t *psup_chan) { t_u16 num_subbands = 0; @@ -352,6 +354,17 @@ wlan_11h_set_supp_channels_ie(mlan_private *priv, t_u8 band, */ switch (cfp_a) { case 0x10: /* USA FCC */ + psup_chan->subband[num_subbands++] = + wlan_11h_unii_lower_band; + psup_chan->subband[num_subbands++] = + wlan_11h_unii_middle_band; + psup_chan->subband[num_subbands++] = + wlan_11h_unii_mid_upper_band; + psup_chan->subband[num_subbands++] = + wlan_11h_unii_upper_band; + psup_chan->subband[num_subbands++] = + wlan_11h_unii_4_band; + break; case 0x20: /* Canada IC */ case 0x30: /* Europe ETSI */ default: @@ -589,6 +602,7 @@ static mlan_status wlan_11h_cmd_chan_rpt_req(mlan_private *priv, wlan_dfs_device_state_t *pstate_dfs = &priv->adapter->state_dfs; MrvlIEtypes_ChanRpt11hBasic_t *ptlv_basic; t_bool is_cancel_req = MFALSE; + MrvlIEtypes_ZeroDfsOperation_t *ptlv_zero_dfs; t_u8 dfs53cfg = priv->adapter->dfs53cfg; MrvlIEtypes_DfsW53Cfg_t *ptlv_dfs53cfg; @@ -601,7 +615,8 @@ static mlan_status wlan_11h_cmd_chan_rpt_req(mlan_private *priv, if (pchan_rpt_req->millisec_dwell_time == 0) is_cancel_req = MTRUE; - if (pstate_dfs->dfs_check_pending && !is_cancel_req) { + if (pstate_dfs->dfs_check_pending && !is_cancel_req && + priv->bss_type != MLAN_BSS_TYPE_DFS) { PRINTM(MERROR, "11h: ChanRptReq - previous CMD_CHAN_REPORT_REQUEST has" " not returned its result yet (as EVENT_CHANNEL_READY)." @@ -650,6 +665,29 @@ static mlan_status wlan_11h_cmd_chan_rpt_req(mlan_private *priv, pcmd_ptr->size += sizeof(MrvlIEtypes_DfsW53Cfg_t); } + if (priv->bss_type == MLAN_BSS_TYPE_DFS) { + memcpy_ext(priv->adapter, &priv->chan_rep_req, pchan_rpt_req, + sizeof(mlan_ds_11h_chan_rep_req), + sizeof(priv->chan_rep_req)); + ptlv_zero_dfs = + (MrvlIEtypes_ZeroDfsOperation_t *)(((t_u8 *)(pcmd_ptr)) + + pcmd_ptr->size); + ptlv_zero_dfs->Header.type = + wlan_cpu_to_le16(TLV_TYPE_ZERO_DFS_OPERATION); + ptlv_zero_dfs->Header.len = wlan_cpu_to_le16(sizeof(t_u8)); + if (!is_cancel_req) { + ptlv_zero_dfs->zero_dfs_enbl = MTRUE; + PRINTM(MCMND, "ZeroDFS: START: chan=%d\n", + pchan_rpt_req->chan_desc.chanNum); + } else { + ptlv_zero_dfs->zero_dfs_enbl = MFALSE; + PRINTM(MCMND, "ZeroDFS: STOP\n"); + } + pcmd_ptr->size += sizeof(MrvlIEtypes_ZeroDfsOperation_t); + pcmd_ptr->size = wlan_cpu_to_le16(pcmd_ptr->size); + LEAVE(); + return MLAN_STATUS_SUCCESS; + } pcmd_ptr->size = wlan_cpu_to_le16(pcmd_ptr->size); /* update dfs sturcture. @@ -733,7 +771,7 @@ static t_u32 wlan_11h_set_local_power_constraint_tlv( * buffer (ppbuffer) */ static t_u32 wlan_11h_process_infra_join(mlan_private *priv, t_u8 **ppbuffer, - t_u8 band, t_u32 channel, + t_u16 band, t_u32 channel, wlan_11h_bss_info_t *p11h_bss_info) { MrvlIEtypesHeader_t ie_header; @@ -1352,6 +1390,8 @@ static t_bool wlan_11h_is_band_valid(mlan_private *priv, t_u8 start_chn, * return MFALSE, 165 is not allowed in bands other than 20MHZ */ if (start_chn == 165) { + if (priv->adapter->region_code == COUNTRY_CODE_US) + return MTRUE; if (uap_band_cfg.chanWidth != CHAN_BW_20MHZ) return MFALSE; } @@ -1916,6 +1956,7 @@ t_void wlan_11h_cleanup(mlan_adapter *adapter) { wlan_dfs_device_state_t *pstate_dfs = &adapter->state_dfs; wlan_dfs_timestamp_t *pdfs_ts; + mlan_private *priv = MNULL; ENTER(); @@ -1926,6 +1967,10 @@ t_void wlan_11h_cleanup(mlan_adapter *adapter) util_unlink_list(adapter->pmoal_handle, &pstate_dfs->dfs_ts_head, (pmlan_linked_list)pdfs_ts, MNULL, MNULL); + priv = wlan_get_priv(adapter, MLAN_BSS_ROLE_ANY); + if (priv) + wlan_set_chan_dfs_state(priv, BAND_A, pdfs_ts->channel, + DFS_USABLE); adapter->callbacks.moal_mfree(adapter->pmoal_handle, (t_u8 *)pdfs_ts); @@ -2448,7 +2493,7 @@ t_s32 wlan_11h_process_start(mlan_private *priv, t_u8 **ppbuffer, * or MLAN_STATUS_SUCCESS (0) */ t_s32 wlan_11h_process_join(mlan_private *priv, t_u8 **ppbuffer, - IEEEtypes_CapInfo_t *pcap_info, t_u8 band, + IEEEtypes_CapInfo_t *pcap_info, t_u16 band, t_u32 channel, wlan_11h_bss_info_t *p11h_bss_info) { t_s32 ret = 0; @@ -2623,6 +2668,8 @@ mlan_status wlan_11h_cmdresp_process(mlan_private *priv, break; case HostCmd_CMD_CHAN_REPORT_REQUEST: + if (priv->bss_type == MLAN_BSS_TYPE_DFS) + break; priv->adapter->state_dfs.dfs_check_priv = priv; priv->adapter->state_dfs.dfs_check_pending = MTRUE; @@ -3018,6 +3065,52 @@ mlan_status wlan_11h_ioctl_chan_switch_count(pmlan_adapter pmadapter, return ret; } +/** + * @brief Get/Set 802.11h channel dfs state + * + * @param pmadapter Pointer to mlan_adapter + * @param pioctl_req Pointer to mlan_ioctl_req + * + * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE + */ +mlan_status wlan_11h_ioctl_chan_dfs_state(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req) +{ + mlan_ds_11h_cfg *ds_11hcfg = MNULL; + t_s32 ret = MLAN_STATUS_FAILURE; + pmlan_private priv = pmadapter->priv[pioctl_req->bss_index]; + + ENTER(); + + if (pioctl_req) { + ds_11hcfg = (mlan_ds_11h_cfg *)pioctl_req->pbuf; + + if (pioctl_req->action == MLAN_ACT_GET) { + wlan_11h_is_channel_under_nop( + pmadapter, + ds_11hcfg->param.ch_dfs_state.channel); + ds_11hcfg->param.ch_dfs_state.dfs_required = + wlan_11h_radar_detect_required( + priv, + ds_11hcfg->param.ch_dfs_state.channel); + if (ds_11hcfg->param.ch_dfs_state.dfs_required) + ds_11hcfg->param.ch_dfs_state + .dfs_state = wlan_get_chan_dfs_state( + priv, BAND_A, + ds_11hcfg->param.ch_dfs_state.channel); + } else { + wlan_set_chan_dfs_state( + priv, BAND_A, + ds_11hcfg->param.ch_dfs_state.channel, + ds_11hcfg->param.ch_dfs_state.dfs_state); + } + ret = MLAN_STATUS_SUCCESS; + } + + LEAVE(); + return ret; +} + /** * @brief 802.11h DFS chan report * @@ -3064,6 +3157,7 @@ t_bool wlan_11h_is_channel_under_nop(mlan_adapter *pmadapter, t_u8 channel) wlan_dfs_timestamp_t *pdfs_ts = MNULL; t_u32 now_sec, now_usec; t_bool ret = MFALSE; + mlan_private *priv; ENTER(); pdfs_ts = wlan_11h_find_dfs_timestamp(pmadapter, channel); @@ -3089,6 +3183,10 @@ t_bool wlan_11h_is_channel_under_nop(mlan_adapter *pmadapter, t_u8 channel) /* if entry is expired, remove it */ if (!ret) { wlan_11h_remove_dfs_timestamp(pmadapter, pdfs_ts); + priv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY); + if (priv) + wlan_set_chan_dfs_state(priv, BAND_A, channel, + DFS_USABLE); } else PRINTM(MMSG, "11h: channel %d is under NOP - can't use.\n", @@ -3123,12 +3221,16 @@ mlan_status wlan_11h_handle_event_chanrpt_ready(mlan_private *priv, wlan_dfs_device_state_t *pstate_dfs = &priv->adapter->state_dfs; t_u8 dfs_radar_found = MFALSE; t_u8 dfs_check_channel = pstate_dfs->dfs_check_channel; + MrvlIEtypes_channel_band_t *tlv; ENTER(); pchan_rpt_rsp = (HostCmd_DS_CHAN_RPT_RSP *)&pevent->event_buf; DBG_HEXDUMP(MCMD_D, "11h: Event ChanRptReady (HostCmd_DS_CHAN_RPT_RSP)", (t_u8 *)pchan_rpt_rsp, pevent->event_len); + if (priv->bss_type == MLAN_BSS_TYPE_DFS) + dfs_check_channel = priv->chan_rep_req.chanNum; + if (wlan_le32_to_cpu(pchan_rpt_rsp->cmd_result) == MLAN_CMD_RESULT_SUCCESS) { pbuffer = (t_u8 *)&pchan_rpt_rsp->tlv_buffer; @@ -3147,6 +3249,10 @@ mlan_status wlan_11h_handle_event_chanrpt_ready(mlan_private *priv, if (pmeas_rpt_basic->radar) dfs_radar_found = MTRUE; break; + case TLV_TYPE_CHANNELBANDLIST: + tlv = (MrvlIEtypes_channel_band_t *)ptlv; + dfs_check_channel = tlv->channel; + break; default: break; } @@ -3166,6 +3272,12 @@ mlan_status wlan_11h_handle_event_chanrpt_ready(mlan_private *priv, dfs_check_channel); } *radar_chan = dfs_check_channel; + if (dfs_radar_found) + wlan_set_chan_dfs_state(priv, BAND_A, dfs_check_channel, + DFS_UNAVAILABLE); + else + wlan_set_chan_dfs_state(priv, BAND_A, dfs_check_channel, + DFS_AVAILABLE); pstate_dfs->dfs_radar_found = dfs_radar_found; /* Update DFS structure. */ priv->adapter->callbacks.moal_get_system_time( @@ -3192,8 +3304,20 @@ mlan_status wlan_11h_print_event_radar_detected(mlan_private *priv, t_u8 *radar_chan) { wlan_dfs_device_state_t *pstate_dfs = &priv->adapter->state_dfs; + MrvlIEtypes_channel_band_t *tlv; ENTER(); *radar_chan = pstate_dfs->dfs_check_channel; + if (pevent->event_len >= sizeof(MrvlIEtypes_channel_band_t)) { + tlv = (MrvlIEtypes_channel_band_t *)&pevent->event_buf; + *radar_chan = tlv->channel; + } else { + if (priv->bss_type == MLAN_BSS_TYPE_DFS) + *radar_chan = priv->chan_rep_req.chanNum; + } + wlan_11h_add_dfs_timestamp(priv->adapter, DFS_TS_REPR_NOP_START, + *radar_chan); + wlan_set_chan_dfs_state(priv, BAND_A, *radar_chan, DFS_UNAVAILABLE); + PRINTM(MEVENT, "ZeroDFS: Radar detected on %d\n", *radar_chan); LEAVE(); return MLAN_STATUS_SUCCESS; } diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11h.h b/mxm_wifiex/wlan_src/mlan/mlan_11h.h index e139045..bcd5a32 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11h.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_11h.h @@ -4,7 +4,7 @@ * function declarations of 802.11h * * - * Copyright 2008-2020 NXP + * Copyright 2008-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -111,7 +111,7 @@ extern t_s32 wlan_11h_process_start(mlan_private *priv, t_u8 **ppbuffer, /** Add any 11h TLVs necessary to complete a join command (adhoc or infra) */ extern t_s32 wlan_11h_process_join(mlan_private *priv, t_u8 **ppbuffer, - IEEEtypes_CapInfo_t *pcap_info, t_u8 band, + IEEEtypes_CapInfo_t *pcap_info, t_u16 band, t_u32 channel, wlan_11h_bss_info_t *p11h_bss_info); @@ -154,6 +154,10 @@ extern mlan_status wlan_11h_ioctl_dfs_chan_report(mlan_private *priv, extern mlan_status wlan_11h_ioctl_chan_switch_count(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); +/** get/set channel dfs state */ +mlan_status wlan_11h_ioctl_chan_dfs_state(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req); + /** get/set dfs w53 cfg */ mlan_status wlan_11h_ioctl_dfs_w53_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11n.c b/mxm_wifiex/wlan_src/mlan/mlan_11n.c index 583d4b9..0876214 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11n.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_11n.c @@ -1330,7 +1330,7 @@ static TxBAStreamTbl *wlan_11n_get_txbastream_status(mlan_private *priv, * * @return N/A */ -static void wlan_fill_cap_info(mlan_private *priv, HTCap_t *ht_cap, t_u8 bands) +static void wlan_fill_cap_info(mlan_private *priv, HTCap_t *ht_cap, t_u16 bands) { t_u32 usr_dot_11n_dev_cap; @@ -1419,7 +1419,8 @@ static void wlan_fill_cap_info(mlan_private *priv, HTCap_t *ht_cap, t_u8 bands) * * @return N/A */ -static void wlan_reset_cap_info(mlan_private *priv, HTCap_t *ht_cap, t_u8 bands) +static void wlan_reset_cap_info(mlan_private *priv, HTCap_t *ht_cap, + t_u16 bands) { t_u32 usr_dot_11n_dev_cap; @@ -1513,8 +1514,10 @@ void wlan_fill_ht_cap_tlv(mlan_private *priv, MrvlIETypes_HTCap_t *pht_cap, rx_mcs_supp = GET_RXMCSSUPP(priv->usr_dev_mcs_support); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if (IS_CARD9098(pmadapter->card_type) || + IS_CARDNW62X(pmadapter->card_type) || IS_CARD9097(pmadapter->card_type)) { if (bands & BAND_A) rx_mcs_supp = MIN( @@ -1587,8 +1590,10 @@ void wlan_fill_ht_cap_ie(mlan_private *priv, IEEEtypes_HTCap_t *pht_cap, rx_mcs_supp = GET_RXMCSSUPP(priv->usr_dev_mcs_support); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if (IS_CARD9098(pmadapter->card_type) || + IS_CARDNW62X(pmadapter->card_type) || IS_CARD9097(pmadapter->card_type)) { if (bands & BAND_A) rx_mcs_supp = MIN( @@ -2294,7 +2299,7 @@ t_u8 wlan_get_second_channel_offset(mlan_private *priv, int chan) t_u8 chan2Offset = SEC_CHAN_NONE; /* Special Case: 20Mhz-only Channel */ - if (chan == 165) + if (priv->adapter->region_code != COUNTRY_CODE_US && chan == 165) return chan2Offset; switch (chan) { @@ -2310,6 +2315,8 @@ t_u8 wlan_get_second_channel_offset(mlan_private *priv, int chan) case 140: case 149: case 157: + case 165: + case 173: chan2Offset = SEC_CHAN_ABOVE; break; case 40: @@ -2324,6 +2331,8 @@ t_u8 wlan_get_second_channel_offset(mlan_private *priv, int chan) case 144: case 153: case 161: + case 169: + case 177: chan2Offset = SEC_CHAN_BELOW; break; } @@ -2555,7 +2564,7 @@ int wlan_cmd_append_11n_tlv(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc, pchan_list->chan_scan_param[0].chan_number = pbss_desc->pht_info->ht_info.pri_chan; pchan_list->chan_scan_param[0].bandcfg.chanBand = - wlan_band_to_radio_type((t_u8)pbss_desc->bss_band); + wlan_band_to_radio_type(pbss_desc->bss_band); /* support the VHT if the network to be join has the VHT * operation */ if (ISSUPP_11ACENABLED(pmadapter->fw_cap_info) && @@ -3127,7 +3136,7 @@ int wlan_get_txbastream_tbl(mlan_private *priv, tx_ba_stream_tbl *buf) * * @return 0--not allowed, other value allowed */ -t_u8 wlan_11n_bandconfig_allowed(mlan_private *pmpriv, t_u8 bss_band) +t_u8 wlan_11n_bandconfig_allowed(mlan_private *pmpriv, t_u16 bss_band) { if (pmpriv->bss_mode == MLAN_BSS_MODE_IBSS) { if (bss_band & BAND_G) diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11n.h b/mxm_wifiex/wlan_src/mlan/mlan_11n.h index 2b4678c..0a2a990 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11n.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_11n.h @@ -6,7 +6,7 @@ * implemented in mlan_11n.c. * * - * Copyright 2008-2020 NXP + * Copyright 2008-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -65,7 +65,7 @@ mlan_status wlan_cmd_tx_bf_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, mlan_status wlan_ret_tx_bf_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf); #ifdef STA_SUPPORT -t_u8 wlan_11n_bandconfig_allowed(mlan_private *pmpriv, t_u8 bss_band); +t_u8 wlan_11n_bandconfig_allowed(mlan_private *pmpriv, t_u16 bss_band); /** Append the 802_11N tlv */ int wlan_cmd_append_11n_tlv(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc, t_u8 **ppbuffer); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11n_aggr.h b/mxm_wifiex/wlan_src/mlan/mlan_11n_aggr.h index b7aca6b..922d4a8 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11n_aggr.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_11n_aggr.h @@ -4,7 +4,7 @@ * of 11n aggregation functionalities * * - * Copyright 2008-2020 NXP + * Copyright 2008-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11n_rxreorder.h b/mxm_wifiex/wlan_src/mlan/mlan_11n_rxreorder.h index 2aae43e..d409e85 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11n_rxreorder.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_11n_rxreorder.h @@ -4,7 +4,7 @@ * of 11n RxReordering functionalities * * - * Copyright 2008-2020 NXP + * Copyright 2008-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mxm_wifiex/wlan_src/mlan/mlan_cfp.c b/mxm_wifiex/wlan_src/mlan/mlan_cfp.c index 7e8455e..c4b611c 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_cfp.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_cfp.c @@ -5,7 +5,7 @@ * related code * * - * Copyright 2009-2021 NXP + * Copyright 2009-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -97,11 +97,11 @@ static t_u8 eu_country_code_table[][COUNTRY_CODE_LEN] = { "LU", "MT", "MD", "MC", "ME", "NL", "NO", "PL", "RO", "SM", "RS", "SI", "SK", "ES", "SE", "CH", "TR", "UA", "UK", "GB", "NZ", "DZ", "AO", "AM", "AW", "BH", "BD", "BT", "BO", "BQ", "BW", "VG", "BF", "BI", "KH", "CL", - "CN", "KM", "CG", "CD", "CW", "EG", "FO", "GF", "PF", "GE", "GI", "GP", - "HK", "IN", "ID", "IM", "IL", "JE", "KE", "XK", "KW", "LA", "LR", "MW", - "MV", "MQ", "MR", "YT", "MA", "MZ", "MM", "NA", "NC", "NE", "NG", "OM", - "PS", "PT", "QA", "RW", "RE", "BL", "MF", "VC", "SA", "SC", "ZA", "SZ", - "SY", "TZ", "TG", "TN", "AE", "VA", "EH", "YE", "ZM", "ZW"}; + "KM", "CG", "CD", "CW", "EG", "FO", "GF", "PF", "GE", "GI", "GP", "HK", + "IN", "ID", "IM", "IL", "JE", "KE", "XK", "KW", "LA", "LR", "MW", "MV", + "MQ", "MR", "YT", "MA", "MZ", "MM", "NA", "NC", "NE", "NG", "OM", "PS", + "PT", "QA", "RW", "RE", "BL", "MF", "VC", "SA", "SC", "ZA", "SZ", "SY", + "TZ", "TG", "TN", "AE", "VA", "EH", "YE", "ZM", "ZW"}; /** * The structure for Channel-Frequency-Power table @@ -346,7 +346,10 @@ static chan_freq_power_t channel_freq_power_A[] = { {153, 5765, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}, {157, 5785, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}, {161, 5805, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}, - {165, 5825, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}}; + {165, 5825, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}, + {169, 5845, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}, + {173, 5865, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}, + {177, 5885, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}}; /** Band: 'A', Region: Canada IC */ static chan_freq_power_t channel_freq_power_CAN_A[] = { @@ -970,8 +973,6 @@ static const rate_map rate_map_table_1x1[] = { t_u16 region_code_index[MRVDRV_MAX_REGION_CODE] = {0x00, 0x10, 0x20, 0x30, 0x40, 0x41, 0x50, 0xfe, 0xff}; -/** The table to keep CFP code for BG */ -t_u16 cfp_code_index_bg[MRVDRV_MAX_CFP_CODE_BG] = {}; /** The table to keep CFP code for A */ t_u16 cfp_code_index_a[MRVDRV_MAX_CFP_CODE_A] = {0x1, 0x2, 0x3, 0x4, 0x5}; @@ -1185,7 +1186,7 @@ static void *wlan_memchr(pmlan_adapter pmadapter, void *s, int c, int n) * @return A pointer to CFP */ static chan_freq_power_t *wlan_get_region_cfp_table(pmlan_adapter pmadapter, - t_u8 region, t_u8 band, + t_u8 region, t_u16 band, int *cfp_no) { t_u32 i; @@ -1250,7 +1251,6 @@ static chan_freq_power_t *wlan_get_region_cfp_table(pmlan_adapter pmadapter, } } } - if (!region) PRINTM(MERROR, "Error Band[0x%x] or code[BG:%#x, A:%#x]\n", band, cfp_bg, cfp_a); @@ -1290,6 +1290,7 @@ static t_void wlan_cfp_copy_dynamic(pmlan_adapter pmadapter, /* do not clear the flags */ for (i = 0; i < num_cfp; i++) { cfp[i].dynamic.blacklist = MFALSE; + cfp[i].dynamic.dfs_state = DFS_USABLE; } /* copy dynamic blacklisted entries from source where channels match */ @@ -1299,6 +1300,8 @@ static t_void wlan_cfp_copy_dynamic(pmlan_adapter pmadapter, if (cfp[i].channel == cfp_src[j].channel) { cfp[i].dynamic.blacklist = cfp_src[j].dynamic.blacklist; + cfp[i].dynamic.dfs_state = + cfp_src[j].dynamic.dfs_state; break; } } @@ -1878,11 +1881,13 @@ t_u32 wlan_get_active_data_rates(mlan_private *pmpriv, t_u32 bss_mode, * present in all the regions. * * @param pmpriv A pointer to mlan_private structure + * @param band band. * @param channel Channel number. * * @return The Tx power */ -t_u8 wlan_get_txpwr_of_chan_from_cfp(mlan_private *pmpriv, t_u8 channel) +t_u8 wlan_get_txpwr_of_chan_from_cfp(mlan_private *pmpriv, t_u16 band, + t_u8 channel) { t_u8 i = 0; t_u8 j = 0; @@ -1894,38 +1899,46 @@ t_u8 wlan_get_txpwr_of_chan_from_cfp(mlan_private *pmpriv, t_u8 channel) ENTER(); - for (i = 0; i < MLAN_CFP_TABLE_SIZE_BG; i++) { - /* Get CFP */ - cfp = cfp_table_BG[i].cfp; - cfp_no = cfp_table_BG[i].cfp_no; - /* Find matching channel and get Tx power */ - for (j = 0; j < cfp_no; j++) { - if ((cfp + j)->channel == channel) { - if (tx_power != 0) - tx_power = MIN(tx_power, - (cfp + j)->max_tx_power); - else - tx_power = - (t_u8)(cfp + j)->max_tx_power; - break; + if (band & (BAND_B | BAND_G)) { + for (i = 0; i < MLAN_CFP_TABLE_SIZE_BG; i++) { + /* Get CFP */ + cfp = cfp_table_BG[i].cfp; + cfp_no = cfp_table_BG[i].cfp_no; + /* Find matching channel and get Tx power */ + for (j = 0; j < cfp_no; j++) { + if ((cfp + j)->channel == channel) { + if (tx_power != 0) + tx_power = MIN( + tx_power, + (cfp + j)->max_tx_power); + else + tx_power = + (t_u8)(cfp + j) + ->max_tx_power; + break; + } } } } - for (i = 0; i < MLAN_CFP_TABLE_SIZE_A; i++) { - /* Get CFP */ - cfp_a = cfp_table_A[i].cfp; - cfp_no_a = cfp_table_A[i].cfp_no; - for (j = 0; j < cfp_no_a; j++) { - if ((cfp_a + j)->channel == channel) { - if (tx_power != 0) - tx_power = - MIN(tx_power, - (cfp_a + j)->max_tx_power); - else - tx_power = (t_u8)( - (cfp_a + j)->max_tx_power); - break; + if (band & BAND_A) { + for (i = 0; i < MLAN_CFP_TABLE_SIZE_A; i++) { + /* Get CFP */ + cfp_a = cfp_table_A[i].cfp; + cfp_no_a = cfp_table_A[i].cfp_no; + for (j = 0; j < cfp_no_a; j++) { + if ((cfp_a + j)->channel == channel) { + if (tx_power != 0) + tx_power = MIN( + tx_power, + (cfp_a + j) + ->max_tx_power); + else + tx_power = (t_u8)( + (cfp_a + j) + ->max_tx_power); + break; + } } } } @@ -1947,7 +1960,7 @@ t_u8 wlan_get_txpwr_of_chan_from_cfp(mlan_private *pmpriv, t_u8 channel) */ chan_freq_power_t * -wlan_get_cfp_by_band_and_channel(pmlan_adapter pmadapter, t_u8 band, +wlan_get_cfp_by_band_and_channel(pmlan_adapter pmadapter, t_u16 band, t_u16 channel, region_chan_t *region_channel) { region_chan_t *rc; @@ -2030,7 +2043,7 @@ wlan_get_cfp_by_band_and_channel(pmlan_adapter pmadapter, t_u8 band, * found. */ chan_freq_power_t *wlan_find_cfp_by_band_and_channel(mlan_adapter *pmadapter, - t_u8 band, t_u16 channel) + t_u16 band, t_u16 channel) { chan_freq_power_t *cfp = MNULL; @@ -2059,7 +2072,7 @@ chan_freq_power_t *wlan_find_cfp_by_band_and_channel(mlan_adapter *pmadapter, * @return Pointer to chan_freq_power_t structure; MNULL if not found */ chan_freq_power_t *wlan_find_cfp_by_band_and_freq(mlan_adapter *pmadapter, - t_u8 band, t_u32 freq) + t_u16 band, t_u32 freq) { chan_freq_power_t *cfp = MNULL; region_chan_t *rc; @@ -2182,6 +2195,27 @@ int wlan_get_rate_index(pmlan_adapter pmadapter, t_u16 *rate_bitmap, int size) return -1; } +/** + * @brief Convert config_bands to B/G/A band + * + * @param config_bands The specified band configuration + * + * @return BAND_B|BAND_G|BAND_A + */ +t_u16 wlan_convert_config_bands(t_u16 config_bands) +{ + t_u16 bands = 0; + if (config_bands & BAND_B) + bands |= BAND_B; + if (config_bands & BAND_G || config_bands & BAND_GN || + config_bands & BAND_GAC || config_bands & BAND_GAX) + bands |= BAND_G; + if (config_bands & BAND_A || config_bands & BAND_AN || + config_bands & BAND_AAC || config_bands & BAND_AAX) + bands |= BAND_A; + return bands; +} + /** * @brief Get supported data rates * @@ -2196,110 +2230,64 @@ t_u32 wlan_get_supported_rates(mlan_private *pmpriv, t_u32 bss_mode, t_u16 config_bands, WLAN_802_11_RATES rates) { t_u32 k = 0; + t_u16 bands = 0; ENTER(); + bands = wlan_convert_config_bands(config_bands); if (bss_mode == MLAN_BSS_MODE_INFRA) { /* Infra. mode */ - switch (config_bands) { - case (t_u8)BAND_B: - PRINTM(MINFO, "Infra Band=%d SupportedRates_B\n", - config_bands); + if (bands == BAND_B) { + /* B only */ + PRINTM(MINFO, "Band: Infra B\n"); k = wlan_copy_rates(rates, k, SupportedRates_B, sizeof(SupportedRates_B)); - break; - case (t_u8)BAND_G: - case BAND_G | BAND_GN: - case BAND_G | BAND_GN | BAND_GAC: - case BAND_G | BAND_GN | BAND_GAC | BAND_GAX: - PRINTM(MINFO, "Infra band=%d SupportedRates_G\n", - config_bands); + } else if (bands == BAND_G) { + /* G only */ + PRINTM(MINFO, "Band: Infra G\n"); k = wlan_copy_rates(rates, k, SupportedRates_G, sizeof(SupportedRates_G)); - break; - case BAND_B | BAND_G: - case BAND_A | BAND_B | BAND_G: - case BAND_A | BAND_B: - case BAND_A | BAND_B | BAND_G | BAND_GN: - case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN: - case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN | BAND_AAC: - case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN | BAND_AAC | - BAND_GAC: - case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN | BAND_AAC | - BAND_AAX: - case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN | BAND_AAC | - BAND_GAC | BAND_AAX | BAND_GAX: - case BAND_B | BAND_G | BAND_GN: - case BAND_B | BAND_G | BAND_GN | BAND_GAC: - case BAND_B | BAND_G | BAND_GN | BAND_GAC | BAND_GAX: - PRINTM(MINFO, "Infra band=%d SupportedRates_BG\n", - config_bands); + + } else if (bands & (BAND_B | BAND_G)) { + /* BG only */ + PRINTM(MINFO, "Band: Infra BG\n"); #ifdef WIFI_DIRECT_SUPPORT if (pmpriv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT) k = wlan_copy_rates(rates, k, SupportedRates_G, sizeof(SupportedRates_G)); else +#endif k = wlan_copy_rates(rates, k, SupportedRates_BG, sizeof(SupportedRates_BG)); -#else - k = wlan_copy_rates(rates, k, SupportedRates_BG, - sizeof(SupportedRates_BG)); -#endif - break; - case BAND_A: - case BAND_A | BAND_G: - PRINTM(MINFO, "Infra band=%d SupportedRates_A\n", - config_bands); + } else if (bands & BAND_A) { + /* support A */ + PRINTM(MINFO, "Band: Infra A\n"); k = wlan_copy_rates(rates, k, SupportedRates_A, sizeof(SupportedRates_A)); - break; - case BAND_AN: - case BAND_A | BAND_AN: - case BAND_A | BAND_G | BAND_AN | BAND_GN: - case BAND_A | BAND_AN | BAND_AAC: - case BAND_A | BAND_G | BAND_AN | BAND_GN | BAND_AAC: - case BAND_A | BAND_AN | BAND_AAC | BAND_AAX: - case BAND_A | BAND_G | BAND_AN | BAND_GN | BAND_AAC | BAND_AAX: - PRINTM(MINFO, "Infra band=%d SupportedRates_A\n", - config_bands); - k = wlan_copy_rates(rates, k, SupportedRates_A, - sizeof(SupportedRates_A)); - break; - case BAND_GN: - case BAND_GN | BAND_GAC: - case BAND_GN | BAND_GAC | BAND_GAX: - PRINTM(MINFO, "Infra band=%d SupportedRates_N\n", - config_bands); - k = wlan_copy_rates(rates, k, SupportedRates_N, - sizeof(SupportedRates_N)); - break; } } else { - /* Ad-hoc mode */ - switch (config_bands) { - case (t_u8)BAND_B: + /* Adhoc. mode */ + if (bands == BAND_B) { + /* B only */ PRINTM(MINFO, "Band: Adhoc B\n"); k = wlan_copy_rates(rates, k, AdhocRates_B, sizeof(AdhocRates_B)); - break; - case (t_u8)BAND_G: - PRINTM(MINFO, "Band: Adhoc G only\n"); + } else if (bands == BAND_G) { + /* G only */ + PRINTM(MINFO, "Band: Adhoc G\n"); k = wlan_copy_rates(rates, k, AdhocRates_G, sizeof(AdhocRates_G)); - break; - case BAND_B | BAND_G: - PRINTM(MINFO, "Band: Adhoc BG\n"); - k = wlan_copy_rates(rates, k, AdhocRates_BG, - sizeof(AdhocRates_BG)); - break; - case BAND_A: - case BAND_A | BAND_AN | BAND_AAC: - case BAND_A | BAND_AN | BAND_AAC | BAND_AAX: + } else if (bands & BAND_A) { + /* support A */ PRINTM(MINFO, "Band: Adhoc A\n"); k = wlan_copy_rates(rates, k, AdhocRates_A, sizeof(AdhocRates_A)); - break; + + } else { + PRINTM(MINFO, "Band: Adhoc BG\n"); + k = wlan_copy_rates(rates, k, AdhocRates_BG, + sizeof(AdhocRates_BG)); } } @@ -2677,7 +2665,7 @@ int wlan_add_supported_oper_class_ie(mlan_private *pmpriv, t_u8 **pptlv_out, * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ -mlan_status wlan_set_regiontable(mlan_private *pmpriv, t_u8 region, t_u8 band) +mlan_status wlan_set_regiontable(mlan_private *pmpriv, t_u8 region, t_u16 band) { mlan_adapter *pmadapter = pmpriv->adapter; int i = 0, j; @@ -2734,7 +2722,7 @@ mlan_status wlan_set_regiontable(mlan_private *pmpriv, t_u8 region, t_u8 band) i++; } if (band & (BAND_A | BAND_AN | BAND_AAC)) { - if (pmadapter->cfp_code_bg) + if (pmadapter->cfp_code_a) cfp_code_a = pmadapter->cfp_code_a; PRINTM(MCMND, "%s: 5G 0x%x\n", __func__, cfp_code_a); cfp = wlan_get_region_cfp_table(pmadapter, cfp_code_a, BAND_A, @@ -2763,6 +2751,7 @@ mlan_status wlan_set_regiontable(mlan_private *pmpriv, t_u8 region, t_u8 band) } else if (cfp) { wlan_cfp_copy_dynamic(pmadapter, cfp, cfp_no, MNULL, 0); } + i++; } LEAVE(); return MLAN_STATUS_SUCCESS; @@ -2824,7 +2813,6 @@ done: * - MTRUE if scan type is passive * - MFALSE otherwise */ - t_bool wlan_bg_scan_type_is_passive(mlan_private *priv, t_u8 chnl) { int i, j; @@ -2873,7 +2861,7 @@ done: * - MFALSE otherwise */ -t_bool wlan_is_chan_passive(mlan_private *priv, t_u8 band, t_u8 chan) +t_bool wlan_is_chan_passive(mlan_private *priv, t_u16 band, t_u8 chan) { int i, j; t_bool passive = MFALSE; @@ -2916,7 +2904,7 @@ t_bool wlan_is_chan_passive(mlan_private *priv, t_u8 band, t_u8 chan) * - MFALSE otherwise */ -t_bool wlan_is_chan_disabled(mlan_private *priv, t_u8 band, t_u8 chan) +t_bool wlan_is_chan_disabled(mlan_private *priv, t_u16 band, t_u8 chan) { int i, j; t_bool disabled = MFALSE; @@ -2960,7 +2948,7 @@ t_bool wlan_is_chan_disabled(mlan_private *priv, t_u8 band, t_u8 chan) * - MFALSE otherwise */ -t_bool wlan_is_chan_blacklisted(mlan_private *priv, t_u8 band, t_u8 chan) +t_bool wlan_is_chan_blacklisted(mlan_private *priv, t_u16 band, t_u8 chan) { int i, j; t_bool blacklist = MFALSE; @@ -3003,7 +2991,7 @@ t_bool wlan_is_chan_blacklisted(mlan_private *priv, t_u8 band, t_u8 chan) * - MFALSE otherwise */ -t_bool wlan_set_chan_blacklist(mlan_private *priv, t_u8 band, t_u8 chan, +t_bool wlan_set_chan_blacklist(mlan_private *priv, t_u16 band, t_u8 chan, t_bool bl) { int i, j; @@ -3035,6 +3023,84 @@ t_bool wlan_set_chan_blacklist(mlan_private *priv, t_u8 band, t_u8 chan, return set_bl; } +/** + * @brief Set channel's dfs state + * + * @param priv Private driver information structure + * @param band Band to check + * @param chan Channel to check + * @param dfs_state dfs state + * + * @return N/A + */ +t_void wlan_set_chan_dfs_state(mlan_private *priv, t_u16 band, t_u8 chan, + dfs_state_t dfs_state) +{ + int i, j; + chan_freq_power_t *pcfp = MNULL; + + ENTER(); + + /*get the cfp table first*/ + for (i = 0; i < MAX_REGION_CHANNEL_NUM; i++) { + if (priv->adapter->region_channel[i].band & band) { + pcfp = priv->adapter->region_channel[i].pcfp; + break; + } + } + + if (pcfp) { + /*check table according to chan num*/ + for (j = 0; j < priv->adapter->region_channel[i].num_cfp; j++) { + if (pcfp[j].channel == chan) { + pcfp[j].dynamic.dfs_state = dfs_state; + break; + } + } + } + + LEAVE(); +} + +/** + * @brief get channel's dfs state + * + * @param priv Private driver information structure + * @param band Band to check + * @param chan Channel to check + * + * @return channel's dfs state + */ +dfs_state_t wlan_get_chan_dfs_state(mlan_private *priv, t_u16 band, t_u8 chan) +{ + int i, j; + chan_freq_power_t *pcfp = MNULL; + dfs_state_t dfs_state = DFS_USABLE; + + ENTER(); + + /*get the cfp table first*/ + for (i = 0; i < MAX_REGION_CHANNEL_NUM; i++) { + if (priv->adapter->region_channel[i].band & band) { + pcfp = priv->adapter->region_channel[i].pcfp; + break; + } + } + + if (pcfp) { + /*check table according to chan num*/ + for (j = 0; j < priv->adapter->region_channel[i].num_cfp; j++) { + if (pcfp[j].channel == chan) { + dfs_state = pcfp[j].dynamic.dfs_state; + break; + } + } + } + + LEAVE(); + return dfs_state; +} + /** * @brief Convert rateid in IEEE format to MRVL format * @@ -3279,10 +3345,12 @@ void wlan_add_fw_cfp_tables(pmlan_private pmpriv, t_u8 *buf, t_u16 buf_left) pmadapter->domain_reg.country_code[1] = pmadapter->otp_region->country_code[1]; pmadapter->domain_reg.country_code[2] = '\0'; - PRINTM(MCMND, "OTP region: region_code=%d %c%c\n", + PRINTM(MCMND, + "OTP region: region_code=%d %c%c dfs_region=%d\n", pmadapter->otp_region->region_code, pmadapter->country_code[0], - pmadapter->country_code[1]); + pmadapter->country_code[1], + pmadapter->otp_region->dfs_region); pmadapter->cfp_code_bg = pmadapter->otp_region->region_code; pmadapter->cfp_code_a = @@ -3367,6 +3435,8 @@ void wlan_add_fw_cfp_tables(pmlan_private pmpriv, t_u8 *buf, t_u16 buf_left) data++; (pmadapter->cfp_otp_a + i)->dynamic.flags = *data; + (pmadapter->cfp_otp_a + i)->dynamic.dfs_state = + DFS_USABLE; if (*data & NXP_CHANNEL_DFS) (pmadapter->cfp_otp_a + i) ->passive_scan_or_radar_detect = @@ -3399,7 +3469,7 @@ void wlan_add_fw_cfp_tables(pmlan_private pmpriv, t_u8 *buf, t_u16 buf_left) while ((i < pmadapter->tx_power_table_bg_rows * pmadapter->tx_power_table_bg_cols) && - (i < tlv_buf_len) && (*tmp != 36)) { + (i < tlv_buf_len)) { i++; tmp++; } @@ -3451,9 +3521,12 @@ void wlan_add_fw_cfp_tables(pmlan_private pmpriv, t_u8 *buf, t_u16 buf_left) ((power_table_attr_t *)data)->rows_5g; pmadapter->tx_power_table_a_cols = ((power_table_attr_t *)data)->cols_5g; - PRINTM(MCMD_D, "OTP region: bg_row=%d, a_row=%d\n", + PRINTM(MCMD_D, + "OTP region: bg_row=%d,bg_cols=%d a_row=%d, a_cols=%d\n", pmadapter->tx_power_table_bg_rows, - pmadapter->tx_power_table_a_rows); + pmadapter->tx_power_table_bg_cols, + pmadapter->tx_power_table_a_rows, + pmadapter->tx_power_table_a_cols); break; default: break; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c b/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c index 9179ce9..6329d95 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c @@ -4,7 +4,7 @@ * @brief This file contains the handling of CMD/EVENT in MLAN * * - * Copyright 2009-2021 NXP + * Copyright 2009-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -131,7 +131,7 @@ static t_u8 wlan_is_cmd_allowed_during_scan(t_u16 cmd_id) } /** - * @brief This function move the cmd from scan_pending_q to + * @brief This function move the cmd from ext_cmd_pending_q to * cmd_pending_q * * @param cmd_id cmd id @@ -146,10 +146,10 @@ t_void wlan_move_cmd_to_cmd_pending_q(pmlan_adapter pmadapter) wlan_request_cmd_lock(pmadapter); while ((pcmd_node = (cmd_ctrl_node *)util_peek_list( - pmadapter->pmoal_handle, &pmadapter->scan_pending_q, + pmadapter->pmoal_handle, &pmadapter->ext_cmd_pending_q, MNULL, MNULL))) { util_unlink_list(pmadapter->pmoal_handle, - &pmadapter->scan_pending_q, + &pmadapter->ext_cmd_pending_q, (pmlan_linked_list)pcmd_node, MNULL, MNULL); wlan_insert_cmd_to_pending_q(pmadapter, pcmd_node, MTRUE); } @@ -157,6 +157,71 @@ t_void wlan_move_cmd_to_cmd_pending_q(pmlan_adapter pmadapter) LEAVE(); } +/** + * @brief This function inserts scan command node to scan_cmd_pending_q. + * + * @param pmpriv A pointer to mlan_private structure + * @param pcmd_node A pointer to cmd_ctrl_node structure + * @return N/A + */ +static t_void wlan_queue_cmd_to_ext_cmd_pending_queue(mlan_private *pmpriv, + cmd_ctrl_node *pcmd_node) +{ + mlan_adapter *pmadapter = pmpriv->adapter; + + ENTER(); + + if (pcmd_node == MNULL) + goto done; + + util_enqueue_list_tail(pmadapter->pmoal_handle, + &pmadapter->ext_cmd_pending_q, + (pmlan_linked_list)pcmd_node, MNULL, MNULL); + +done: + LEAVE(); +} + +/** + * @brief Internal function used to flush the scan cmd pending queue + * + * @param pmadapter A pointer to mlan_adapter structure + * + * @return N/A + */ +t_void wlan_flush_ext_cmd_pending_queue(pmlan_adapter pmadapter) +{ + cmd_ctrl_node *pcmd_node = MNULL; + HostCmd_DS_COMMAND *pcmd = MNULL; + mlan_ioctl_req *pioctl_buf = MNULL; + pmlan_callbacks pcb = &pmadapter->callbacks; + ENTER(); + + wlan_request_cmd_lock(pmadapter); + while ((pcmd_node = (cmd_ctrl_node *)util_peek_list( + pmadapter->pmoal_handle, &pmadapter->ext_cmd_pending_q, + MNULL, MNULL))) { + util_unlink_list(pmadapter->pmoal_handle, + &pmadapter->ext_cmd_pending_q, + (pmlan_linked_list)pcmd_node, MNULL, MNULL); + pcmd = (HostCmd_DS_COMMAND *)(pcmd_node->cmdbuf->pbuf + + pcmd_node->cmdbuf->data_offset); + PRINTM(MCMND, "flush ext_cmd_pending_queue: cmd 0x%02x\n", + wlan_le16_to_cpu(pcmd->command)); + if (pcmd_node->pioctl_buf) { + pioctl_buf = (mlan_ioctl_req *)pcmd_node->pioctl_buf; + pcmd_node->pioctl_buf = MNULL; + pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL; + pcb->moal_ioctl_complete(pmadapter->pmoal_handle, + pioctl_buf, + MLAN_STATUS_FAILURE); + } + wlan_insert_cmd_to_free_q(pmadapter, pcmd_node); + } + wlan_release_cmd_lock(pmadapter); + LEAVE(); +} + /** * @brief This function inserts command node to scan_pending_q or * cmd_pending_q @@ -173,9 +238,10 @@ static t_void wlan_queue_cmd(mlan_private *pmpriv, cmd_ctrl_node *pcmd_node, if (pmpriv->adapter->scan_processing && pmpriv->adapter->ext_scan_type == EXT_SCAN_ENHANCE) { if (MFALSE == wlan_is_cmd_allowed_during_scan(cmd_no)) { - PRINTM(MCMND, "QUEUE_CMD: cmd=0x%x scan_pending_q\n", + PRINTM(MCMND, "QUEUE_CMD: cmd=0x%x ext_cmd_pending_q\n", cmd_no); - wlan_queue_scan_cmd(pmpriv, pcmd_node); + wlan_queue_cmd_to_ext_cmd_pending_queue(pmpriv, + pcmd_node); return; } } @@ -1634,20 +1700,28 @@ mlan_status wlan_process_event(pmlan_adapter pmadapter) (t_u16)eventcause; if ((eventcause & EVENT_ID_MASK) == EVENT_RADAR_DETECTED) { - if (wlan_11h_dfs_event_preprocessing(pmadapter) == - MLAN_STATUS_SUCCESS) { - memcpy_ext(pmadapter, (t_u8 *)&eventcause, - pmbuf->pbuf + pmbuf->data_offset, - sizeof(eventcause), sizeof(eventcause)); - } else { - priv = wlan_get_priv_by_id( - pmadapter, EVENT_GET_BSS_NUM(eventcause), - EVENT_GET_BSS_TYPE(eventcause)); - if (priv) - PRINTM_NETINTF(MEVENT, priv); - PRINTM(MERROR, "Error processing DFS Event: 0x%x\n", - eventcause); - goto done; + priv = wlan_get_priv_by_id(pmadapter, + EVENT_GET_BSS_NUM(eventcause), + EVENT_GET_BSS_TYPE(eventcause)); + if (priv && priv->bss_type != MLAN_BSS_TYPE_DFS) { + if (wlan_11h_dfs_event_preprocessing(pmadapter) == + MLAN_STATUS_SUCCESS) { + memcpy_ext(pmadapter, (t_u8 *)&eventcause, + pmbuf->pbuf + pmbuf->data_offset, + sizeof(eventcause), + sizeof(eventcause)); + } else { + priv = wlan_get_priv_by_id( + pmadapter, + EVENT_GET_BSS_NUM(eventcause), + EVENT_GET_BSS_TYPE(eventcause)); + if (priv) + PRINTM_NETINTF(MEVENT, priv); + PRINTM(MERROR, + "Error processing DFS Event: 0x%x\n", + eventcause); + goto done; + } } } /* Get BSS number and corresponding priv */ @@ -1845,13 +1919,7 @@ mlan_status wlan_prepare_cmd(mlan_private *pmpriv, t_u16 cmd_no, #ifdef STA_SUPPORT if (cmd_no == HostCmd_CMD_802_11_SCAN || cmd_no == HostCmd_CMD_802_11_SCAN_EXT) { - if (cmd_no == HostCmd_CMD_802_11_SCAN_EXT && - pmadapter->ext_scan && pmadapter->ext_scan_enh && - pmadapter->ext_scan_type == EXT_SCAN_ENHANCE) { - wlan_insert_cmd_to_pending_q(pmadapter, pcmd_node, - MTRUE); - } else - wlan_queue_scan_cmd(pmpriv, pcmd_node); + wlan_queue_scan_cmd(pmpriv, pcmd_node); } else { #endif if ((cmd_no == HostCmd_CMD_802_11_HS_CFG_ENH) && @@ -2214,7 +2282,7 @@ mlan_status wlan_process_cmdresp(mlan_adapter *pmadapter) if (IS_PCIE(pmadapter->card_type) && cmdresp_no == HostCmd_CMD_FUNC_SHUTDOWN && pmadapter->pwarm_reset_ioctl_req) { -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) #endif wlan_pcie_init_fw(pmadapter); @@ -2244,7 +2312,8 @@ mlan_status wlan_process_cmdresp(mlan_adapter *pmadapter) i = pmpriv->bss_index + 1; while (i < pmadapter->priv_num && (!(pmpriv_next = pmadapter->priv[i]) || - pmpriv_next->bss_virtual)) + pmpriv_next->bss_virtual || + pmpriv_next->bss_type == MLAN_BSS_TYPE_DFS)) i++; if (!pmpriv_next || i >= pmadapter->priv_num) { #ifdef STA_SUPPORT @@ -2477,9 +2546,9 @@ mlan_status wlan_cancel_pending_scan_cmd(pmlan_adapter pmadapter, status = MLAN_STATUS_PENDING; } } - } else - /* Cancel all pending scan command */ - wlan_flush_scan_queue(pmadapter); + } + /* Cancel all pending scan command */ + wlan_flush_scan_queue(pmadapter); LEAVE(); return status; } @@ -2552,6 +2621,8 @@ t_void wlan_cancel_all_pending_cmd(pmlan_adapter pmadapter, t_u8 flag) wlan_release_cmd_lock(pmadapter); /* Cancel all pending scan command */ wlan_flush_scan_queue(pmadapter); + /* Cancel all pending command in scan_cmd_pending_q command */ + wlan_flush_ext_cmd_pending_queue(pmadapter); LEAVE(); } @@ -2641,9 +2712,9 @@ t_void wlan_cancel_bss_pending_cmd(pmlan_adapter pmadapter, t_u32 bss_index) priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING, MNULL); } - } else - /* Cancel all pending scan command */ - wlan_flush_scan_queue(pmadapter); + } + /* Cancel all pending scan command */ + wlan_flush_scan_queue(pmadapter); } #endif LEAVE(); @@ -2718,9 +2789,9 @@ t_void wlan_cancel_pending_ioctl(pmlan_adapter pmadapter, priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING, MNULL); } - } else - /* Cancel all pending scan command */ - wlan_flush_scan_queue(pmadapter); + } + /* Cancel all pending scan command */ + wlan_flush_scan_queue(pmadapter); } #endif if (find) { @@ -4672,6 +4743,62 @@ mlan_status wlan_process_vdll_event(pmlan_private pmpriv, pmlan_buffer pevent) return status; } +/** + * @brief This function handle the csi event + * + * @param pmpriv A pointer to mlan_private structure + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_process_csi_event(pmlan_private pmpriv) +{ + pmlan_adapter pmadapter = pmpriv->adapter; + mlan_status status; + t_u32 eventcause = pmadapter->event_cause; + t_u8 *evt_buf = MNULL; + pmlan_buffer pmbuf = pmadapter->pmlan_buffer_event; + pmlan_callbacks pcb = &pmadapter->callbacks; + pmlan_event pevent; + + ENTER(); + + /* Allocate memory for event buffer */ + status = pcb->moal_malloc(pmadapter->pmoal_handle, MAX_EVENT_SIZE, + MLAN_MEM_DEF, &evt_buf); + if ((status == MLAN_STATUS_SUCCESS) && evt_buf) { + t_u16 csi_sig; + pcsi_record_ds csi_record = (pcsi_record_ds)( + pmbuf->pbuf + pmbuf->data_offset + sizeof(eventcause)); + /* Check CSI signature */ + csi_sig = csi_record->CSI_Sign; + if (csi_sig != CSI_SIGNATURE) { + PRINTM(MERROR, + "Wrong CSI signature 0x%04x. Should be 0x%04x", + csi_sig, CSI_SIGNATURE); + status = MLAN_STATUS_FAILURE; + } else { + /* Send event to moal */ + pevent = (pmlan_event)evt_buf; + pevent->bss_index = pmpriv->bss_index; + pevent->event_id = MLAN_EVENT_ID_CSI; + /* Event length is the CSI record length in byte */ + pevent->event_len = csi_record->Len * 4; + if (pevent->event_len > + pmbuf->data_len - sizeof(eventcause)) + pevent->event_len = + pmbuf->data_len - sizeof(eventcause); + memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf, + csi_record, pevent->event_len, + pevent->event_len); + wlan_recv_event(pmpriv, pevent->event_id, pevent); + } + pcb->moal_mfree(pmadapter->pmoal_handle, evt_buf); + } + + LEAVE(); + return status; +} + /** * @brief This function prepares command of get_hw_spec. * @@ -5020,7 +5147,8 @@ mlan_status wlan_ret_get_hw_spec(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, wlan_show_dot11ndevcap(pmadapter, pmadapter->hw_dot_11n_dev_cap); wlan_show_devmcssupport(pmadapter, pmadapter->hw_dev_mcs_support); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) pmadapter->user_htstream = pmadapter->hw_dev_mcs_support; /** separate stream config for 2.4G and 5G, will be changed according to * antenna cfg*/ @@ -5211,7 +5339,6 @@ mlan_status wlan_ret_get_hw_spec(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, pmadapter, (MrvlIEtypes_Extension_t *)ext_tlv); } - break; case TLV_TYPE_FW_CAP_INFO: fw_cap_tlv = (MrvlIEtypes_fw_cap_info_t *)tlv; @@ -6166,7 +6293,8 @@ mlan_status wlan_ret_802_11_rf_antenna(pmlan_private pmpriv, t_u16 tx_ant_mode = wlan_le16_to_cpu(pantenna->tx_antenna_mode); t_u16 rx_ant_mode = wlan_le16_to_cpu(pantenna->rx_antenna_mode); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) mlan_adapter *pmadapter = pmpriv->adapter; #endif typedef struct _HostCmd_DS_802_11_RF_ANTENNA_1X1 { @@ -6195,8 +6323,10 @@ mlan_status wlan_ret_802_11_rf_antenna(pmlan_private pmpriv, wlan_le16_to_cpu(pantenna->action_tx), tx_ant_mode, wlan_le16_to_cpu(pantenna->action_rx), rx_ant_mode); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if (IS_CARD9098(pmadapter->card_type) || + IS_CARDNW62X(pmadapter->card_type) || IS_CARD9097(pmadapter->card_type)) { tx_ant_mode &= 0x0303; rx_ant_mode &= 0x0303; @@ -6267,7 +6397,8 @@ mlan_status wlan_cmd_reg_access(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, { mlan_ds_reg_rw *reg_rw; #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(USB9097) || defined(SD9097) + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) MrvlIEtypes_Reg_type_t *tlv; mlan_adapter *pmadapter = pmpriv->adapter; #endif @@ -6285,9 +6416,11 @@ mlan_status wlan_cmd_reg_access(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, mac_reg->offset = wlan_cpu_to_le16((t_u16)reg_rw->offset); mac_reg->value = wlan_cpu_to_le32(reg_rw->value); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(USB9097) || defined(SD9097) + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) if ((reg_rw->type == MLAN_REG_MAC2) && (IS_CARD9098(pmadapter->card_type) || + IS_CARDNW62X(pmadapter->card_type) || IS_CARD9097(pmadapter->card_type))) { tlv = (MrvlIEtypes_Reg_type_t *)((t_u8 *)cmd + @@ -6304,6 +6437,17 @@ mlan_status wlan_cmd_reg_access(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, #endif break; } + case HostCmd_CMD_REG_ACCESS: { + HostCmd_DS_REG_ACCESS *reg; + cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_REG_ACCESS) + + S_DS_GEN); + reg = (HostCmd_DS_REG_ACCESS *)&cmd->params.reg; + reg->action = wlan_cpu_to_le16(cmd_action); + reg->reg_type = wlan_cpu_to_le16((t_u16)reg_rw->type); + reg->offset = wlan_cpu_to_le16((t_u16)reg_rw->offset); + reg->value = wlan_cpu_to_le32(reg_rw->value); + break; + } case HostCmd_CMD_BBP_REG_ACCESS: { HostCmd_DS_BBP_REG_ACCESS *bbp_reg; cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_BBP_REG_ACCESS) + @@ -6313,9 +6457,11 @@ mlan_status wlan_cmd_reg_access(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, bbp_reg->offset = wlan_cpu_to_le16((t_u16)reg_rw->offset); bbp_reg->value = (t_u8)reg_rw->value; #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(USB9097) || defined(SD9097) + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) if ((reg_rw->type == MLAN_REG_BBP2) && (IS_CARD9098(pmadapter->card_type) || + IS_CARDNW62X(pmadapter->card_type) || IS_CARD9097(pmadapter->card_type))) { tlv = (MrvlIEtypes_Reg_type_t *)((t_u8 *)cmd + @@ -6341,9 +6487,11 @@ mlan_status wlan_cmd_reg_access(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, rf_reg->offset = wlan_cpu_to_le16((t_u16)reg_rw->offset); rf_reg->value = (t_u8)reg_rw->value; #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(USB9097) || defined(SD9097) + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) if ((reg_rw->type == MLAN_REG_RF2) && (IS_CARD9098(pmadapter->card_type) || + IS_CARDNW62X(pmadapter->card_type) || IS_CARD9097(pmadapter->card_type))) { tlv = (MrvlIEtypes_Reg_type_t *)((t_u8 *)cmd + @@ -6404,9 +6552,11 @@ mlan_status wlan_cmd_reg_access(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, bca_reg->offset = wlan_cpu_to_le16((t_u16)reg_rw->offset); bca_reg->value = wlan_cpu_to_le32(reg_rw->value); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(USB9097) || defined(SD9097) + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) if ((reg_rw->type == MLAN_REG_BCA2) && (IS_CARD9098(pmadapter->card_type) || + IS_CARDNW62X(pmadapter->card_type) || IS_CARD9097(pmadapter->card_type))) { tlv = (MrvlIEtypes_Reg_type_t *)((t_u8 *)cmd + @@ -6463,6 +6613,13 @@ mlan_status wlan_ret_reg_access(mlan_adapter *pmadapter, t_u16 type, reg_rw->value = wlan_le32_to_cpu(reg->value); break; } + case HostCmd_CMD_REG_ACCESS: { + HostCmd_DS_REG_ACCESS *reg; + reg = (HostCmd_DS_REG_ACCESS *)&resp->params.reg; + reg_rw->offset = (t_u32)wlan_le16_to_cpu(reg->offset); + reg_rw->value = wlan_le32_to_cpu(reg->value); + break; + } case HostCmd_CMD_BBP_REG_ACCESS: { HostCmd_DS_BBP_REG_ACCESS *reg; reg = (HostCmd_DS_BBP_REG_ACCESS *)&resp->params.bbp_reg; @@ -6685,35 +6842,64 @@ mlan_status wlan_cmd_802_11_supplicant_pmk(pmlan_private pmpriv, t_u8 zero_mac[] = {0, 0, 0, 0, 0, 0}; t_u8 ssid_flag = 0, bssid_flag = 0, pmk_flag = 0, passphrase_flag = 0; t_u8 sae_password_flag = 0; + t_u8 zero[MLAN_MAX_KEY_LENGTH] = {0}; + MrvlIEtypes_fw_roam_enable_t *proam_tlv = MNULL; + MrvlIEtypes_keyParams_t *key_tlv = MNULL; + int length = 0; + t_u8 userset_passphrase = 0; ENTER(); - psk = (mlan_ds_passphrase *)&sec->param.passphrase; + if (sec->multi_passphrase) + psk = (mlan_ds_passphrase *)&sec->param + .roam_passphrase[userset_passphrase]; + else + psk = (mlan_ds_passphrase *)&sec->param.passphrase; + if (cmd_action == HostCmd_ACT_GEN_REMOVE) { + cmd->size = + sizeof(HostCmd_DS_802_11_SUPPLICANT_PMK) + S_DS_GEN - 1; + proam_tlv = (MrvlIEtypes_fw_roam_enable_t *)ptlv_buffer; + proam_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_ROAM); + proam_tlv->header.len = sizeof(MrvlIEtypes_fw_roam_enable_t) - + sizeof(MrvlIEtypesHeader_t); + proam_tlv->roam_enable = MTRUE; + ptlv_buffer += + (proam_tlv->header.len + sizeof(MrvlIEtypesHeader_t)); + cmd->size += + (proam_tlv->header.len + sizeof(MrvlIEtypesHeader_t)); + proam_tlv->header.len = wlan_cpu_to_le16(proam_tlv->header.len); - /* - * Parse the rest of the buf here - * 1) - This will get the passphrase, AKMP - * for specified ssid, if none specified then it will get all. - * Eg: iwpriv passphrase 0:ssid=nxp - * 2) :: - * - passphrase and psk cannot be provided to - * the same SSID, Takes one SSID at a time, If ssid= is present - * the it should contain a passphrase or psk. If no arguments are - * provided then AKMP=802.1x, and passphrase should be provided - * after association. - * End of each parameter should be followed by a ':'(except for the - * last parameter) as the delimiter. If ':' has to be used in - * an SSID then a '/' should be preceded to ':' as a escape. - * Eg:iwpriv passphrase - * "1:ssid=mrvl AP:psk=abcdefgh:bssid=00:50:43:ef:23:f3" - * iwpriv passphrase - * "1:ssid=nxp/: AP:psk=abcdefgd:bssid=00:50:43:ef:23:f3" - * iwpriv passphrase "1:ssid=mrvlAP:psk=abcdefgd" - * 3) - This will clear the passphrase - * for specified ssid, if none specified then it will clear all. - * Eg: iwpriv passphrase 2:ssid=nxp - */ + cmd->command = wlan_cpu_to_le16(HostCmd_CMD_SUPPLICANT_PMK); + pesupplicant_psk->action = wlan_cpu_to_le16(cmd_action); + pesupplicant_psk->cache_result = 0; + cmd->size = wlan_cpu_to_le16(cmd->size); + LEAVE(); + return MLAN_STATUS_SUCCESS; + } - /* -1 is for t_u8 TlvBuffer[1] as this should not be included */ + // Parse the rest of the buf here + // 1) - This will get the passphrase, AKMP + // for specified ssid, if none specified then it will get all. + // Eg: iwpriv passphrase 0:ssid=nxp + // 2) :: + // - passphrase and psk cannot be provided to + // the same SSID, Takes one SSID at a time, If ssid= is present + // the it should contain a passphrase or psk. If no arguments are + // provided then AKMP=802.1x, and passphrase should be provided + // after association. + // End of each parameter should be followed by a ':'(except for the + // last parameter) as the delimiter. If ':' has to be used in + // an SSID then a '/' should be preceded to ':' as a escape. + // Eg:iwpriv passphrase + // "1:ssid=mrvl AP:psk=abcdefgh:bssid=00:50:43:ef:23:f3" + // iwpriv passphrase + // "1:ssid=nxp/: AP:psk=abcdefgd:bssid=00:50:43:ef:23:f3" + // iwpriv passphrase "1:ssid=mrvlAP:psk=abcdefgd" + // 3) - This will clear the passphrase + // for specified ssid, if none specified then it will clear all. + // Eg: iwpriv passphrase 2:ssid=nxp + // + // + // -1 is for t_u8 TlvBuffer[1] as this should not be included */ cmd->size = sizeof(HostCmd_DS_802_11_SUPPLICANT_PMK) + S_DS_GEN - 1; if (psk && memcmp(pmpriv->adapter, (t_u8 *)&psk->bssid, zero_mac, sizeof(zero_mac))) { @@ -6743,60 +6929,133 @@ mlan_status wlan_cmd_802_11_supplicant_pmk(pmlan_private pmpriv, (ppmk_tlv->header.len + sizeof(MrvlIEtypesHeader_t)); ppmk_tlv->header.len = wlan_cpu_to_le16(ppmk_tlv->header.len); pmk_flag = 1; + if (memcmp(pmpriv->adapter, psk->psk.pmk.pmk_r0, zero, + MLAN_MAX_KEY_LENGTH)) { + ppmk_tlv = (MrvlIEtypes_PMK_t *)ptlv_buffer; + ppmk_tlv->header.type = + wlan_cpu_to_le16(TLV_TYPE_PMK_R0); + ppmk_tlv->header.len = MLAN_MAX_KEY_LENGTH; + memcpy_ext(pmpriv->adapter, ppmk_tlv->pmk, + psk->psk.pmk.pmk_r0, MLAN_MAX_KEY_LENGTH, + MLAN_MAX_KEY_LENGTH); + ptlv_buffer += (ppmk_tlv->header.len + + sizeof(MrvlIEtypesHeader_t)); + cmd->size += (ppmk_tlv->header.len + + sizeof(MrvlIEtypesHeader_t)); + ppmk_tlv->header.len = + wlan_cpu_to_le16(ppmk_tlv->header.len); + } + if (memcmp(pmpriv->adapter, psk->psk.pmk.pmk_r0_name, zero, + MLAN_MAX_PMKR0_NAME_LENGTH)) { + ppmk_tlv = (MrvlIEtypes_PMK_t *)ptlv_buffer; + ppmk_tlv->header.type = + wlan_cpu_to_le16(TLV_TYPE_PMK_R0_NAME); + ppmk_tlv->header.len = MLAN_MAX_PMKR0_NAME_LENGTH; + memcpy_ext(pmpriv->adapter, ppmk_tlv->pmk, + psk->psk.pmk.pmk_r0_name, + MLAN_MAX_PMKR0_NAME_LENGTH, + MLAN_MAX_PMKR0_NAME_LENGTH); + ptlv_buffer += (ppmk_tlv->header.len + + sizeof(MrvlIEtypesHeader_t)); + cmd->size += (ppmk_tlv->header.len + + sizeof(MrvlIEtypesHeader_t)); + ppmk_tlv->header.len = + wlan_cpu_to_le16(ppmk_tlv->header.len); + } } - if (psk->ssid.ssid_len) { - pssid_tlv = (MrvlIEtypes_SsIdParamSet_t *)ptlv_buffer; - pssid_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_SSID); - pssid_tlv->header.len = - (t_u16)MIN(MLAN_MAX_SSID_LENGTH, psk->ssid.ssid_len); - memcpy_ext(pmpriv->adapter, (t_u8 *)pssid_tlv->ssid, - (t_u8 *)psk->ssid.ssid, psk->ssid.ssid_len, - MLAN_MAX_SSID_LENGTH); + if (pmpriv->adapter->fw_roaming && + (pmpriv->adapter->userset_passphrase || + (psk && psk->psk_type == MLAN_PSK_PMK))) { + proam_tlv = (MrvlIEtypes_fw_roam_enable_t *)ptlv_buffer; + proam_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_ROAM); + proam_tlv->header.len = sizeof(MrvlIEtypes_fw_roam_enable_t) - + sizeof(MrvlIEtypesHeader_t); + proam_tlv->roam_enable = MTRUE; + proam_tlv->userset_passphrase = + pmpriv->adapter->userset_passphrase; ptlv_buffer += - (pssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t)); + (proam_tlv->header.len + sizeof(MrvlIEtypesHeader_t)); cmd->size += - (pssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t)); - pssid_tlv->header.len = wlan_cpu_to_le16(pssid_tlv->header.len); - ssid_flag = 1; - } - if (psk->psk_type == MLAN_PSK_PASSPHRASE) { - ppassphrase_tlv = (MrvlIEtypes_Passphrase_t *)ptlv_buffer; - ppassphrase_tlv->header.type = - wlan_cpu_to_le16(TLV_TYPE_PASSPHRASE); - ppassphrase_tlv->header.len = - (t_u16)MIN(MLAN_MAX_PASSPHRASE_LENGTH, - psk->psk.passphrase.passphrase_len); - memcpy_ext(pmpriv->adapter, ppassphrase_tlv->passphrase, - psk->psk.passphrase.passphrase, - psk->psk.passphrase.passphrase_len, - MLAN_MAX_PASSPHRASE_LENGTH); - ptlv_buffer += (ppassphrase_tlv->header.len + - sizeof(MrvlIEtypesHeader_t)); - cmd->size += (ppassphrase_tlv->header.len + - sizeof(MrvlIEtypesHeader_t)); - ppassphrase_tlv->header.len = - wlan_cpu_to_le16(ppassphrase_tlv->header.len); - passphrase_flag = 1; - } - if (psk->psk_type == MLAN_PSK_SAE_PASSWORD) { - psae_password_tlv = (MrvlIEtypes_SAE_Password_t *)ptlv_buffer; - psae_password_tlv->header.type = - wlan_cpu_to_le16(TLV_TYPE_SAE_PASSWORD); - psae_password_tlv->header.len = - (t_u16)MIN(MLAN_MAX_SAE_PASSWORD_LENGTH, - psk->psk.sae_password.sae_password_len); - memcpy_ext(pmpriv->adapter, psae_password_tlv->sae_password, - psk->psk.sae_password.sae_password, - psk->psk.sae_password.sae_password_len, - MLAN_MAX_SAE_PASSWORD_LENGTH); - ptlv_buffer += (psae_password_tlv->header.len + - sizeof(MrvlIEtypesHeader_t)); - cmd->size += (psae_password_tlv->header.len + - sizeof(MrvlIEtypesHeader_t)); - psae_password_tlv->header.len = - wlan_cpu_to_le16(psae_password_tlv->header.len); - sae_password_flag = 1; + (proam_tlv->header.len + sizeof(MrvlIEtypesHeader_t)); + proam_tlv->header.len = wlan_cpu_to_le16(proam_tlv->header.len); } + do { + if (pmpriv->adapter->userset_passphrase && + sec->multi_passphrase) { + key_tlv = (MrvlIEtypes_keyParams_t *)ptlv_buffer; + key_tlv->header.type = wlan_cpu_to_le16( + TLV_TYPE_ROAM_OFFLOAD_USER_SET_PMK); + ptlv_buffer += sizeof(MrvlIEtypesHeader_t); + cmd->size += sizeof(MrvlIEtypesHeader_t); + length = cmd->size; + } + if (psk->ssid.ssid_len) { + pssid_tlv = (MrvlIEtypes_SsIdParamSet_t *)ptlv_buffer; + pssid_tlv->header.type = + wlan_cpu_to_le16(TLV_TYPE_SSID); + pssid_tlv->header.len = (t_u16)MIN(MLAN_MAX_SSID_LENGTH, + psk->ssid.ssid_len); + memcpy_ext(pmpriv->adapter, (t_u8 *)pssid_tlv->ssid, + (t_u8 *)psk->ssid.ssid, psk->ssid.ssid_len, + MLAN_MAX_SSID_LENGTH); + ptlv_buffer += (pssid_tlv->header.len + + sizeof(MrvlIEtypesHeader_t)); + cmd->size += (pssid_tlv->header.len + + sizeof(MrvlIEtypesHeader_t)); + pssid_tlv->header.len = + wlan_cpu_to_le16(pssid_tlv->header.len); + ssid_flag = 1; + } + if (psk->psk_type == MLAN_PSK_PASSPHRASE) { + ppassphrase_tlv = + (MrvlIEtypes_Passphrase_t *)ptlv_buffer; + ppassphrase_tlv->header.type = + wlan_cpu_to_le16(TLV_TYPE_PASSPHRASE); + ppassphrase_tlv->header.len = + (t_u16)MIN(MLAN_MAX_PASSPHRASE_LENGTH, + psk->psk.passphrase.passphrase_len); + memcpy_ext(pmpriv->adapter, ppassphrase_tlv->passphrase, + psk->psk.passphrase.passphrase, + psk->psk.passphrase.passphrase_len, + MLAN_MAX_PASSPHRASE_LENGTH); + ptlv_buffer += (ppassphrase_tlv->header.len + + sizeof(MrvlIEtypesHeader_t)); + cmd->size += (ppassphrase_tlv->header.len + + sizeof(MrvlIEtypesHeader_t)); + ppassphrase_tlv->header.len = + wlan_cpu_to_le16(ppassphrase_tlv->header.len); + passphrase_flag = 1; + } + if (psk->psk_type == MLAN_PSK_SAE_PASSWORD) { + psae_password_tlv = + (MrvlIEtypes_SAE_Password_t *)ptlv_buffer; + psae_password_tlv->header.type = + wlan_cpu_to_le16(TLV_TYPE_SAE_PASSWORD); + psae_password_tlv->header.len = (t_u16)MIN( + MLAN_MAX_SAE_PASSWORD_LENGTH, + psk->psk.sae_password.sae_password_len); + memcpy_ext(pmpriv->adapter, + psae_password_tlv->sae_password, + psk->psk.sae_password.sae_password, + psk->psk.sae_password.sae_password_len, + MLAN_MAX_SAE_PASSWORD_LENGTH); + ptlv_buffer += (psae_password_tlv->header.len + + sizeof(MrvlIEtypesHeader_t)); + cmd->size += (psae_password_tlv->header.len + + sizeof(MrvlIEtypesHeader_t)); + psae_password_tlv->header.len = + wlan_cpu_to_le16(psae_password_tlv->header.len); + sae_password_flag = 1; + } + if (key_tlv) + key_tlv->header.len = + wlan_cpu_to_le16(cmd->size - length); + userset_passphrase++; + psk = (mlan_ds_passphrase *)&sec->param + .roam_passphrase[userset_passphrase]; + } while (psk && sec->multi_passphrase && + userset_passphrase < pmpriv->adapter->userset_passphrase); + pmpriv->adapter->userset_passphrase = 0; if ((cmd_action == HostCmd_ACT_GEN_SET) && ((ssid_flag || bssid_flag) && (!pmk_flag && !passphrase_flag) && (!pmk_flag && !sae_password_flag))) { @@ -8819,6 +9078,115 @@ mlan_status wlan_ret_get_chan_trpc_config(pmlan_private pmpriv, return MLAN_STATUS_SUCCESS; } +/** + * @brief This function prepares command of mc_aggr_cfg + * + * @param pmpriv A pointer to mlan_private structure + * @param cmd A pointer to HostCmd_DS_COMMAND structure + * @param cmd_action the action: GET or SET + * @param pdata_buf A pointer to data buffer + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_cmd_mc_aggr_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, + t_u16 cmd_action, t_void *pdata_buf) +{ + HostCmd_DS_MC_AGGR_CFG *cfg_cmd = + (HostCmd_DS_MC_AGGR_CFG *)&cmd->params.mc_aggr_cfg; + mlan_ds_mc_aggr_cfg *cfg = (mlan_ds_mc_aggr_cfg *)pdata_buf; + + ENTER(); + + cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MC_AGGR_CFG); + cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_MC_AGGR_CFG) + S_DS_GEN); + cfg_cmd->action = wlan_cpu_to_le16(cmd_action); + + cfg_cmd->enable_bitmap = (t_u8)cfg->enable_bitmap; + cfg_cmd->mask_bitmap = (t_u8)cfg->mask_bitmap; + cfg_cmd->cts2self_offset = wlan_cpu_to_le16(cfg->cts2self_offset); + LEAVE(); + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief This function handles the command response of mc_aggr_cfg + * + * @param pmpriv A pointer to mlan_private structure + * @param resp A pointer to HostCmd_DS_COMMAND + * @param pioctl_buf A pointer to mlan_ioctl_req structure + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_ret_mc_aggr_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf) +{ + HostCmd_DS_MC_AGGR_CFG *cfg_cmd = + (HostCmd_DS_MC_AGGR_CFG *)&resp->params.mc_aggr_cfg; + mlan_ds_misc_cfg *misc_cfg = MNULL; + + ENTER(); + + if (pioctl_buf) { + misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; + misc_cfg->param.mc_aggr_cfg.enable_bitmap = + (t_u8)cfg_cmd->enable_bitmap; + misc_cfg->param.mc_aggr_cfg.mask_bitmap = + (t_u8)cfg_cmd->mask_bitmap; + misc_cfg->param.mc_aggr_cfg.cts2self_offset = + (t_u8)cfg_cmd->cts2self_offset; + } + LEAVE(); + return MLAN_STATUS_SUCCESS; +} +/** + * @brief This function prepares command of ch_load + * + * @param pmpriv A pointer to mlan_private structure + * @param cmd A pointer to HostCmd_DS_COMMAND structure + * @param cmd_action the action: GET or SET + * @param pdata_buf A pointer to data buffer + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_cmd_get_ch_load(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, + t_u16 cmd_action, t_void *pdata_buf) +{ + HostCmd_DS_GET_CH_LOAD *cfg_cmd = + (HostCmd_DS_GET_CH_LOAD *)&cmd->params.ch_load; + mlan_ds_ch_load *cfg = (mlan_ds_ch_load *)pdata_buf; + + ENTER(); + + cmd->command = wlan_cpu_to_le16(HostCmd_CMD_GET_CH_LOAD); + cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_GET_CH_LOAD) + S_DS_GEN); + cfg_cmd->action = wlan_cpu_to_le16(cmd_action); + cfg_cmd->ch_load = wlan_cpu_to_le16(cfg->ch_load_param); + LEAVE(); + return MLAN_STATUS_SUCCESS; +} +/** + * @brief This function handles the command response of ch_load + * + * @param pmpriv A pointer to mlan_private structure + * @param resp A pointer to HostCmd_DS_COMMAND + * @param pioctl_buf A pointer to mlan_ioctl_req structure + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_ret_ch_load(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf) +{ + HostCmd_DS_GET_CH_LOAD *cfg_cmd = + (HostCmd_DS_GET_CH_LOAD *)&resp->params.ch_load; + mlan_ds_misc_cfg *misc_cfg = MNULL; + ENTER(); + if (pioctl_buf) { + misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; + misc_cfg->param.ch_load.ch_load_param = + wlan_le16_to_cpu(cfg_cmd->ch_load); + } + LEAVE(); + return MLAN_STATUS_SUCCESS; +} + /** * @brief This function prepares command of RANGE_EXT * @@ -8875,3 +9243,59 @@ mlan_status wlan_ret_range_ext(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, LEAVE(); return MLAN_STATUS_SUCCESS; } + +/** + * @brief This function prepares command of get_sensor_temp + * + * @param pmpriv A pointer to mlan_private structure + * @param cmd A pointer to HostCmd_DS_COMMAND structure + * @param cmd_action the action: GET or SET + * @param pdata_buf A pointer to data buffer + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_cmd_get_sensor_temp(pmlan_private pmpriv, + HostCmd_DS_COMMAND *cmd, t_u16 cmd_action) +{ + ENTER(); + + if (cmd_action != HostCmd_ACT_GEN_GET) { + PRINTM(MERROR, "wlan_cmd_get_sensor_temp: support GET only.\n"); + LEAVE(); + return MLAN_STATUS_FAILURE; + } + + cmd->command = wlan_cpu_to_le16(HostCmd_DS_GET_SENSOR_TEMP); + cmd->size = wlan_cpu_to_le16(S_DS_GEN + 4); + + LEAVE(); + return MLAN_STATUS_SUCCESS; +} +/** + * @brief This function handles the command response of get_sensor_temp + * + * @param pmpriv A pointer to mlan_private structure + * @param resp A pointer to HostCmd_DS_COMMAND + * @param pioctl_buf A pointer to mlan_ioctl_req structure + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_ret_get_sensor_temp(pmlan_private pmpriv, + HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf) +{ + mlan_ds_misc_cfg *pcfg = MNULL; + const HostCmd_DS_SENSOR_TEMP *pSensorT = &resp->params.temp_sensor; + + ENTER(); + + if (pioctl_buf) { + pcfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; + pcfg->param.sensor_temp.temperature = + wlan_le32_to_cpu(pSensorT->temperature); + PRINTM(MCMND, "get SOC temperature %u C \n", + pSensorT->temperature); + } + + LEAVE(); + return MLAN_STATUS_SUCCESS; +} diff --git a/mxm_wifiex/wlan_src/mlan/mlan_decl.h b/mxm_wifiex/wlan_src/mlan/mlan_decl.h index f24b04b..7d1be10 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_decl.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_decl.h @@ -3,7 +3,7 @@ * @brief This file declares the generic data structures and APIs. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -24,7 +24,7 @@ #define _MLAN_DECL_H_ /** MLAN release version */ -#define MLAN_RELEASE_VERSION "299.p1" +#define MLAN_RELEASE_VERSION "322" /** Re-define generic data types for MLAN/MOAL */ /** Signed char (1-byte) */ @@ -98,6 +98,8 @@ typedef t_s32 t_sval; /** MLAN FALSE */ #define MFALSE (0) +#define CHANNEL_SPEC_SNIFFER_MODE 1 + #ifndef MACSTR /** MAC address security format */ #define MACSTR "%02x:XX:XX:XX:%02x:%02x" @@ -375,6 +377,8 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; #define CARD_TYPE_9177 0x09 /** 8801 card type */ #define CARD_TYPE_8801 0x0a +/** OWL card type */ +#define CARD_TYPE_NW62X 0x0b /** 9098 A0 reverion num */ #define CHIP_9098_REV_A0 1 @@ -406,6 +410,8 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; #define CARD_TYPE_SD9177 (CARD_TYPE_9177 | (INTF_SD << 8)) /** SD8801 card type */ #define CARD_TYPE_SD8801 (CARD_TYPE_8801 | (INTF_SD << 8)) +/** SD_NW62X card type */ +#define CARD_TYPE_SDNW62X (CARD_TYPE_NW62X | (INTF_SD << 8)) #define IS_SD8887(ct) (CARD_TYPE_SD8887 == (ct)) #define IS_SD8897(ct) (CARD_TYPE_SD8897 == (ct)) @@ -417,6 +423,7 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; #define IS_SD9098(ct) (CARD_TYPE_SD9098 == (ct)) #define IS_SD9177(ct) (CARD_TYPE_SD9177 == (ct)) #define IS_SD8801(ct) (CARD_TYPE_SD8801 == (ct)) +#define IS_SDNW62X(ct) (CARD_TYPE_SDNW62X == (ct)) /** SD8887 Card */ #define CARD_SD8887 "SD8887" @@ -431,15 +438,15 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; /** SD8987 Card */ #define CARD_SD8987 "SD8987" /** SD9097 Card */ -#define CARD_SD9097 "SD9097" -/** SDIW620 Card */ -#define CARD_SDIW620 "SDIW620" +#define CARD_SD9097 "SDIW620" /** SD9098 Card */ #define CARD_SD9098 "SD9098" /** SD9177 Card */ #define CARD_SD9177 "SD9177" /** SD8801 Card */ #define CARD_SD8801 "SD8801" +/** SDNW62X Card */ +#define CARD_SDNW62X "SDNW62X" #endif #ifdef PCIE @@ -451,26 +458,29 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; #define CARD_TYPE_PCIE9097 (CARD_TYPE_9097 | (INTF_PCIE << 8)) /** PCIE9098 card type */ #define CARD_TYPE_PCIE9098 (CARD_TYPE_9098 | (INTF_PCIE << 8)) +/** PCIENW62X card type */ +#define CARD_TYPE_PCIENW62X (CARD_TYPE_NW62X | (INTF_PCIE << 8)) #define IS_PCIE8897(ct) (CARD_TYPE_PCIE8897 == (ct)) #define IS_PCIE8997(ct) (CARD_TYPE_PCIE8997 == (ct)) #define IS_PCIE9097(ct) (CARD_TYPE_PCIE9097 == (ct)) #define IS_PCIE9098(ct) (CARD_TYPE_PCIE9098 == (ct)) +#define IS_PCIENW62X(ct) (CARD_TYPE_PCIENW62X == (ct)) /** PCIE8897 Card */ #define CARD_PCIE8897 "PCIE8897" /** PCIE8997 Card */ #define CARD_PCIE8997 "PCIE8997" /** PCIE9097 Card */ -#define CARD_PCIE9097 "PCIE9097" -/** PCIEIW620 Card */ -#define CARD_PCIEIW620 "PCIEIW620" +#define CARD_PCIE9097 "PCIEIW620" /** PCIE9000S Card */ #define CARD_PCIE9000S "PCIE9000S" /** PCIE9098 Card */ #define CARD_PCIE9098 "PCIE9098" /** PCIEAW690 Card */ #define CARD_PCIEAW690 "PCIEAW690" +/** PCIENW62X Card */ +#define CARD_PCIENW62X "PCIENW62X" #endif #ifdef USB @@ -486,6 +496,8 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; #define CARD_TYPE_USB9098 (CARD_TYPE_9098 | (INTF_USB << 8)) /** USB9097 card type */ #define CARD_TYPE_USB9097 (CARD_TYPE_9097 | (INTF_USB << 8)) +/** USBNW62X card type */ +#define CARD_TYPE_USBNW62X (CARD_TYPE_NW62X | (INTF_USB << 8)) #define IS_USB8801(ct) (CARD_TYPE_USB8801 == (ct)) #define IS_USB8897(ct) (CARD_TYPE_USB8897 == (ct)) @@ -493,6 +505,7 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; #define IS_USB8978(ct) (CARD_TYPE_USB8978 == (ct)) #define IS_USB9098(ct) (CARD_TYPE_USB9098 == (ct)) #define IS_USB9097(ct) (CARD_TYPE_USB9097 == (ct)) +#define IS_USBNW62X(ct) (CARD_TYPE_USBNW62X == (ct)) /** USB8801 Card */ #define CARD_USB8801 "USB8801" @@ -505,9 +518,9 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; /** USB9098 Card */ #define CARD_USB9098 "USB9098" /** USB9097 Card */ -#define CARD_USB9097 "USB9097" -/** USBIW620 Card */ -#define CARD_USBIW620 "USBIW620" +#define CARD_USB9097 "USBIW620" +/** USBNW62X Card */ +#define CARD_USBNW62X "USBNW62X" #endif #define IS_CARD8801(ct) (CARD_TYPE_8801 == ((ct)&0xf)) @@ -519,6 +532,7 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; #define IS_CARD9098(ct) (CARD_TYPE_9098 == ((ct)&0xf)) #define IS_CARD9097(ct) (CARD_TYPE_9097 == ((ct)&0xf)) #define IS_CARD9177(ct) (CARD_TYPE_9177 == ((ct)&0xf)) +#define IS_CARDNW62X(ct) (CARD_TYPE_NW62X == ((ct)&0xf)) typedef struct _card_type_entry { t_u16 card_type; @@ -578,6 +592,9 @@ typedef enum { /** Buffer flag for TX_STATUS */ #define MLAN_BUF_FLAG_TX_STATUS MBIT(10) +/** Buffer flag for NET_MONITOR */ +#define MLAN_BUF_FLAG_NET_MONITOR MBIT(11) + /** Buffer flag for NULL data packet */ #define MLAN_BUF_FLAG_NULL_PKT MBIT(12) /** Buffer flag for Diag pkt */ @@ -585,6 +602,8 @@ typedef enum { #define MLAN_BUF_FLAG_TX_CTRL MBIT(14) +#define MLAN_BUF_FLAG_MC_AGGR_PKT MBIT(17) + #ifdef DEBUG_LEVEL1 /** Debug level bit definition */ #define MMSG MBIT(0) @@ -694,6 +713,7 @@ typedef enum _mlan_bss_type { #ifdef WIFI_DIRECT_SUPPORT MLAN_BSS_TYPE_WIFIDIRECT = 2, #endif + MLAN_BSS_TYPE_DFS = 8, MLAN_BSS_TYPE_ANY = 0xff, } mlan_bss_type; @@ -767,6 +787,7 @@ typedef enum _mlan_event_id { #if defined(PCIE) MLAN_EVENT_ID_SSU_DUMP_FILE = 0x00000039, #endif /* SSU_SUPPORT */ + MLAN_EVENT_ID_CSI = 0x00000040, /* Event generated by MLAN driver (MSB=1) */ MLAN_EVENT_ID_DRV_CONNECTED = 0x80000001, MLAN_EVENT_ID_DRV_DEFER_HANDLING = 0x80000002, @@ -789,6 +810,7 @@ typedef enum _mlan_event_id { #ifdef UAP_SUPPORT MLAN_EVENT_ID_DRV_UAP_CHAN_INFO = 0x80000020, #endif + MLAN_EVENT_ID_FW_ROAM_OFFLOAD_RESULT = 0x80000023, MLAN_EVENT_ID_DRV_ASSOC_FAILURE_LOGGER = 0x80000026, MLAN_EVENT_ID_DRV_ASSOC_SUCC_LOGGER = 0x80000027, MLAN_EVENT_ID_DRV_DISCONNECT_LOGGER = 0x80000028, @@ -875,6 +897,7 @@ enum mlan_channel_type { enum { BAND_2GHZ = 0, BAND_5GHZ = 1, BAND_4GHZ = 2, + BAND_6GHZ = 3, }; /** channel offset */ @@ -925,16 +948,6 @@ typedef enum _dfs_w53_cfg_t { /** Band_Config_t */ typedef MLAN_PACK_START struct _Band_Config_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Channel Selection Mode - (00)=manual, (01)=ACS, (02)=user*/ - t_u8 scanMode : 2; - /** Secondary Channel Offset - (00)=None, (01)=Above, (11)=Below */ - t_u8 chan2Offset : 2; - /** Channel Width - (00)=20MHz, (10)=40MHz, (11)=80MHz */ - t_u8 chanWidth : 2; - /** Band Info - (00)=2.4GHz, (01)=5GHz */ - t_u8 chanBand : 2; -#else /** Band Info - (00)=2.4GHz, (01)=5GHz */ t_u8 chanBand : 2; /** Channel Width - (00)=20MHz, (10)=40MHz, (11)=80MHz */ @@ -943,7 +956,6 @@ typedef MLAN_PACK_START struct _Band_Config_t { t_u8 chan2Offset : 2; /** Channel Selection Mode - (00)=manual, (01)=ACS, (02)=Adoption mode*/ t_u8 scanMode : 2; -#endif } MLAN_PACK_END Band_Config_t; /** channel_band_t */ @@ -1033,6 +1045,45 @@ typedef struct _mlan_cmdresp_event { } mlan_cmdresp_event, *pmlan_cmdresp_event; /** csi event data structure */ +typedef MLAN_PACK_START struct _csi_record_ds { + /** Length in DWORDS, including header */ + t_u16 Len; + /** CSI signature. 0xABCD fixed */ + t_u16 CSI_Sign; + /** User defined HeaderID */ + t_u32 CSI_HeaderID; + /** Packet info field */ + t_u16 PKT_info; + /** Frame control field for the received packet*/ + t_u16 FCF; + /** Timestamp when packet received */ + t_u64 TSF; + /** Received Packet Destination MAC Address */ + t_u8 Dst_MAC[6]; + /** Received Packet Source MAC Address */ + t_u8 Src_MAC[6]; + /** RSSI for antenna A */ + t_u8 Rx_RSSI_A; + /** RSSI for antenna B */ + t_u8 Rx_RSSI_B; + /** Noise floor for antenna A */ + t_u8 Rx_NF_A; + /** Noise floor for antenna A */ + t_u8 Rx_NF_B; + /** Rx signal strength above noise floor */ + t_u8 Rx_SINR; + /** Channel */ + t_u8 channel; + /** user defined Chip ID */ + t_u16 chip_id; + /** Reserved */ + t_u32 rsvd; + /** CSI data length in DWORDs */ + t_u32 CSI_Data_Length; + /** Start of CSI data */ + t_u8 CSI_Data[0]; + /** At the end of CSI raw data, user defined TailID of 4 bytes*/ +} MLAN_PACK_END csi_record_ds, *pcsi_record_ds; /** mlan_ioctl_req data structure */ typedef struct _mlan_ioctl_req { @@ -1060,18 +1111,52 @@ typedef struct _mlan_ioctl_req { t_ptr reserved_1; } mlan_ioctl_req, *pmlan_ioctl_req; +typedef MLAN_PACK_START struct _mix_rate_info { + /** bit0: LGI: gi=0, SGI: gi= 1 */ + /** bit1-2: 20M: bw=0, 40M: bw=1, 80M: bw=2, 160M: bw=3 */ + /** bit3-4: LG: format=0, HT: format=1, VHT: format=2 */ + /** bit5: LDPC: 0-not support, 1-support */ + /** bit6-7:reserved */ + t_u8 rate_info; + /** MCS index */ + t_u8 mcs_index; + /** bitrate, in 500Kbps */ + t_u16 bitrate; +} MLAN_PACK_END mix_rate_info, *pmix_rate_info; + +typedef MLAN_PACK_START struct _rxpd_extra_info { + /** flags */ + t_u8 flags; + /** channel.flags */ + t_u16 channel_flags; + /** mcs.known */ + t_u8 mcs_known; + /** mcs.flags */ + t_u8 mcs_flags; + /** vht sig1 */ + t_u32 vht_sig1; + /** vht sig2 */ + t_u32 vht_sig2; +} MLAN_PACK_END rxpd_extra_info, *prxpd_extra_info; + +typedef MLAN_PACK_START struct _radiotap_info { + /** Rate Info */ + mix_rate_info rate_info; + /** SNR */ + t_s8 snr; + /** Noise Floor */ + t_s8 nf; + /** band config */ + t_u8 band_config; + /** chan number */ + t_u8 chan_num; + t_u8 antenna; + /** extra rxpd info from FW */ + rxpd_extra_info extra_info; +} MLAN_PACK_END radiotap_info, *pradiotap_info; + /** txpower structure */ typedef MLAN_PACK_START struct { -#ifdef BIG_ENDIAN_SUPPORT - /** Host tx power ctrl: - 0x0: use fw setting for TX power - 0x1: value specified in bit[6] and bit[5:0] are valid */ - t_u8 hostctl : 1; - /** Sign of the power specified in bit[5:0] */ - t_u8 sign : 1; - /** Power to be used for transmission(in dBm) */ - t_u8 abs_val : 6; -#else /** Power to be used for transmission(in dBm) */ t_u8 abs_val : 6; /** Sign of the power specified in bit[5:0] */ @@ -1080,7 +1165,6 @@ typedef MLAN_PACK_START struct { 0x0: use fw setting for TX power 0x1: value specified in bit[6] and bit[5:0] are valid */ t_u8 hostctl : 1; -#endif } MLAN_PACK_END tx_power_t; /* pkt_txctrl */ typedef MLAN_PACK_START struct _pkt_txctrl { @@ -1111,6 +1195,25 @@ typedef MLAN_PACK_START struct _pkt_rxinfo { t_u8 rssi; } MLAN_PACK_END pkt_rxinfo, *ppkt_rxinfo; +#define MC_FLAG_RETRY MBIT(0) +#define MC_FLAG_START_CYCLE MBIT(1) +#define MC_FLAG_END_CYCLE MBIT(2) +#define MC_FLAG_START_AMPDU MBIT(3) +#define MC_FLAG_END_AMPDU MBIT(4) +/* mc pkt txcontrol */ +typedef MLAN_PACK_START struct _mc_txcontrol { + /** Data rate in mcs index, 0-7 */ + t_u8 mcs_index; + /** band width 0-20Mhz, 1-40Mhz */ + t_u8 bandwidth; + /** seq_num */ + t_u16 seq_num; + /** packet expiry time */ + t_u32 pkt_expiry; + /** mc_pkt_flags */ + t_u8 mc_pkt_flags; +} MLAN_PACK_END mc_txcontrol, *pmc_txcontrol; + /** mlan_buffer data structure */ typedef struct _mlan_buffer { /** Pointer to previous mlan_buffer */ @@ -1162,6 +1265,7 @@ typedef struct _mlan_buffer { /** Use count for this buffer */ t_u32 use_count; union { + mc_txcontrol mc_tx_info; pkt_txctrl tx_info; pkt_rxinfo rx_info; } u; @@ -2270,4 +2374,6 @@ MLAN_API mlan_status mlan_disable_host_int(t_void *padapter); /** mlan unmask host interrupt */ MLAN_API mlan_status mlan_enable_host_int(t_void *padapter); +#define CSI_SIGNATURE 0xABCD + #endif /* !_MLAN_DECL_H_ */ diff --git a/mxm_wifiex/wlan_src/mlan/mlan_fw.h b/mxm_wifiex/wlan_src/mlan/mlan_fw.h index c439b8c..f1bcd9f 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_fw.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_fw.h @@ -5,7 +5,7 @@ * in MLAN module. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -421,6 +421,31 @@ typedef enum _WLAN_802_11_WEP_STATUS { /** TLV type : BCN miss */ #define TLV_TYPE_PRE_BCNMISS (PROPRIETARY_TLV_BASE_ID + 0x49) /* 0x0149 */ +/** TLV type : ENABLE ROAM IE */ +#define TLV_TYPE_ROAM (PROPRIETARY_TLV_BASE_ID + 245) +/** TLV type : AP LIST IE */ +#define TLV_TYPE_APLIST (PROPRIETARY_TLV_BASE_ID + 246) +/** TLV type : PMK */ +#define TLV_TYPE_PMK_R0 (PROPRIETARY_TLV_BASE_ID + 247) +/** TLV type : PMK */ +#define TLV_TYPE_PMK_R0_NAME (PROPRIETARY_TLV_BASE_ID + 248) +/** TLV type : TRIGGER CONDITION*/ +#define TLV_TYPE_ROM_TRIGGER (PROPRIETARY_TLV_BASE_ID + 264) +/** TLV type : RETRY_COUNT*/ +#define TLV_TYPE_ROM_RETRY_COUNT (PROPRIETARY_TLV_BASE_ID + 265) +/** TLV type : BGSCAN SETTING*/ +#define TLV_TYPE_ROM_BGSCAN (PROPRIETARY_TLV_BASE_ID + 266) +/** TLV type : PARA RSSI*/ +#define TLV_TYPE_ROM_PARA_RSSI (PROPRIETARY_TLV_BASE_ID + 267) +/** TLV type : BSSID blacklist*/ +#define TLV_TYPE_BLACKLIST_BSSID (PROPRIETARY_TLV_BASE_ID + 0x11d) +/** TLV type : BAND & RSSI*/ +#define TLV_TYPE_BAND_RSSI (PROPRIETARY_TLV_BASE_ID + 0x11e) +/** TLV type : ESS scan*/ +#define TLV_TYPE_ENERGYEFFICIENTSCAN (PROPRIETARY_TLV_BASE_ID + 0xda) +/** TLV type : KEY params*/ +#define TLV_TYPE_ROAM_OFFLOAD_USER_SET_PMK (PROPRIETARY_TLV_BASE_ID + 291) + /** TLV type: WAPI IE */ #define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 0x5e) /* 0x015e */ @@ -429,6 +454,10 @@ typedef enum _WLAN_802_11_WEP_STATUS { /** TLV type: MAX_MGMT_IE */ #define TLV_TYPE_MAX_MGMT_IE (PROPRIETARY_TLV_BASE_ID + 0xaa) /* 0x01aa */ +/** TLV : Region Domain Code */ +#define TLV_TYPE_REGION_DOMAIN_CODE \ + (PROPRIETARY_TLV_BASE_ID + 0xab) /* 0x01ab */ + /** TLV type: key param v2 */ #define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 0x9C) /* 0x019C */ @@ -1062,6 +1091,8 @@ typedef enum _WLAN_802_11_WEP_STATUS { (PROPRIETARY_TLV_BASE_ID + 0x5b) /* 0x015b \ */ +/** TLV type : ZERO DFS Operation */ +#define TLV_TYPE_ZERO_DFS_OPERATION (PROPRIETARY_TLV_BASE_ID + 0x13b) // + 315 /** TLV type : DFS W53 Configuration */ #define TLV_TYPE_DFS_W53_CFG (PROPRIETARY_TLV_BASE_ID + 0x145) // + 325 #ifdef OPCHAN @@ -1261,6 +1292,8 @@ typedef enum _WLAN_802_11_WEP_STATUS { /** Host Command ID : 802.11 RSSI INFO EXT*/ #define HostCmd_CMD_RSSI_INFO_EXT 0x0237 +/** Host Command ID : ROAMING OFFLOAD TO FW*/ +#define HostCmd_CMD_ROAM_OFFLOAD 0x0245 #ifdef RX_PACKET_COALESCE /** TLV ID for RX pkt coalesce config */ @@ -1316,6 +1349,10 @@ typedef enum _WLAN_802_11_WEP_STATUS { #define HostCmd_CMD_MGMT_IE_LIST 0x00f2 #define HostCmd_CMD_802_11_BAND_STEERING 0x026f +/*** Host Command ID " MC_AGGR_CFG */ +#define HostCmd_CMD_MC_AGGR_CFG 0x027a +#define HostCmd_CMD_GET_CH_LOAD 0x027b + /** Host Command ID : TDLS configuration */ #define HostCmd_CMD_TDLS_CONFIG 0x0100 /** Host Command ID : TDLS operation */ @@ -1342,6 +1379,9 @@ typedef enum _WLAN_802_11_WEP_STATUS { /** fw_cap_info bit23 for embedded authenticator support*/ #define FW_CAPINFO_AUTH_SUPPORT MBIT(22) +/** fw_cap_info bit23 for firmware roaming*/ +#define FW_ROAMING_SUPPORT MBIT(23) + /** fw_cap_info bit25 for adhoc support*/ #define FW_CAPINFO_ADHOC_SUPPORT MBIT(25) /** Check if adhoc is supported by firmware */ @@ -1382,6 +1422,10 @@ typedef enum _WLAN_802_11_WEP_STATUS { #define FW_CAPINFO_EXT_OTP_CALDATA MBIT(11) /** FW cap info bit 12: RTT Support */ #define FW_CAPINFO_EXT_RTT MBIT(12) +/** FW cap info bit 13: Channel Tracking Support */ +#define FW_CAPINFO_EXT_CHAN_TRACK MBIT(13) +/** FW cap info bit 14: 6G Support */ +#define FW_CAPINFO_EXT_6G MBIT(14) /** Check if 5G 1x1 only is supported by firmware */ #define IS_FW_SUPPORT_5G_1X1_ONLY(_adapter) \ @@ -1415,6 +1459,11 @@ typedef enum _WLAN_802_11_WEP_STATUS { (_adapter->fw_cap_ext & FW_CAPINFO_EXT_BEACON_PROT) /** Check if RTT supported by firmware */ #define IS_FW_SUPPORT_RTT(_adapter) (_adapter->fw_cap_ext & FW_CAPINFO_EXT_RTT) +/** Check if Channel Tracking supported by firmware */ +#define IS_FW_SUPPORT_CHAN_TRACK(_adapter) \ + (_adapter->fw_cap_ext & FW_CAPINFO_EXT_CHAN_TRACK) +/** Check if 6G supported by firmware */ +#define IS_FW_SUPPORT_6G(_adapter) (_adapter->fw_cap_ext & FW_CAPINFO_EXT_6G) /** MrvlIEtypes_PrevBssid_t */ typedef MLAN_PACK_START struct _MrvlIEtypes_PrevBssid_t { @@ -1482,6 +1531,24 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_He_cap_t { t_u8 val[20]; } MLAN_PACK_END MrvlIEtypes_He_cap_t, *pMrvlIEtypes_he_cap_t; +typedef MLAN_PACK_START struct _MrvlIEtypes_He_Op_t { + /** Header */ + MrvlIEtypesHeader_t header; + /** Element id extension */ + t_u8 ext_id; + /** HE Operation Parameters */ + t_u16 he_op_param1; + /** HE Operation Parameters */ + t_u8 he_op_param2; + /** BSS Color Info */ + t_u8 bss_color_info; + /** Basic HE-MCS and NSS Set */ + t_u16 basic_he_mcs_nss; + /** Optional Field, including VHT Operation Info Max Co-Hosted BSSID + * Indicator, and 6Ghz Operation Info */ + t_u8 option[9]; +} MLAN_PACK_END MrvlIEtypes_He_Op_t; + #ifdef RX_PACKET_COALESCE /** Host Command ID : Rx packet coalescing configuration */ #define HostCmd_CMD_RX_PKT_COALESCE_CFG 0x012c @@ -1526,6 +1593,9 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_He_cap_t { /** Host Command id: PMIC CONFIGURE*/ #define HOST_CMD_PMIC_CONFIGURE 0x23E +/** Host Command ID: 802.11 Network Monitor */ +#define HostCmd_CMD_802_11_NET_MONITOR 0x0102 + /** Host Command ID: Tx data pause */ #define HostCmd_CMD_CFG_TX_DATA_PAUSE 0x0103 @@ -1564,6 +1634,8 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_He_cap_t { /** Host Command ID: BCA device access */ #define HostCmd_CMD_BCA_REG_ACCESS 0x0272 +/** Host Command ID: register device access */ +#define HostCmd_CMD_REG_ACCESS 0x027C /** Host Command ID: DFS repeater mode */ #define HostCmd_DFS_REPEATER_MODE 0x012b @@ -1588,7 +1660,8 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_He_cap_t { #define HostCmd_CMD_INDEPENDENT_RESET_CFG 0x0243 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(USB9097) || defined(SD9097) + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) /* TLV type: reg type */ #define TLV_TYPE_REG_ACCESS_CTRL (PROPRIETARY_TLV_BASE_ID + 0x13C) /* 0x023c*/ /** MrvlIEtypes_Reg_type_t*/ @@ -1598,7 +1671,6 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_Reg_type_t { /** type: 0x81/0x82/0x83 */ t_u8 type; } MLAN_PACK_END MrvlIEtypes_Reg_type_t; - #endif /** use to query chan region cfg setting in firmware */ #define HostCmd_CMD_CHAN_REGION_CFG 0x0242 @@ -1669,6 +1741,9 @@ typedef MLAN_PACK_START struct _power_table_attr { #if defined(PCIE) #define HostCmd_CMD_SSU 0x0259 #endif +#define HostCmd_CMD_CSI 0x025b +#define CSI_CMD_ENABLE 0x0001 +#define CSI_CMD_DISABLE 0x0002 #define HostCmd_CMD_DMCS_CONFIG 0x0260 @@ -1989,12 +2064,15 @@ typedef enum _ENH_PS_MODES { #define EVENT_VDLL_IND 0x00000081 +#define EVENT_ROAM_OFFLOAD 0x00000083 + #define EVENT_EXCEED_MAX_P2P_CONN 0x00000089 #if defined(PCIE) #define EVENT_SSU_DUMP_DMA 0x0000008C #endif +#define EVENT_CSI 0x0000008D #define EVENT_FW_HANG_REPORT 0x0000008F /** Card Event definition : RESET PN */ @@ -2082,6 +2160,8 @@ typedef enum _tdls_error_code_e { TDLS_PEER_STA_UNREACHABLE = 25, } tdls_error_code_e; +#define RXPD_FLAG_EXTRA_HEADER (1 << 1) + /** Event_WEP_ICV_ERR structure */ typedef MLAN_PACK_START struct _Event_WEP_ICV_ERR { /** Reason code */ @@ -2159,6 +2239,8 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_TDLS_Idle_Timeout_t { /** Packet type: debugging */ #define PKT_TYPE_DEBUG 0xEF +#define PKT_TYPE_802DOT11_MC_AGGR 11 + /** channel number at bit 5-13 */ #define RXPD_CHAN_MASK 0x3FE0 /** Rate control mask 15-23 */ @@ -2175,43 +2257,6 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_TDLS_Idle_Timeout_t { #define TXPD_RETRY_ENABLE MBIT(12) /** tx_control*/ -#ifdef BIG_ENDIAN_SUPPORT -typedef MLAN_PACK_START struct _tx_ctrl { - /** reserved */ - t_u32 reserved : 3; - /** mc retry packet */ - t_u32 mc_pkt_retry : 1; - /** end of mc AMPDU */ - t_u32 mc_ampdu_end : 1; - /** start of mc AMPDU */ - t_u32 mc_ampdu_start : 1; - /** End of mc cycle */ - t_u32 mc_cycle_end : 1; - /** start of mc cycle */ - t_u32 mc_cycle_start : 1; - /** bw 0-20MHz, 1-40MHz */ - t_u32 bw : 3; - /** Rate used for transmission MCS0-7*/ - t_u32 tx_rate : 5; - /** Control the use of txRate. 0 - use FW setting, 1 - use the specified - * txRate;*/ - t_u32 host_txrate_ctrl : 1; - /** 0/1 - use FW setting, 2 - ACK_IMMD, 3 - NO_ACK.*/ - t_u32 ack_policy : 2; - /** Control the use of retryLimit. 0 - use FW setting, 1 - use the - * specified retryLimit.*/ - t_u32 host_retry_ctrl : 1; - /** retry limit */ - t_u32 retry_limit : 4; - /** Control the use of txPower. 0 - use FW power setting, 1 - use the - * specified txPower.*/ - t_u32 host_tx_powerctrl : 1; - /** Sign of the txPower, 0 - positive_sign(+), 1 - negative_sign(-). */ - t_u32 tx_power_sign : 1; - /** Power used for transmission(in dBm); */ - t_u32 tx_power : 6; -} MLAN_PACK_END tx_ctrl; -#else typedef MLAN_PACK_START struct _tx_ctrl { /** Power used for transmission(in dBm); */ t_u32 tx_power : 6; @@ -2247,7 +2292,14 @@ typedef MLAN_PACK_START struct _tx_ctrl { /** reserved */ t_u32 reserved : 3; } MLAN_PACK_END tx_ctrl; -#endif + +/** mc tx ctrl */ +typedef MLAN_PACK_START struct _mc_tx_ctrl { + /** mc seq */ + t_u16 mc_seq; + /** abs_tsf_expirytime*/ + t_u32 abs_tsf_expirytime; +} MLAN_PACK_END mc_tx_ctrl; /** TxPD descriptor */ typedef MLAN_PACK_START struct _TxPD { @@ -2322,32 +2374,6 @@ typedef MLAN_PACK_START struct _RxPD { } MLAN_PACK_END RxPD, *PRxPD; /** IEEEtypes_FrameCtl_t*/ -#ifdef BIG_ENDIAN_SUPPORT -typedef MLAN_PACK_START struct _IEEEtypes_FrameCtl_t { - /** Order */ - t_u8 order : 1; - /** Wep */ - t_u8 wep : 1; - /** More Data */ - t_u8 more_data : 1; - /** Power Mgmt */ - t_u8 pwr_mgmt : 1; - /** Retry */ - t_u8 retry : 1; - /** More Frag */ - t_u8 more_frag : 1; - /** From DS */ - t_u8 from_ds : 1; - /** To DS */ - t_u8 to_ds : 1; - /** Sub Type */ - t_u8 sub_type : 4; - /** Type */ - t_u8 type : 2; - /** Protocol Version */ - t_u8 protocol_version : 2; -} MLAN_PACK_END IEEEtypes_FrameCtl_t; -#else typedef MLAN_PACK_START struct _IEEEtypes_FrameCtl_t { /** Protocol Version */ t_u8 protocol_version : 2; @@ -2372,7 +2398,6 @@ typedef MLAN_PACK_START struct _IEEEtypes_FrameCtl_t { /** Order */ t_u8 order : 1; } MLAN_PACK_END IEEEtypes_FrameCtl_t; -#endif /** MrvlIETypes_MgmtFrameSet_t */ typedef MLAN_PACK_START struct _MrvlIETypes_MgmtFrameSet_t { @@ -2465,7 +2490,7 @@ typedef MLAN_PACK_START struct _chan_power_11d { /** 11D channel */ t_u8 chan; /** Band for channel */ - t_u8 band; + t_u16 band; /** 11D channel power */ t_u8 pwr; /** AP seen on channel */ @@ -2483,24 +2508,6 @@ typedef MLAN_PACK_START struct _parsed_region_chan_11d { /** ChanScanMode_t */ typedef MLAN_PACK_START struct _ChanScanMode_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Reserved */ - t_u8 reserved_7 : 1; - /** First passive scan then active scan */ - t_u8 passive_to_active_scan : 1; - /** First channel in scan */ - t_u8 first_chan : 1; - /** Enable hidden ssid report */ - t_u8 hidden_ssid_report : 1; - /** Enable probe response timeout */ - t_u8 rsp_timeout_en : 1; - /** Multidomain scan mode */ - t_u8 multidomain_scan : 1; - /** Disble channel filtering flag */ - t_u8 disable_chan_filt : 1; - /** Channel scan mode passive flag */ - t_u8 passive_scan : 1; -#else /** Channel scan mode passive flag */ t_u8 passive_scan : 1; /** Disble channel filtering flag */ @@ -2517,7 +2524,6 @@ typedef MLAN_PACK_START struct _ChanScanMode_t { t_u8 passive_to_active_scan : 1; /** Reserved */ t_u8 reserved_7 : 1; -#endif } MLAN_PACK_END ChanScanMode_t; /** ChanScanParamSet_t */ @@ -2974,50 +2980,24 @@ typedef MLAN_PACK_START struct _HostCmd_DS_GTK_REKEY_PARAMS { /** Data structure of WMM QoS information */ typedef MLAN_PACK_START struct _WmmQosInfo_t { -#ifdef BIG_ENDIAN_SUPPORT - /** QoS UAPSD */ - t_u8 qos_uapsd : 1; - /** Reserved */ - t_u8 reserved : 3; - /** Parameter set count */ - t_u8 para_set_count : 4; -#else /** Parameter set count */ t_u8 para_set_count : 4; /** Reserved */ t_u8 reserved : 3; /** QoS UAPSD */ t_u8 qos_uapsd : 1; -#endif /* BIG_ENDIAN_SUPPORT */ } MLAN_PACK_END WmmQosInfo_t, *pWmmQosInfo_t; /** Data structure of WMM ECW */ typedef MLAN_PACK_START struct _WmmEcw_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Maximum Ecw */ - t_u8 ecw_max : 4; - /** Minimum Ecw */ - t_u8 ecw_min : 4; -#else /** Minimum Ecw */ t_u8 ecw_min : 4; /** Maximum Ecw */ t_u8 ecw_max : 4; -#endif /* BIG_ENDIAN_SUPPORT */ } MLAN_PACK_END WmmEcw_t, *pWmmEcw_t; /** Data structure of WMM Aci/Aifsn */ typedef MLAN_PACK_START struct _WmmAciAifsn_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Reserved */ - t_u8 reserved : 1; - /** Aci */ - t_u8 aci : 2; - /** Acm */ - t_u8 acm : 1; - /** Aifsn */ - t_u8 aifsn : 4; -#else /** Aifsn */ t_u8 aifsn : 4; /** Acm */ @@ -3026,7 +3006,6 @@ typedef MLAN_PACK_START struct _WmmAciAifsn_t { t_u8 aci : 2; /** Reserved */ t_u8 reserved : 1; -#endif /* BIG_ENDIAN_SUPPORT */ } MLAN_PACK_END WmmAciAifsn_t, *pWmmAciAifsn_t; /** Data structure of WMM AC parameters */ @@ -3497,6 +3476,33 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_RSSI_EXT_t { t_s16 bcn_nf_avg; } MLAN_PACK_END MrvlIEtypes_RSSI_EXT_t; +/** HostCmd_DS_CMD_MC_AGGR_CFG */ +typedef MLAN_PACK_START struct _HostCmd_DS_MC_AGGR_CFG { + /** Action */ + t_u16 action; + /** Reserved field 1 */ + t_u16 reserved_1; + /* 1 enable, 0 disable + * bit 0 MC aggregation + * bit 1 packet expiry + * bit 2 CTS2Self + * bit 3 CTS2Self duration offset*/ + t_u8 enable_bitmap; + /* 1 valid, 0 invalid + * bit 0 MC aggregation + * bit 1 packet expiry + * bit 2 CTS2Self + * bit 3 CTS2Self duration offset*/ + t_u8 mask_bitmap; + /** CTS2Self duration offset */ + t_u16 cts2self_offset; +} MLAN_PACK_END HostCmd_DS_MC_AGGR_CFG; +typedef MLAN_PACK_START struct _HostCmd_DS_GET_CH_LOAD { + /** Action */ + t_u16 action; + t_u16 ch_load; +} MLAN_PACK_END HostCmd_DS_GET_CH_LOAD; + /** HostCmd_DS_CMD_802_11_RSSI_INFO */ typedef MLAN_PACK_START struct _HostCmd_DS_802_11_RSSI_INFO { /** Action */ @@ -3553,6 +3559,18 @@ typedef MLAN_PACK_START struct _HostCmd_DS_MAC_CONTROL { t_u32 action; } MLAN_PACK_END HostCmd_DS_MAC_CONTROL; +/** HostCmd_DS_802_11_NET_MONITOR */ +typedef MLAN_PACK_START struct _HostCmd_802_11_DS_NET_MONITOR { + /** Action */ + t_u16 action; + /** Enable/disable net monitor */ + t_u16 enable_net_mon; + /** set net monitor filer flag */ + t_u16 filter_flag; + /** Channel to monitor */ + MrvlIEtypes_ChanBandListParamSet_t monitor_chan; +} MLAN_PACK_END HostCmd_DS_802_11_NET_MONITOR; + /** HostCmd_DS_CMD_TX_DATA_PAUSE */ typedef MLAN_PACK_START struct _HostCmd_DS_CMD_TX_DATA_PAUSE { /** Action */ @@ -4246,6 +4264,22 @@ typedef MLAN_PACK_START struct _HostCmd_DS_SSU_CFG { } MLAN_PACK_END HostCmd_DS_SSU_CFG; #endif +/** HostCmd_CMD_CSI_START */ +typedef MLAN_PACK_START struct _HostCmd_DS_CSI_CFG { + /** Action */ + t_u16 action; + /** Header ID*/ + t_u32 head_id; + /** Tail ID */ + t_u32 tail_id; + /** Number of CSI filters */ + t_u8 csi_filter_cnt; + /** Chip ID */ + t_u8 chip_id; + /** CSI filters */ + mlan_csi_filter_t csi_filter[CSI_FILTER_MAX]; +} MLAN_PACK_END HostCmd_DS_CSI_CFG; + typedef MLAN_PACK_START struct _HostCmd_DS_HAL_PHY_CFG { /** Action */ t_u16 action; @@ -4271,6 +4305,8 @@ typedef enum _SNMP_MIB_INDEX { SignalextEnable_i = 41, ECSAEnable_i = 42, StopDeauth_i = 44, + Dot11H_fakeRadar = 45, + ChanTrackParam_i = 46, } SNMP_MIB_INDEX; /** max SNMP buf size */ @@ -5223,15 +5259,9 @@ typedef MLAN_PACK_START struct { */ typedef MLAN_PACK_START struct { mlan_wmm_queue_stats_action_e action; /**< Start, Stop, or Get */ -#ifdef BIG_ENDIAN_SUPPORT - t_u8 select_bin : 7; /**< WMM_AC_BK(0) to WMM_AC_VO(3), or TID */ - t_u8 select_is_userpri : 1; /**< Set if select_bin is UP, Clear for AC - */ -#else t_u8 select_is_userpri : 1; /**< Set if select_bin is UP, Clear for AC */ t_u8 select_bin : 7; /**< WMM_AC_BK(0) to WMM_AC_VO(3), or TID */ -#endif t_u16 pkt_count; /**< Number of successful packets transmitted */ t_u16 pkt_loss; /**< Packets lost; not included in pktCount */ t_u32 avg_queue_delay; /**< Average Queue delay in microsec */ @@ -5858,6 +5888,20 @@ typedef MLAN_PACK_START struct _HostCmd_DS_MEM_ACCESS { t_u32 value; } MLAN_PACK_END HostCmd_DS_MEM_ACCESS; +/** HostCmd_CMD_REG_ACCESS */ +typedef MLAN_PACK_START struct _HostCmd_DS_REG_ACCESS { + /** Action */ + t_u16 action; + /** reg type */ + t_u16 reg_type; + /** reserved */ + t_u16 reserved; + /** register offset */ + t_u16 offset; + /** register value */ + t_u32 value; +} MLAN_PACK_END HostCmd_DS_REG_ACCESS; + /** HostCmd_DS_TARGET_ACCESS */ typedef MLAN_PACK_START struct _HostCmd_DS_TARGET_ACCESS { /** Action */ @@ -6313,7 +6357,11 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_action_chan_switch_t { /** Header */ MrvlIEtypesHeader_t header; /* 0 send broadcast CSA action frame, 1 send unicast CSA action frame */ - t_u32 mode; + t_u8 mode; + /* number of frame */ + t_u8 num_pkt; + /** reserved */ + t_u16 reserved; /**ie buf*/ t_u8 ie_buf[]; } MLAN_PACK_END MrvlIEtypes_action_chan_switch_t; @@ -6408,6 +6456,10 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_auth_type_t { MrvlIEtypesHeader_t header; /** Authentication type */ t_u8 auth_type; + /** PWE derivation */ + t_u8 PWE_derivation; + /** transition disable */ + t_u8 transition_disable; } MLAN_PACK_END MrvlIEtypes_auth_type_t; /** MrvlIEtypes_encrypt_protocol_t */ @@ -6751,6 +6803,111 @@ typedef MLAN_PACK_START struct _HostCmd_DS_RX_PKT_COAL_CFG { } MLAN_PACK_END HostCmd_DS_RX_PKT_COAL_CFG; #endif +/** TLV buffer : firmware roam keys */ +typedef MLAN_PACK_START struct _MrvlIEtypes_keyParams_t { + /** Header */ + MrvlIEtypesHeader_t header; + /** Tlv buffer */ + t_u8 tlv_buffer[]; +} MLAN_PACK_END MrvlIEtypes_keyParams_t; + +/** TLV buffer : firmware roam enable */ +typedef MLAN_PACK_START struct _MrvlIEtypes_fw_roam_enable_t { + /** Header */ + MrvlIEtypesHeader_t header; + /** Enable */ + t_u8 roam_enable; + /** User set passphrase*/ + t_u8 userset_passphrase; +} MLAN_PACK_END MrvlIEtypes_fw_roam_enable_t; +/** HostCmd_DS_ROAM_OFFLOAD */ +typedef MLAN_PACK_START struct _HostCmd_DS_ROAM_OFFLOAD { + /** Action */ + t_u16 action; + /** tlv */ + t_u8 tlv[]; +} MLAN_PACK_END HostCmd_DS_ROAM_OFFLOAD; +/** HostCmd_DS_ROAM_OFFLOAD_APLIST */ +typedef MLAN_PACK_START struct _MrvlIEtypes_roam_aplist_t { + /** Header */ + MrvlIEtypesHeader_t header; + /** AP mac addrs**/ + t_u8 ap_mac[][MLAN_MAC_ADDR_LENGTH]; +} MLAN_PACK_END MrvlIEtypes_roam_aplist_t; +/** MrvlIEtypes_fw_roam_trigger_condition_t */ +typedef MLAN_PACK_START struct _MrvlIEtypes_fw_roam_trigger_condition_t { + /** Header */ + MrvlIEtypesHeader_t header; + /** Roam offload trigger condition**/ + t_u16 trigger_condition; +} MLAN_PACK_END MrvlIEtypes_fw_roam_trigger_condition_t; +/** MrvlIEtypes_fw_roam_retry_count_t */ +typedef MLAN_PACK_START struct _MrvlIEtypes_fw_roam_retry_count_t { + /** Header */ + MrvlIEtypesHeader_t header; + /** Roam offload retry count**/ + t_u16 retry_count; +} MLAN_PACK_END MrvlIEtypes_fw_roam_retry_count_t; +/** MrvlIEtypes_fw_roam_bgscan_setting_t */ +typedef MLAN_PACK_START struct _MrvlIEtypes_fw_roam_bgscan_setting_t { + /** Header */ + MrvlIEtypesHeader_t header; + /** Bss type of BG scan during fw roam**/ + t_u8 bss_type; + /** Number of channels scanned during each scan**/ + t_u8 channels_perscan; + /** Interval between consecutive scans**/ + t_u32 scan_interval; + /** Condition to trigger report to host**/ + t_u32 report_condition; +} MLAN_PACK_END MrvlIEtypes_fw_roam_bgscan_setting_t; +/** MrvlIEtypes_para_rssi_t */ +typedef MLAN_PACK_START struct _MrvlIEtypes_para_rssi_t { + /** Header */ + MrvlIEtypesHeader_t header; + /** Max value of RSSI threshold**/ + t_u8 max_rssi; + /** Min value of RSSI threshold**/ + t_u8 min_rssi; + /** Adjusting step value of RSSI threshold**/ + t_u8 step_rssi; +} MLAN_PACK_END MrvlIEtypes_para_rssi_t; +/** MrvlIEtypes_band_rssi_t */ +typedef MLAN_PACK_START struct _MrvlIEtypes_band_rssi_t { + /** Header */ + MrvlIEtypesHeader_t header; + /** BAND and RSSI gap*/ + mlan_ds_misc_band_rssi band_rssi; +} MLAN_PACK_END MrvlIEtypes_band_rssi_t; +/** MrvlIEtypes_ees_param_set_t */ +typedef MLAN_PACK_START struct _MrvlIEtypes_ees_param_set_t { + /** Header */ + MrvlIEtypesHeader_t header; + /** ees params*/ + mlan_ds_misc_ees_cfg ees_cfg; +} MLAN_PACK_END MrvlIEtypes_ees_param_set_t; +/** MrvlIEtypes_roam_blacklist_t */ +typedef MLAN_PACK_START struct _MrvlIEtypes_roam_blacklist_t { + /** Header */ + MrvlIEtypesHeader_t header; + /* Black list(BSSID list)*/ + mlan_ds_misc_roam_offload_aplist blacklist; +} MLAN_PACK_END MrvlIEtypes_roam_blacklist_t; +/** MrvlIEtypes_beacon_miss_threshold_t */ +typedef MLAN_PACK_START struct _MrvlIEtypes_beacon_miss_threshold_t { + /** Header */ + MrvlIEtypesHeader_t header; + /* Beacon miss threshold*/ + t_u8 bcn_miss_threshold; +} MLAN_PACK_END MrvlIEtypes_beacon_miss_threshold_t; +/** MrvlIEtypes_pre_beacon_miss_threshold_t */ +typedef MLAN_PACK_START struct _MrvlIEtypes_pre_beacon_miss_threshold_t { + /** Header */ + MrvlIEtypesHeader_t header; + /* Pre-Beacon miss threshold*/ + t_u8 pre_bcn_miss_threshold; +} MLAN_PACK_END MrvlIEtypes_pre_beacon_miss_threshold_t; + /** HostCmd_DS_DYN_BW */ typedef MLAN_PACK_START struct _HostCmd_DS_DYN_BW { /** Action */ @@ -6933,20 +7090,6 @@ typedef MLAN_PACK_START enum _MeasType_t { * @brief Mode octet of the measurement request element (7.3.2.21) */ typedef MLAN_PACK_START struct { -#ifdef BIG_ENDIAN_SUPPORT - /**< Reserved */ - t_u8 rsvd5_7 : 3; - /**< 11k: duration spec. for meas. is mandatory */ - t_u8 duration_mandatory : 1; - /**< 11h: en/disable report rcpt. of spec. type */ - t_u8 report : 1; - /**< 11h: en/disable requests of specified type */ - t_u8 request : 1; - /**< 11h: enable report/request bits */ - t_u8 enable : 1; - /**< 11k: series or parallel with previous meas */ - t_u8 parallel : 1; -#else /**< 11k: series or parallel with previous meas */ t_u8 parallel : 1; /**< 11h: enable report/request bits */ @@ -6959,7 +7102,6 @@ typedef MLAN_PACK_START struct { t_u8 duration_mandatory : 1; /**< Reserved */ t_u8 rsvd5_7 : 3; -#endif /* BIG_ENDIAN_SUPPORT */ } MLAN_PACK_END MeasReqMode_t; @@ -7004,17 +7146,10 @@ typedef union { * @brief Mode octet of the measurement report element (7.3.2.22) */ typedef MLAN_PACK_START struct { -#ifdef BIG_ENDIAN_SUPPORT - t_u8 rsvd3_7 : 5; /**< Reserved */ - t_u8 refused : 1; /**< Measurement refused */ - t_u8 incapable : 1; /**< Incapable of performing measurement */ - t_u8 late : 1; /**< Start TSF time missed for measurement */ -#else t_u8 late : 1; /**< Start TSF time missed for measurement */ t_u8 incapable : 1; /**< Incapable of performing measurement */ t_u8 refused : 1; /**< Measurement refused */ t_u8 rsvd3_7 : 5; /**< Reserved */ -#endif /* BIG_ENDIAN_SUPPORT */ } MLAN_PACK_END MeasRptMode_t; @@ -7146,6 +7281,15 @@ typedef MLAN_PACK_START struct { MeasRptBasicMap_t map; /**< IEEE 802.11h basic meas report */ } MLAN_PACK_END MrvlIEtypes_ChanRpt11hBasic_t; +/* MrvlIEtypes_ZeroDfsOperation_t */ +typedef MLAN_PACK_START struct { + /* header */ + MrvlIEtypesHeader_t Header; + /**< 0-DFS Enable/Disable> */ + t_u8 zero_dfs_enbl; + +} MLAN_PACK_END MrvlIEtypes_ZeroDfsOperation_t; + /* MrvlIEtypes_DfsW53Cfg_t*/ typedef MLAN_PACK_START struct { /* header */ @@ -7154,6 +7298,16 @@ typedef MLAN_PACK_START struct { t_u8 dfs53cfg; } MLAN_PACK_END MrvlIEtypes_DfsW53Cfg_t; +/* MrvlIEtypes_Rgn_dom_code_t*/ +typedef MLAN_PACK_START struct { + /* header */ + MrvlIEtypesHeader_t header; + /** Domain Code */ + t_u8 domain_code; + /** Reserved field */ + t_u8 reserved; +} MLAN_PACK_END MrvlIEtypes_Rgn_dom_code_t; + typedef MLAN_PACK_START struct { MrvlChannelDesc_t chan_desc; /**< Channel band, number */ t_u32 millisec_dwell_time; /**< Channel dwell time in milliseconds */ @@ -7736,6 +7890,8 @@ typedef struct MLAN_PACK_START _HostCmd_DS_COMMAND { HostCmd_DS_TARGET_ACCESS target; /** BCA register access */ HostCmd_DS_BCA_REG_ACCESS bca_reg; + /** register access */ + HostCmd_DS_REG_ACCESS reg; /** Inactivity timeout extend */ HostCmd_DS_INACTIVITY_TIMEOUT_EXT inactivity_to; #ifdef UAP_SUPPORT @@ -7760,6 +7916,7 @@ typedef struct MLAN_PACK_START _HostCmd_DS_COMMAND { HostCmd_DS_SDIO_PULL_CTRL sdio_pull_ctl; #endif HostCmd_DS_SET_BSS_MODE bss_mode; + HostCmd_DS_802_11_NET_MONITOR net_mon; HostCmd_DS_CMD_TX_DATA_PAUSE tx_data_pause; #if defined(PCIE) #if defined(PCIE8997) || defined(PCIE8897) @@ -7795,6 +7952,7 @@ typedef struct MLAN_PACK_START _HostCmd_DS_COMMAND { /** GPIO Independent reset configure */ HostCmd_DS_INDEPENDENT_RESET_CFG ind_rst_cfg; HostCmd_DS_802_11_PS_INACTIVITY_TIMEOUT ps_inact_tmo; + HostCmd_DS_ROAM_OFFLOAD roam_offload; HostCmd_DS_CHAN_REGION_CFG reg_cfg; HostCmd_DS_AUTO_TX auto_tx; HostCmd_DS_DYN_BW dyn_bw; @@ -7803,6 +7961,7 @@ typedef struct MLAN_PACK_START _HostCmd_DS_COMMAND { #if defined(PCIE) HostCmd_DS_SSU_CFG ssu_params; #endif + HostCmd_DS_CSI_CFG csi_params; /** boot sleep configure */ HostCmd_DS_BOOT_SLEEP boot_sleep; #if defined(DRV_EMBEDDED_AUTHENTICATOR) || defined(DRV_EMBEDDED_SUPPLICANT) @@ -7839,6 +7998,8 @@ typedef struct MLAN_PACK_START _HostCmd_DS_COMMAND { HostCmd_DS_CMD_DOT11MC_UNASSOC_FTM_CFG dot11mc_unassoc_ftm_cfg; HostCmd_DS_HAL_PHY_CFG hal_phy_cfg_params; HostCmd_DS_IPS_CONFIG ips_cfg; + HostCmd_DS_MC_AGGR_CFG mc_aggr_cfg; + HostCmd_DS_GET_CH_LOAD ch_load; } params; } MLAN_PACK_END HostCmd_DS_COMMAND, *pHostCmd_DS_COMMAND; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_ieee.h b/mxm_wifiex/wlan_src/mlan/mlan_ieee.h index 500ee3e..743d789 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_ieee.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_ieee.h @@ -4,7 +4,7 @@ * definitions used in MLAN and MOAL module. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -46,17 +46,10 @@ typedef enum _WLAN_802_11_NETWORK_TYPE { Wlan802_11NetworkTypeMax } WLAN_802_11_NETWORK_TYPE; -#ifdef BIG_ENDIAN_SUPPORT -/** Frame control: Type Mgmt frame */ -#define IEEE80211_FC_MGMT_FRAME_TYPE_MASK 0x3000 -/** Frame control: SubType Mgmt frame */ -#define IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE(fc) (((fc)&0xF000) >> 12) -#else /** Frame control: Type Mgmt frame */ #define IEEE80211_FC_MGMT_FRAME_TYPE_MASK 0x000C /** Frame control: SubType Mgmt frame */ #define IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE(fc) (((fc)&0x00F0) >> 4) -#endif #ifdef PRAGMA_PACK #pragma pack(push, 1) @@ -67,7 +60,8 @@ typedef enum _WLAN_802_11_NETWORK_TYPE { typedef enum _IEEEtypes_Ext_ElementId_e { HE_CAPABILITY = 35, - HE_OPERATION = 36 + HE_OPERATION = 36, + HE_6G_CAPABILITY = 59 } IEEEtypes_Ext_ElementId_e; /** IEEE Type definitions */ @@ -178,21 +172,12 @@ typedef MLAN_PACK_START struct _IEEEtypes_Generic_t { /**ft capability policy*/ typedef MLAN_PACK_START struct _IEEEtypes_FtCapPolicy_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Reserved */ - t_u8 reserved : 6; - /** RIC support */ - t_u8 ric : 1; - /** FT over the DS capable */ - t_u8 ft_over_ds : 1; -#else /** FT over the DS capable */ t_u8 ft_over_ds : 1; /** RIC support */ t_u8 ric : 1; /** Reserved */ t_u8 reserved : 6; -#endif } MLAN_PACK_END IEEEtypes_FtCapPolicy_t; /** Mobility domain IE */ @@ -325,25 +310,6 @@ typedef MLAN_PACK_START struct _TLV_Generic_t { #define CAPINFO_MASK (~(MBIT(15) | MBIT(14) | MBIT(11) | MBIT(9))) /** Capability Bit Map*/ -#ifdef BIG_ENDIAN_SUPPORT -typedef MLAN_PACK_START struct _IEEEtypes_CapInfo_t { - t_u8 rsrvd1 : 2; - t_u8 dsss_ofdm : 1; - t_u8 radio_measurement : 1; - t_u8 rsvrd2 : 1; - t_u8 short_slot_time : 1; - t_u8 rsrvd3 : 1; - t_u8 spectrum_mgmt : 1; - t_u8 chan_agility : 1; - t_u8 pbcc : 1; - t_u8 short_preamble : 1; - t_u8 privacy : 1; - t_u8 cf_poll_rqst : 1; - t_u8 cf_pollable : 1; - t_u8 ibss : 1; - t_u8 ess : 1; -} MLAN_PACK_END IEEEtypes_CapInfo_t, *pIEEEtypes_CapInfo_t; -#else typedef MLAN_PACK_START struct _IEEEtypes_CapInfo_t { /** Capability Bit Map : ESS */ t_u8 ess : 1; @@ -376,7 +342,6 @@ typedef MLAN_PACK_START struct _IEEEtypes_CapInfo_t { /** Capability Bit Map : Reserved */ t_u8 rsrvd1 : 2; } MLAN_PACK_END IEEEtypes_CapInfo_t, *pIEEEtypes_CapInfo_t; -#endif /* BIG_ENDIAN_SUPPORT */ /** IEEEtypes_Ssid_t */ typedef MLAN_PACK_START struct _IEEEtypes_Ssid_t { @@ -591,35 +556,16 @@ typedef MLAN_PACK_START struct _IEEEtypes_Wpa_t { /** Data structure of WMM QoS information */ typedef MLAN_PACK_START struct _IEEEtypes_WmmQosInfo_t { -#ifdef BIG_ENDIAN_SUPPORT - /** QoS UAPSD */ - t_u8 qos_uapsd : 1; - /** Reserved */ - t_u8 reserved : 3; - /** Parameter set count */ - t_u8 para_set_count : 4; -#else /** Parameter set count */ t_u8 para_set_count : 4; /** Reserved */ t_u8 reserved : 3; /** QoS UAPSD */ t_u8 qos_uapsd : 1; -#endif /* BIG_ENDIAN_SUPPORT */ } MLAN_PACK_END IEEEtypes_WmmQosInfo_t, *pIEEEtypes_WmmQosInfo_t; /** Data structure of WMM Aci/Aifsn */ typedef MLAN_PACK_START struct _IEEEtypes_WmmAciAifsn_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Reserved */ - t_u8 reserved : 1; - /** Aci */ - t_u8 aci : 2; - /** Acm */ - t_u8 acm : 1; - /** Aifsn */ - t_u8 aifsn : 4; -#else /** Aifsn */ t_u8 aifsn : 4; /** Acm */ @@ -628,22 +574,14 @@ typedef MLAN_PACK_START struct _IEEEtypes_WmmAciAifsn_t { t_u8 aci : 2; /** Reserved */ t_u8 reserved : 1; -#endif /* BIG_ENDIAN_SUPPORT */ } MLAN_PACK_END IEEEtypes_WmmAciAifsn_t, *pIEEEtypes_WmmAciAifsn_t; /** Data structure of WMM ECW */ typedef MLAN_PACK_START struct _IEEEtypes_WmmEcw_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Maximum Ecw */ - t_u8 ecw_max : 4; - /** Minimum Ecw */ - t_u8 ecw_min : 4; -#else /** Minimum Ecw */ t_u8 ecw_min : 4; /** Maximum Ecw */ t_u8 ecw_max : 4; -#endif /* BIG_ENDIAN_SUPPORT */ } MLAN_PACK_END IEEEtypes_WmmEcw_t, *pIEEEtypes_WmmEcw_t; /** Data structure of WMM AC parameters */ @@ -731,22 +669,6 @@ typedef MLAN_PACK_START enum _IEEEtypes_WMM_TSPEC_TS_TRAFFIC_TYPE_e { /** Data structure of WMM TSPEC information */ typedef MLAN_PACK_START struct { -#ifdef BIG_ENDIAN_SUPPORT - t_u8 Reserved17_23 : 7; /* ! Reserved */ - t_u8 Schedule : 1; - IEEEtypes_WMM_TSPEC_TS_Info_AckPolicy_e AckPolicy : 2; - t_u8 UserPri : 3; /* ! 802.1d User Priority */ - // IEEEtypes_WMM_TSPEC_TS_Info_PSB_e PowerSaveBehavior : 1; /* - // !Legacy/Trigg*/ - t_u8 PowerSaveBehavior : 1; - t_u8 Aggregation : 1; /* ! Reserved */ - t_u8 AccessPolicy2 : 1; /* ! */ - t_u8 AccessPolicy1 : 1; /* ! */ - IEEEtypes_WMM_TSPEC_TS_Info_Direction_e Direction : 2; - t_u8 TID : 4; /* ! Unique identifier */ - // IEEEtypes_WMM_TSPEC_TS_TRAFFIC_TYPE_e TrafficType : 1; - t_u8 TrafficType : 1; -#else // IEEEtypes_WMM_TSPEC_TS_TRAFFIC_TYPE_e TrafficType : 1; t_u8 TrafficType : 1; t_u8 TID : 4; /* ! Unique identifier */ @@ -761,31 +683,19 @@ typedef MLAN_PACK_START struct { IEEEtypes_WMM_TSPEC_TS_Info_AckPolicy_e AckPolicy : 2; t_u8 Schedule : 1; t_u8 Reserved17_23 : 7; /* ! Reserved */ -#endif } MLAN_PACK_END IEEEtypes_WMM_TSPEC_TS_Info_t; /** Data structure of WMM TSPEC Nominal Size */ typedef MLAN_PACK_START struct { -#ifdef BIG_ENDIAN_SUPPORT - t_u16 Fixed : 1; /* ! 1: Fixed size given in Size, 0: Var, size is - nominal */ - t_u16 Size : 15; /* ! Nominal size in octets */ -#else t_u16 Size : 15; /* ! Nominal size in octets */ t_u16 Fixed : 1; /* ! 1: Fixed size given in Size, 0: Var, size is nominal */ -#endif } MLAN_PACK_END IEEEtypes_WMM_TSPEC_NomMSDUSize_t; /** Data structure of WMM TSPEC SBWA */ typedef MLAN_PACK_START struct { -#ifdef BIG_ENDIAN_SUPPORT - t_u16 Whole : 3; /* ! Whole portion */ - t_u16 Fractional : 13; /* ! Fractional portion */ -#else t_u16 Fractional : 13; /* ! Fractional portion */ t_u16 Whole : 3; /* ! Whole portion */ -#endif } MLAN_PACK_END IEEEtypes_WMM_TSPEC_SBWA; /** Data structure of WMM TSPEC Body */ @@ -1126,26 +1036,6 @@ typedef MLAN_PACK_START struct _VHT_MCS_set { /** VHT Capabilities info field, reference 802.11ac D1.4 p89 */ typedef MLAN_PACK_START struct _VHT_capa { #if 0 -#ifdef BIG_ENDIAN_SUPPORT - t_u8 mpdu_max_len:2; - t_u8 chan_width:2; - t_u8 rx_LDPC:1; - t_u8 sgi_80:1; - t_u8 sgi_160:1; - t_u8 tx_STBC:1; - t_u8 rx_STBC:3; - t_u8 SU_beamformer_capa:1; - t_u8 SU_beamformee_capa:1; - t_u8 beamformer_ante_num:3; - t_u8 sounding_dim_num:3; - t_u8 MU_beamformer_capa:1; - t_u8 MU_beamformee_capa:1; - t_u8 VHT_TXOP_ps:1; - t_u8 HTC_VHT_capa:1; - t_u8 max_ampdu_len:3; - t_u8 link_apapt_capa:2; - t_u8 reserved_1:4; -#else t_u8 reserved_1:4; t_u8 link_apapt_capa:2; t_u8 max_ampdu_len:3; @@ -1164,7 +1054,6 @@ typedef MLAN_PACK_START struct _VHT_capa { t_u8 rx_LDPC:1; t_u8 chan_width:2; t_u8 mpdu_max_len:2; -#endif /* BIG_ENDIAN_SUPPORT */ #endif t_u32 vht_cap_info; VHT_MCS_set_t mcs_sets; @@ -1272,6 +1161,32 @@ typedef MLAN_PACK_START struct _IEEEtypes_Extension_t { t_u8 data[]; } MLAN_PACK_END IEEEtypes_Extension_t, *pIEEEtypes_Extension_t; +typedef MLAN_PACK_START struct _IEEEtypes_HeMcsMap_t { + /** Max HE-MAC for 1 SS */ + t_u8 max_mcs_1ss : 2; + /** Max HE-MAC for 2 SS */ + t_u8 max_mcs_2ss : 2; + /** Max HE-MAC for 3 SS */ + t_u8 max_mcs_3ss : 2; + /** Max HE-MAC for 4 SS */ + t_u8 max_mcs_4ss : 2; + /** Max HE-MAC for 5 SS */ + t_u8 max_mcs_5ss : 2; + /** Max HE-MAC for 6 SS */ + t_u8 max_mcs_6ss : 2; + /** Max HE-MAC for 7 SS */ + t_u8 max_mcs_7ss : 2; + /** Max HE-MAC for 8 SS */ + t_u8 max_mcs_8ss : 2; +} MLAN_PACK_END IEEEtypes_HeMcsMap_t, *pIEEEtypes_HeMcsMap_t; + +typedef MLAN_PACK_START struct _IEEEtypes_HeMcsNss_t { + /** HE Rx MCS and NSS Set */ + t_u16 rx_mcs; + /** HE Tx MCS and NSS Set*/ + t_u16 tx_mcs; +} MLAN_PACK_END IEEEtypes_HeMcsNss_t, *pIEEEtypes_HeMcsNss_t; + typedef MLAN_PACK_START struct _IEEEtypes_HECap_t { /** Generic IE header */ IEEEtypes_Header_t ieee_hdr; @@ -1281,11 +1196,55 @@ typedef MLAN_PACK_START struct _IEEEtypes_HECap_t { t_u8 he_mac_cap[6]; /** he phy capability info */ t_u8 he_phy_cap[11]; - /** he txrx mcs support , size would be 4 or 8 or 12 */ + /** he txrx mcs support (for 80 MHz) */ t_u8 he_txrx_mcs_support[4]; - /** PPE Thresholds (optional) */ + /** Optional Field, including he_txrx_mcs_support for 160 and 80+80 MHz, + * and PPE Thresholds */ + t_u8 option[28]; } MLAN_PACK_END IEEEtypes_HECap_t, *pIEEEtypes_HECap_t; +typedef MLAN_PACK_START struct _IEEEtypes_HeOpParam_t { + /** Default PE Duration */ + t_u16 default_pe_dur : 3; /* bit 0-2 */ + /** TWT Required */ + t_u16 twt_req : 1; /* bit 3 */ + /** TXOP Duration RTS Threshold */ + t_u16 txop_dur_rts_threshold : 10; /* bit 4-13 */ + /** VHT Operation Info Present */ + t_u16 vht_op_info_present : 1; /* bit 14 */ + /** Co-Hosted BSS */ + t_u16 co_located_bss : 1; /* bit 15 */ + /** ER SU Disable */ + t_u8 er_su_disable : 1; /* bit 16 */ + /** Reserved, including 6G Operation Info Pressent (bit17) */ + t_u8 reserved : 7; /* bit 17-23 */ +} MLAN_PACK_END IEEEtypes_HeOpParam_t; + +typedef MLAN_PACK_START struct _IEEEtypes_HeBssColorInfo_t { + /** BSS Color */ + t_u8 bss_color : 6; /* bit 0-5 */ + /** Partial BSS Color */ + t_u8 partial_bss_color : 1; /* bit 6 */ + /** BSS Color Disabled */ + t_u8 bss_color_disabled : 1; /* bit 7 */ +} MLAN_PACK_END IEEEtypes_HeBssColorInfo_t; + +typedef MLAN_PACK_START struct _IEEEtypes_HeOp_t { + /** Generic IE header */ + IEEEtypes_Header_t ieee_hdr; + /** Element id extension */ + t_u8 ext_id; + /** HE Operation Parameters */ + IEEEtypes_HeOpParam_t he_op_param; + /** BSS Color Info */ + IEEEtypes_HeBssColorInfo_t bss_color_info; + /** Basic HE-MCS and NSS Set */ + IEEEtypes_HeMcsMap_t basic_he_mcs_nss; + /** Optional Field, including VHT Operation Info Max Co-Hosted BSSID + * Indicator, and 6Ghz Operation Info */ + t_u8 option[9]; +} MLAN_PACK_END IEEEtypes_HeOp_t; + /** default channel switch count */ #define DEF_CHAN_SWITCH_COUNT 5 @@ -1321,7 +1280,7 @@ typedef MLAN_PACK_START struct { } MLAN_PACK_END IEEEtypes_ExtChanSwitchAnn_t; /** Maximum number of subbands in the IEEEtypes_SupportedChannels_t structure */ -#define WLAN_11H_MAX_SUBBANDS 5 +#define WLAN_11H_MAX_SUBBANDS 6 /** Maximum number of DFS channels configured in IEEEtypes_IBSS_DFS_t */ #define WLAN_11H_MAX_IBSS_DFS_CHANNELS 25 @@ -1429,20 +1388,6 @@ typedef MLAN_PACK_START struct { *** @brief Map octet of the basic measurement report (7.3.2.22.1) **/ typedef MLAN_PACK_START struct { -#ifdef BIG_ENDIAN_SUPPORT - /**< Reserved */ - t_u8 rsvd5_7 : 3; - /**< Channel is unmeasured */ - t_u8 unmeasured : 1; - /**< Radar detected on channel */ - t_u8 radar : 1; - /**< Unidentified signal found on channel */ - t_u8 unidentified_sig : 1; - /**< OFDM preamble detected on channel */ - t_u8 ofdm_preamble : 1; - /**< At least one valid MPDU received on channel */ - t_u8 bss : 1; -#else /**< At least one valid MPDU received on channel */ t_u8 bss : 1; /**< OFDM preamble detected on channel */ @@ -1455,7 +1400,6 @@ typedef MLAN_PACK_START struct { t_u8 unmeasured : 1; /**< Reserved */ t_u8 rsvd5_7 : 3; -#endif /* BIG_ENDIAN_SUPPORT */ } MLAN_PACK_END MeasRptBasicMap_t; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_init.c b/mxm_wifiex/wlan_src/mlan/mlan_init.c index 15f6406..6f90aae 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_init.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_init.c @@ -240,9 +240,10 @@ mlan_status wlan_allocate_adapter(pmlan_adapter pmadapter) t_u32 buf_size; BSSDescriptor_t *ptemp_scan_table = MNULL; t_u8 chan_2g[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; - t_u8 chan_5g[] = {12, 16, 34, 38, 42, 46, 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}; + t_u8 chan_5g[] = {12, 16, 34, 38, 42, 46, 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, 169, 173, 177}; #endif #ifdef SDIO t_u32 max_mp_regs = 0; @@ -603,6 +604,7 @@ mlan_status wlan_init_priv(pmlan_private priv) priv->hotspot_cfg = 0; priv->intf_hr_len = pmadapter->ops.intf_header_len; + memset(pmadapter, &priv->chan_rep_req, 0, sizeof(priv->chan_rep_req)); #ifdef USB if (IS_USB(pmadapter->card_type)) { pusb_tx_aggr = @@ -722,6 +724,8 @@ t_void wlan_init_adapter(pmlan_adapter pmadapter) pmadapter->last_init_cmd = 0; pmadapter->pending_ioctl = MFALSE; pmadapter->scan_processing = MFALSE; + pmadapter->fw_roaming = MFALSE; + pmadapter->userset_passphrase = MFALSE; pmadapter->cmd_timer_is_set = MFALSE; pmadapter->dnld_cmd_in_secs = 0; @@ -957,7 +961,7 @@ t_void wlan_init_adapter(pmlan_adapter pmadapter) EVT_RW_PTR_ROLLOVER_IND; } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { pmadapter->pcard_pcie->rxbd_wrptr = pmadapter->pcard_pcie->txrx_bd_size; @@ -1154,7 +1158,10 @@ mlan_status wlan_init_lock_list(pmlan_adapter pmadapter) util_init_list_head((t_void *)pmadapter->pmoal_handle, &pmadapter->scan_pending_q, MTRUE, pmadapter->callbacks.moal_init_lock); - + /* Initialize ext_cmd_pending_q */ + util_init_list_head((t_void *)pmadapter->pmoal_handle, + &pmadapter->ext_cmd_pending_q, MTRUE, + pmadapter->callbacks.moal_init_lock); /* Initialize ioctl_pending_q */ util_init_list_head((t_void *)pmadapter->pmoal_handle, &pmadapter->ioctl_pending_q, MTRUE, @@ -1246,6 +1253,10 @@ t_void wlan_free_lock_list(pmlan_adapter pmadapter) &pmadapter->scan_pending_q, pmadapter->callbacks.moal_free_lock); + util_free_list_head((t_void *)pmadapter->pmoal_handle, + &pmadapter->ext_cmd_pending_q, + pmadapter->callbacks.moal_free_lock); + util_free_list_head((t_void *)pmadapter->pmoal_handle, &pmadapter->ioctl_pending_q, pmadapter->callbacks.moal_free_lock); @@ -1896,7 +1907,9 @@ static mlan_status wlan_init_interface(pmlan_adapter pmadapter) pmadapter->priv[i]->bss_role = MLAN_BSS_ROLE_STA; else if (pmadapter->bss_attr[i].bss_type == - MLAN_BSS_TYPE_UAP) + MLAN_BSS_TYPE_UAP || + pmadapter->bss_attr[i].bss_type == + MLAN_BSS_TYPE_DFS) pmadapter->priv[i]->bss_role = MLAN_BSS_ROLE_UAP; #ifdef WIFI_DIRECT_SUPPORT diff --git a/mxm_wifiex/wlan_src/mlan/mlan_init.h b/mxm_wifiex/wlan_src/mlan/mlan_init.h index f8e1738..4a9022a 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_init.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_init.h @@ -4,7 +4,7 @@ * structures. * * - * Copyright 2008-2020 NXP + * Copyright 2008-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -104,22 +104,9 @@ typedef MLAN_PACK_START struct _FWSyncPkt { t_u32 fw_ready; } MLAN_PACK_END FWSyncPkt; -#ifdef BIG_ENDIAN_SUPPORT -/** Convert sequence number and command fields - * of fwheader to correct endian format - */ -#define endian_convert_syncfwheader(x) \ - { \ - (x)->cmd = wlan_le32_to_cpu((x)->cmd); \ - (x)->seq_num = wlan_le32_to_cpu((x)->seq_num); \ - (x)->status = wlan_le32_to_cpu((x)->status); \ - (x)->offset = wlan_le32_to_cpu((x)->offset); \ - } -#else /** Convert sequence number and command fields * of fwheader to correct endian format */ #define endian_convert_syncfwheader(x) -#endif /* BIG_ENDIAN_SUPPORT */ #endif /* _MLAN_INIT_H_ */ diff --git a/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h b/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h index 21139c3..7fbf073 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h @@ -3,7 +3,7 @@ * @brief This file declares the IOCTL data structures and APIs. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -110,6 +110,8 @@ enum _mlan_ioctl_req_id { MLAN_OID_SNMP_MIB_DTIM_PERIOD = 0x00040006, MLAN_OID_SNMP_MIB_SIGNALEXT_ENABLE = 0x00040007, MLAN_OID_SNMP_MIB_CTRL_DEAUTH = 0x00040008, + MLAN_OID_SNMP_MIB_DOT11H_FAKERADAR = 0x00040009, + MLAN_OID_SNMP_MIB_CHAN_TRACK = 0x0004000A, /* Status Information Group */ MLAN_IOCTL_GET_INFO = 0x00050000, @@ -232,6 +234,7 @@ enum _mlan_ioctl_req_id { MLAN_OID_11H_CHAN_REPORT_REQUEST = 0x00110004, MLAN_OID_11H_CHAN_SWITCH_COUNT = 0x00110005, MLAN_OID_11H_CHAN_NOP_INFO = 0x00110006, + MLAN_OID_11H_CHAN_DFS_STATE = 0x00110007, MLAN_OID_11H_DFS_W53_CFG = 0x00110008, /* 802.11n Configuration Group RANDYTODO for value assign */ @@ -262,6 +265,7 @@ enum _mlan_ioctl_req_id { MLAN_OID_MISC_INIT_SHUTDOWN = 0x0020000D, MLAN_OID_MISC_CUSTOM_IE = 0x0020000F, MLAN_OID_MISC_TDLS_CONFIG = 0x00200010, + MLAN_OID_MISC_NET_MONITOR = 0x00200011, MLAN_OID_MISC_TX_DATAPAUSE = 0x00200012, MLAN_OID_MISC_IP_ADDR = 0x00200013, MLAN_OID_MISC_MAC_CONTROL = 0x00200014, @@ -306,6 +310,8 @@ enum _mlan_ioctl_req_id { MLAN_OID_MISC_OPER_CLASS = 0x00200038, MLAN_OID_MISC_PMIC_CFG = 0x00200039, MLAN_OID_MISC_IND_RST_CFG = 0x00200040, + MLAN_OID_MISC_ROAM_OFFLOAD = 0x00200042, + MLAN_OID_MISC_ROAM_OFFLOAD_APLIST = 0x00200043, MLAN_OID_MISC_GET_TSF = 0x00200045, MLAN_OID_MISC_GET_CHAN_REGION_CFG = 0x00200046, MLAN_OID_MISC_CLOUD_KEEP_ALIVE = 0x00200048, @@ -324,6 +330,7 @@ enum _mlan_ioctl_req_id { #if defined(PCIE) MLAN_OID_MISC_SSU = 0x00200062, #endif + MLAN_OID_MISC_CSI = 0x00200064, MLAN_OID_MISC_DMCS_CONFIG = 0x00200065, MLAN_OID_MISC_RX_ABORT_CFG = 0x00200066, MLAN_OID_MISC_RX_ABORT_CFG_EXT = 0x00200067, @@ -351,6 +358,8 @@ enum _mlan_ioctl_req_id { MLAN_OID_MISC_GET_TSF_INFO = 0x00200083, MLAN_OID_MISC_ASSOC_REQ = 0x00200084, MLAN_OID_MISC_IPS_CFG = 0x00200085, + MLAN_OID_MISC_MC_AGGR_CFG = 0x00200086, + MLAN_OID_MISC_CH_LOAD = 0x00200087, }; /** Sub command size */ @@ -600,6 +609,8 @@ enum _mlan_bss_mode { /** Maximum key length */ #define MLAN_MAX_KEY_LENGTH 32 +/** Maximum PMK R0 NAME key length */ +#define MLAN_MAX_PMKR0_NAME_LENGTH 16 /** Maximum atim window in milliseconds */ #define MLAN_MAX_ATIM_WINDOW 50 @@ -632,7 +643,7 @@ typedef struct _mlan_multicast_list { } mlan_multicast_list, *pmlan_multicast_list; /** Max channel */ -#define MLAN_MAX_CHANNEL 165 +#define MLAN_MAX_CHANNEL 177 /** Maximum number of channels in table */ #define MLAN_MAX_CHANNEL_NUM 128 @@ -746,31 +757,14 @@ typedef struct _mlan_ssid_bssid { /** Data structure of WMM ECW */ typedef struct _wmm_ecw_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Maximum Ecw */ - t_u8 ecw_max : 4; - /** Minimum Ecw */ - t_u8 ecw_min : 4; -#else /** Minimum Ecw */ t_u8 ecw_min : 4; /** Maximum Ecw */ t_u8 ecw_max : 4; -#endif /* BIG_ENDIAN_SUPPORT */ } wmm_ecw_t, *pwmm_ecw_t; /** Data structure of WMM Aci/Aifsn */ typedef struct _wmm_aci_aifsn_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Reserved */ - t_u8 reserved : 1; - /** Aci */ - t_u8 aci : 2; - /** Acm */ - t_u8 acm : 1; - /** Aifsn */ - t_u8 aifsn : 4; -#else /** Aifsn */ t_u8 aifsn : 4; /** Acm */ @@ -779,7 +773,6 @@ typedef struct _wmm_aci_aifsn_t { t_u8 aci : 2; /** Reserved */ t_u8 reserved : 1; -#endif /* BIG_ENDIAN_SUPPORT */ } wmm_aci_aifsn_t, *pwmm_aci_aifsn_t; /** Data structure of WMM AC parameters */ @@ -986,21 +979,12 @@ typedef struct _wep_param { /** Data structure of WMM QoS information */ typedef struct _wmm_qos_info_t { -#ifdef BIG_ENDIAN_SUPPORT - /** QoS UAPSD */ - t_u8 qos_uapsd : 1; - /** Reserved */ - t_u8 reserved : 3; - /** Parameter set count */ - t_u8 para_set_count : 4; -#else /** Parameter set count */ t_u8 para_set_count : 4; /** Reserved */ t_u8 reserved : 3; /** QoS UAPSD */ t_u8 qos_uapsd : 1; -#endif /* BIG_ENDIAN_SUPPORT */ } wmm_qos_info_t, *pwmm_qos_info_t; /** Data structure of WMM parameter IE */ @@ -1086,6 +1070,10 @@ typedef struct _mlan_uap_bss_param { t_u8 channel; /** auth mode */ t_u16 auth_mode; + /** PWE derivation */ + t_u8 pwe_derivation; + /** transition disable */ + t_u8 transition_disable; /** encryption protocol */ t_u16 protocol; /** key managment type */ @@ -1144,6 +1132,8 @@ typedef struct _mlan_uap_scan_channels { scan_chan_list chan_list[MLAN_MAX_CHANNEL]; } mlan_uap_scan_channels; +#define MAX_NUM_PKTS 9 +#define DEF_NUM_PKTS 3 /** mlan_chan_switch_param */ typedef struct _mlan_action_chan_switch { /** mode*/ @@ -1335,7 +1325,6 @@ enum _mlan_band_def { BAND_AAC = 64, BAND_GAX = 256, BAND_AAX = 512, - }; /** Channel bandwidth */ @@ -1482,6 +1471,7 @@ typedef struct _mlan_ds_snmp_mib { t_u8 signalext_enable; /** Control deauth when uap switch channel */ t_u8 deauthctrl; + t_u8 chan_track; } param; } mlan_ds_snmp_mib, *pmlan_ds_snmp_mib; @@ -1882,6 +1872,8 @@ typedef struct _mlan_fw_info { t_u8 antinfo; /** max AP associated sta count supported by fw */ t_u8 max_ap_assoc_sta; + /** FW support roaming offload */ + t_u8 fw_roaming_support; /** Bandwidth not support 80Mhz */ t_u8 prohibit_80mhz; /** FW support beacon protection */ @@ -1899,100 +1891,6 @@ typedef struct _mlan_ver_ext { char version_str[MLAN_MAX_VER_STR_LEN]; } mlan_ver_ext, *pmlan_ver_ext; -#ifdef BIG_ENDIAN_SUPPORT -/** Extended Capabilities Data */ -typedef struct MLAN_PACK_START _ExtCap_t { - /** Extended Capabilities value */ - t_u8 rsvdBit87 : 1; /* bit 87 */ - t_u8 rsvdBit86 : 1; /* bit 86 */ - t_u8 rsvdBit85 : 1; /* bit 85 */ - t_u8 beacon_prot : 1; /* bit 84 */ - t_u8 rsvdBit83 : 1; /* bit 83 */ - t_u8 rsvdBit82 : 1; /* bit 82 */ - t_u8 rsvdBit81 : 1; /* bit 81 */ - t_u8 rsvdBit80 : 1; /* bit 80 */ - t_u8 rsvdBit79 : 1; /* bit 79 */ - t_u8 TWTResp : 1; /* bit 78 */ - t_u8 TWTReq : 1; /* bit 77 */ - t_u8 rsvdBit76 : 1; /* bit 76 */ - t_u8 rsvdBit75 : 1; /* bit 75 */ - t_u8 rsvdBit74 : 1; /* bit 74 */ - t_u8 rsvdBit73 : 1; /* bit 73 */ - t_u8 FILS : 1; /* bit 72 */ - t_u8 FTMI : 1; /* bit 71 */ - t_u8 FTMR : 1; /* bit 70 */ - t_u8 CAQ : 1; /* bit 69 */ - t_u8 rsvdBit68 : 1; /* bit 68 */ - t_u8 NCC : 1; /* bit 67 */ - t_u8 rsvdBit66 : 1; /* bit 66 */ - t_u8 chanSchedMgnt : 1; /* bit 65 */ - t_u8 MaxAMSDU1 : 1; /* bit 64 */ - t_u8 MaxAMSDU0 : 1; /* bit 63 */ - t_u8 OperModeNtf : 1; /* bit 62 */ - t_u8 TDLSWildBandwidth : 1; /* bit 61 */ - t_u8 rsvdBit60 : 1; /* bit 60 */ - t_u8 rsvdBit59 : 1; /* bit 59 */ - t_u8 rsvdBit58 : 1; /* bit 58 */ - t_u8 rsvdBit57 : 1; /* bit 57 */ - t_u8 rsvdBit56 : 1; /* bit 56 */ - t_u8 rsvdBit55 : 1; /* bit 55 */ - t_u8 rsvdBit54 : 1; /* bit 54 */ - t_u8 rsvdBit53 : 1; /* bit 53 */ - t_u8 rsvdBit52 : 1; /* bit 52 */ - t_u8 rsvdBit51 : 1; /* bit 51 */ - t_u8 rsvdBit50 : 1; /* bit 50 */ - t_u8 rsvdBit49 : 1; /* bit 49 */ - t_u8 rsvdBit48 : 1; /* bit 48 */ - t_u8 rsvdBit47 : 1; /* bit 47 */ - t_u8 rsvdBit46 : 1; /* bit 46 */ - t_u8 rsvdBit45 : 1; /* bit 45 */ - t_u8 rsvdBit44 : 1; /* bit 44 */ - t_u8 rsvdBit43 : 1; /* bit 43 */ - t_u8 rsvdBit42 : 1; /* bit 42 */ - t_u8 rsvdBit41 : 1; /* bit 41 */ - t_u8 rsvdBit40 : 1; /* bit 40 */ - t_u8 TDLSChlSwitchProhib : 1; /* bit 39 */ - t_u8 TDLSProhibited : 1; /* bit 38 */ - t_u8 TDLSSupport : 1; /* bit 37 */ - t_u8 MSGCF_Capa : 1; /* bit 36 */ - t_u8 Reserved35 : 1; /* bit 35 */ - t_u8 SSPN_Interface : 1; /* bit 34 */ - t_u8 EBR : 1; /* bit 33 */ - t_u8 Qos_Map : 1; /* bit 32 */ - t_u8 Interworking : 1; /* bit 31 */ - t_u8 TDLSChannelSwitching : 1; /* bit 30 */ - t_u8 TDLSPeerPSMSupport : 1; /* bit 29 */ - t_u8 TDLSPeerUAPSDSupport : 1; /* bit 28 */ - t_u8 UTC : 1; /* bit 27 */ - t_u8 DMS : 1; /* bit 26 */ - t_u8 SSID_List : 1; /* bit 25 */ - t_u8 ChannelUsage : 1; /* bit 24 */ - t_u8 TimingMeasurement : 1; /* bit 23 */ - t_u8 MultipleBSSID : 1; /* bit 22 */ - t_u8 AC_StationCount : 1; /* bit 21 */ - t_u8 QoSTrafficCap : 1; /* bit 20 */ - t_u8 BSS_Transition : 1; /* bit 19 */ - t_u8 TIM_Broadcast : 1; /* bit 18 */ - t_u8 WNM_Sleep : 1; /* bit 17 */ - t_u8 TFS : 1; /* bit 16 */ - t_u8 GeospatialLocation : 1; /* bit 15 */ - t_u8 CivicLocation : 1; /* bit 14 */ - t_u8 CollocatedIntf : 1; /* bit 13 */ - t_u8 ProxyARPService : 1; /* bit 12 */ - t_u8 FMS : 1; /* bit 11 */ - t_u8 LocationTracking : 1; /* bit 10 */ - t_u8 MulticastDiagnostics : 1; /* bit 9 */ - t_u8 Diagnostics : 1; /* bit 8 */ - t_u8 Event : 1; /* bit 7 */ - t_u8 SPSMP_Support : 1; /* bit 6 */ - t_u8 Reserved5 : 1; /* bit 5 */ - t_u8 PSMP_Capable : 1; /* bit 4 */ - t_u8 RejectUnadmFrame : 1; /* bit 3 */ - t_u8 ExtChanSwitching : 1; /* bit 2 */ - t_u8 Reserved1 : 1; /* bit 1 */ - t_u8 BSS_CoexistSupport : 1; /* bit 0 */ -} MLAN_PACK_END ExtCap_t, *pExtCap_t; -#else /** Extended Capabilities Data */ typedef struct MLAN_PACK_START _ExtCap_t { /** Extended Capabilities value */ @@ -2085,7 +1983,6 @@ typedef struct MLAN_PACK_START _ExtCap_t { t_u8 rsvdBit86 : 1; /* bit 86 */ t_u8 rsvdBit87 : 1; /* bit 87 */ } MLAN_PACK_END ExtCap_t, *pExtCap_t; -#endif /** ExtCap : TDLS prohibited */ #define IS_EXTCAP_TDLS_PROHIBITED(ext_cap) (ext_cap.TDLSProhibited) @@ -2211,6 +2108,8 @@ typedef struct _tdls_peer_info { t_u8 ht_cap[IEEE_MAX_IE_SIZE]; /** VHT Capabilities IE */ t_u8 vht_cap[IEEE_MAX_IE_SIZE]; + /** HE Capabilities IE */ + t_u8 he_cap[IEEE_MAX_IE_SIZE]; } tdls_peer_info; /** max ralist num */ @@ -2682,6 +2581,8 @@ typedef struct _mlan_sae_password_t { typedef struct _mlan_pmk_t { /** PMK */ t_u8 pmk[MLAN_MAX_KEY_LENGTH]; + t_u8 pmk_r0[MLAN_MAX_KEY_LENGTH]; + t_u8 pmk_r0_name[MLAN_MAX_PMKR0_NAME_LENGTH]; } mlan_pmk_t; /** Embedded supplicant RSN type: No RSN */ @@ -2732,10 +2633,20 @@ typedef struct _mlan_ds_ewpa_mode { t_u32 act_groupcipher; } mlan_ds_esupp_mode, *pmlan_ds_esupp_mode; +/* Security SSID MAX number support by firmware*/ +#define MAX_SEC_SSID_NUM 6 + /** Type definition of mlan_ds_sec_cfg for MLAN_IOCTL_SEC_CFG */ typedef struct _mlan_ds_sec_cfg { /** Sub-command */ t_u32 sub_command; + /** Flag to extend some structures to support multiple values. + ** For example, mlan_ds_passphrase can only contain one value, + ** if need use mlan_ds_passphrase[N], just set this flag and + ** use mlan_ds_passphrase[] instead to avoid modify + ** more already exist code. + */ + t_u8 multi_passphrase; /** Security configuration parameter */ union { /** Authentication mode for MLAN_OID_SEC_CFG_AUTH_MODE */ @@ -2761,6 +2672,7 @@ typedef struct _mlan_ds_sec_cfg { #ifdef UAP_SUPPORT t_u8 sta_mac[MLAN_MAC_ADDR_LENGTH]; #endif + mlan_ds_passphrase roam_passphrase[MAX_SEC_SSID_NUM]; } param; } mlan_ds_sec_cfg, *pmlan_ds_sec_cfg; @@ -3075,6 +2987,8 @@ typedef struct _mlan_ds_hs_cfg { t_u8 ext_gap; /** GPIO wave level for extend hscfg*/ t_u8 gpio_wave; + /** Minimum delay between HsActive and HostWake (in msec) */ + t_u16 min_wake_holdoff; } mlan_ds_hs_cfg, *pmlan_ds_hs_cfg; #define MAX_MGMT_FRAME_FILTER 2 @@ -3922,7 +3836,7 @@ typedef MLAN_PACK_START struct _mlan_ds_11ax_he_capa { /** Type definition of mlan_ds_11ax_he_cfg for MLAN_OID_11AX_HE_CFG */ typedef struct _mlan_ds_11ax_he_cfg { - /** band, BIT0:2.4G, BIT1:5G*/ + /** band, BIT0:2.4G, BIT1:5G BIT2:6G*/ t_u8 band; /** mlan_ds_11ax_he_capa */ mlan_ds_11ax_he_capa he_cap; @@ -4117,12 +4031,19 @@ typedef struct _mlan_ds_subband_set_t { t_u8 max_tx_pwr; } mlan_ds_subband_set_t; +#define NXP_DFS_UNSET 0 +#define NXP_DFS_FCC 1 +#define NXP_DFS_ETSI 2 +#define NXP_DFS_JP 3 +#define NXP_DFS_UNKNOWN 0xFF /** Domain regulatory information */ typedef struct _mlan_ds_11d_domain_info { + /** DFS region code */ + t_u8 dfs_region; /** Country Code */ t_u8 country_code[COUNTRY_CODE_LEN]; /** Band that channels in sub_band belong to */ - t_u8 band; + t_u16 band; /** No. of subband in below */ t_u8 no_of_sub_band; /** Subband data to send/last sent */ @@ -4166,7 +4087,14 @@ enum _mlan_reg_type { MLAN_REG_PSU = 6, MLAN_REG_BCA = 7, #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(USB9097) || defined(SD9097) + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) || \ + defined(SD9177) + MLAN_REG_CIU = 8, +#endif +#if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) MLAN_REG_MAC2 = 0x81, MLAN_REG_BBP2 = 0x82, MLAN_REG_RF2 = 0x83, @@ -4261,6 +4189,16 @@ typedef struct _mlan_ds_11h_chan_rep_req { t_u8 host_based; } mlan_ds_11h_chan_rep_req; +/** channel dfs state for MLAN_OID_11H_CHAN_DFS_STATE */ +typedef struct _mlan_ds_11h_chan_dfs_state { + /** channel */ + t_u8 channel; + /** is dfs channel */ + t_u8 dfs_required; + /** dfs state */ + dfs_state_t dfs_state; +} mlan_ds_11h_chan_dfs_state; + typedef struct _mlan_ds_11h_dfs_w53_cfg { /** dfs w53 cfg */ t_u8 dfs53cfg; @@ -4282,6 +4220,8 @@ typedef struct _mlan_ds_11h_cfg { mlan_ds_11h_chan_rep_req chan_rpt_req; /** channel switch count for MLAN_OID_11H_CHAN_SWITCH_COUNT*/ t_s8 cs_count; + /** channel dfs state for MLAN_OID_11H_CHAN_DFS_STATE */ + mlan_ds_11h_chan_dfs_state ch_dfs_state; mlan_ds_11h_dfs_w53_cfg dfs_w53_cfg; } param; } mlan_ds_11h_cfg, *pmlan_ds_11h_cfg; @@ -4370,6 +4310,26 @@ enum _mlan_func_cmd { MLAN_FUNC_SHUTDOWN, }; +/** Net monitor filter: management frame */ +#define MLAN_NETMON_MANAGEMENT_FRAME MBIT(0) +/** Net monitor filter: control frame */ +#define MLAN_NETMON_CONTROL_FRAME MBIT(1) +/** Net monitor filter: data frame */ +#define MLAN_NETMON_DATA_FRAME MBIT(2) + +typedef struct _mlan_ds_misc_net_monitor { + /** Enable/disable network monitor */ + t_u32 enable_net_mon; + /** Set net monitor filer flag */ + t_u32 filter_flag; + /** Radio type */ + t_u32 band; + /** Channel */ + t_u32 channel; + /** Secondary channel bandwidth */ + t_u32 chan_bandwidth; +} mlan_ds_misc_net_monitor; + /** Type definition of mlan_ds_misc_tx_datapause * for MLAN_OID_MISC_TX_DATAPAUSE */ @@ -4780,6 +4740,166 @@ typedef struct _mlan_ds_misc_pmfcfg { #define MAX_SSID_NUM 16 #define MAX_AP_LIST 8 +#define RETRY_UNLIMITED_TIME 0xFF + +#define FW_ROAM_ENABLE MBIT(0) +#define FW_ROAM_TRIGGER_COND MBIT(1) +#define FW_ROAM_BSSID MBIT(2) +#define FW_ROAM_SSID MBIT(3) +#define FW_ROAM_RETRY_COUNT MBIT(4) +#define FW_ROAM_RSSI_PARA MBIT(5) +#define FW_ROAM_BAND_RSSI MBIT(6) +#define FW_ROAM_BGSCAN_PARAM MBIT(7) +#define FW_ROAM_EES_PARAM MBIT(8) +#define FW_ROAM_BCN_MISS_THRESHOLD MBIT(9) +#define FW_ROAM_PRE_BCN_MISS_THRESHOLD MBIT(10) +#define FW_ROAM_BLACKLIST MBIT(11) +#define FW_ROAM_REPEAT_CNT MBIT(12) + +/*Roam offload configuration for auto reconnection when suspend and resume*/ +typedef enum _roam_offload_config_mode { + ROAM_OFFLOAD_ENABLE = 1, + ROAM_OFFLOAD_SUSPEND_CFG, + ROAM_OFFLOAD_RESUME_CFG, + ROAM_OFFLOAD_PARAM_CFG, +} roam_offload_config_mode; + +typedef enum _roam_offload_set_mode { + ROAM_OFFLOAD_DISABLE = 0, + ROAM_OFFLOAD_WITH_APLIST, + ROAM_OFFLOAD_WITHOUT_APLIST, + ROAM_OFFLOAD_WITH_BSSID, + ROAM_OFFLOAD_WITH_SSID, + AUTO_RECONNECT, +} roam_offload_set_mode; + +typedef enum _roam_offload_trigger_mode { + NO_TRIGGER = 0x00, + RSSI_LOW_TRIGGER = 0x01, + PRE_BEACON_LOST_TRIGGER = 0x02, + LINK_LOST_TRIGGER = 0x04, + DEAUTH_WITH_EXT_AP_TRIGGER = 0x08, +} roam_offload_trigger_mode; + +/** mlan_ds_misc_ees_cfg structure */ +typedef MLAN_PACK_START struct _mlan_ds_misc_ees_cfg { + /* EES mode*/ + t_u16 ees_mode; + /* EES report condition*/ + t_u16 ees_rpt_condition; + /* High scan period(milliseconds)*/ + t_u16 high_scan_period; + /* High scan count*/ + t_u16 high_scan_count; + /* Middle scan period(milliseconds)*/ + t_u16 mid_scan_period; + /* Middle scan count*/ + t_u16 mid_scan_count; + /* Low scan period(milliseconds)*/ + t_u16 low_scan_period; + /* Low scan count*/ + t_u16 low_scan_count; +} MLAN_PACK_END mlan_ds_misc_ees_cfg; + +/** mlan_ds_misc_bgscan_cfg structure */ +typedef MLAN_PACK_START struct _mlan_ds_misc_bgscan_cfg { + /* BSS Type 0x1-bss independent, 0x2-bss infrastructure, 0x3-bss any*/ + t_u8 bss_type; + /* Number of channels scanned for each scan*/ + t_u8 channels_per_scan; + /* Interval between consective scans*/ + t_u32 scan_interval; + /* Conditons to trigger report to host*/ + t_u32 bg_rpt_condition; +} MLAN_PACK_END mlan_ds_misc_bgscan_cfg; + +/** mlan_ds_misc_band_rssi structure */ +typedef MLAN_PACK_START struct _mlan_ds_misc_band_rssi { + /* RSSI hysteresis*/ + t_u8 rssi_hysteresis; + /* Preferred channel band for fw roaming + * 0:2.4G band; 1: 5G band; 2:4G band; 0xFF:band not set(invalid) + */ + t_u8 band_preferred; +} MLAN_PACK_END mlan_ds_misc_band_rssi; + +/** mlan_ds_misc_ssid_list structure */ +typedef MLAN_PACK_START struct _mlan_ds_misc_ssid_list { + /* SSID number*/ + t_u8 ssid_num; + /* SSID for fw roaming/auto_reconnect*/ + mlan_802_11_ssid ssids[MAX_SSID_NUM]; +} MLAN_PACK_END mlan_ds_misc_ssid_list; + +typedef MLAN_PACK_START struct _mlan_ds_misc_roam_offload_aplist { + /** Number of AP**/ + t_u8 ap_num; + /** AP mac addrs**/ + t_u8 ap_mac[MAX_AP_LIST][MLAN_MAC_ADDR_LENGTH]; +} MLAN_PACK_END mlan_ds_misc_roam_offload_aplist; + +typedef MLAN_PACK_START struct _mlan_ds_misc_roam_offload_para_rssi { + /** Setting flag**/ + t_u8 set_flag; + /** Max value of RSSI threshold**/ + t_u8 max_rssi; + /** Min value of RSSI threshold**/ + t_u8 min_rssi; + /** Adjusting step value of RSSI threshold**/ + t_u8 step_rssi; +} MLAN_PACK_END mlan_ds_misc_roam_offload_para_rssi; + +typedef MLAN_PACK_START struct _mlan_ds_misc_roam_offload { + /** Enable roam offload**/ + t_u8 enable; + /** User set passphrase**/ + t_u8 userset_passphrase; + /* Condition to trigger roaming + * Bit0 : RSSI low trigger + * Bit1 : Pre-beacon lost trigger + * Bit2 : Link Lost trigger + * Bit3 : Deauth by ext-AP trigger + * Bit4 ~ Bit15 : Reserved + * value 0 : no trigger + * value 0xff : invalid + */ + t_u16 trigger_condition; + /** AP list**/ + mlan_ds_misc_roam_offload_aplist aplist; + /*Roam offload configuration mode for auto connection when suspend and + * resume*/ + roam_offload_config_mode config_mode; + /** Retry count**/ + t_u8 retry_count; + /** RSSI para**/ + mlan_ds_misc_roam_offload_para_rssi para_rssi; + /** BSSID of reconnection**/ + mlan_802_11_mac_addr bssid_reconnect; + /* SSID List(White list)*/ + mlan_ds_misc_ssid_list ssid_list; + /* Black list(BSSID list)*/ + mlan_ds_misc_roam_offload_aplist black_list; + /* BAND and RSSI_HYSTERESIS set flag*/ + t_u8 band_rssi_flag; + mlan_ds_misc_band_rssi band_rssi; + + /* BGSCAN params set flag*/ + t_u8 bgscan_set_flag; + mlan_ds_misc_bgscan_cfg bgscan_cfg; + + /* EES mode params set flag*/ + t_u8 ees_param_set_flag; + mlan_ds_misc_ees_cfg ees_cfg; + + /* Beacon miss threshold*/ + t_u8 bcn_miss_threshold; + + /* Beacon miss threshold*/ + t_u8 pre_bcn_miss_threshold; + + /* Scan repeat count*/ + t_u16 repeat_count; +} MLAN_PACK_END mlan_ds_misc_roam_offload; /**Action ID for TDLS disable link*/ #define WLAN_TDLS_DISABLE_LINK 0x00 @@ -4833,6 +4953,8 @@ typedef struct _mlan_ds_misc_tdls_oper { #define TDLS_IE_FLAGS_QOS_INFO 0x0080 /** flag for TDLS SETUP */ #define TDLS_IE_FLAGS_SETUP 0x0100 +#define TDLS_IE_FLAGS_HECAP 0x0200 +#define TDLS_IE_FLAGS_HEOP 0x0400 /** TDLS ie buffer */ typedef struct _mlan_ds_misc_tdls_ies { @@ -4854,6 +4976,10 @@ typedef struct _mlan_ds_misc_tdls_ies { t_u8 vht_oprat[IEEE_MAX_IE_SIZE]; /** aid Info */ t_u8 aid_info[IEEE_MAX_IE_SIZE]; + /** HE Capabilities IE */ + t_u8 he_cap[IEEE_MAX_IE_SIZE]; + /** HE Operation IE */ + t_u8 he_op[IEEE_MAX_IE_SIZE]; /** supported channels */ t_u8 supp_chan[IEEE_MAX_IE_SIZE]; /** supported regulatory class */ @@ -5112,6 +5238,34 @@ typedef struct _mlan_ds_ssu_params { } mlan_ds_ssu_params; #endif +#define CSI_FILTER_MAX 16 +/** Structure of CSI filters */ +typedef MLAN_PACK_START struct _mlan_csi_filter_t { + /** Source address of the packet to receive */ + t_u8 mac_addr[MLAN_MAC_ADDR_LENGTH]; + /** Pakcet type of the interested CSI */ + t_u8 pkt_type; + /* Packet subtype of the interested CSI */ + t_u8 subtype; + /* Other filter flags */ + t_u8 flags; +} MLAN_PACK_END mlan_csi_filter_t; +/** Structure of CSI parameters */ +typedef MLAN_PACK_START struct _mlan_ds_csi_params { + /** CSI enable flag. 1: enable, 0: disable */ + t_u16 csi_enable; + /** Header ID*/ + t_u32 head_id; + /** Tail ID */ + t_u32 tail_id; + /** Number of CSI filters */ + t_u8 csi_filter_cnt; + /** Chip ID */ + t_u8 chip_id; + /** CSI filters */ + mlan_csi_filter_t csi_filter[CSI_FILTER_MAX]; +} MLAN_PACK_END mlan_ds_csi_params; + typedef MLAN_PACK_START struct _mlan_ds_hal_phy_cfg_params { /** 11b pwr spectral density mask enable/disable */ t_u8 dot11b_psd_mask_cfg; @@ -5319,6 +5473,31 @@ typedef struct _mlan_ds_misc_cfp_tbl { chan_freq_power_t cfp_tbl[]; } mlan_ds_misc_cfp_tbl; +/** mlan_ds_mc_aggr_cfg for MLAN_OID_MISC_MC_AGGR_CFG */ +typedef struct _mlan_ds_mc_aggr_cfg { + /** action */ + t_u8 action; + /* 1 enable, 0 disable + * bit 0 MC aggregation + * bit 1 packet expiry + * bit 2 CTS2Self + * bit 3 CTS2Self duration offset*/ + t_u8 enable_bitmap; + /* 1 valid, 0 invalid + * bit 0 MC aggregation + * bit 1 packet expiry + * bit 2 CTS2Self + * bit 3 CTS2Self duration offset*/ + t_u8 mask_bitmap; + /** CTS2Self duration offset */ + t_u16 cts2self_offset; +} mlan_ds_mc_aggr_cfg; +typedef struct _mlan_ds_ch_load { + /** action */ + t_u8 action; + t_u16 ch_load_param; +} mlan_ds_ch_load; + /** Type definition of mlan_ds_misc_cfg for MLAN_IOCTL_MISC_CFG */ typedef struct _mlan_ds_misc_cfg { /** Sub-command */ @@ -5358,6 +5537,8 @@ typedef struct _mlan_ds_misc_cfg { mlan_ds_misc_tdls_ies tdls_ies; /**tdls cs off channel*/ t_u8 tdls_cs_channel; + /** Net monitor for MLAN_OID_MISC_NET_MONITOR */ + mlan_ds_misc_net_monitor net_mon; /** Tx data pause for MLAN_OID_MISC_TX_DATAPAUSE */ mlan_ds_misc_tx_datapause tx_datapause; /** IP address configuration */ @@ -5419,6 +5600,8 @@ typedef struct _mlan_ds_misc_cfg { mlan_ds_misc_gtk_rekey_data gtk_rekey; mlan_ds_bw_chan_oper bw_chan_oper; mlan_ds_ind_rst_cfg ind_rst_cfg; + /** Roam offload */ + mlan_ds_misc_roam_offload roam_offload; t_u64 misc_tsf; mlan_ds_custom_reg_domain custom_reg_domain; mlan_ds_misc_keep_alive keep_alive; @@ -5430,6 +5613,7 @@ typedef struct _mlan_ds_misc_cfg { #if defined(PCIE) mlan_ds_ssu_params ssu_params; #endif + mlan_ds_csi_params csi_params; /** boot sleep enable or disable */ t_u16 boot_sleep; /** Mapping Policy */ @@ -5455,10 +5639,12 @@ typedef struct _mlan_ds_misc_cfg { mlan_ds_misc_dot11mc_unassoc_ftm_cfg dot11mc_unassoc_ftm_cfg; mlan_ds_misc_tp_state tp_state; mlan_ds_hal_phy_cfg_params hal_phy_cfg_params; + mlan_ds_mc_aggr_cfg mc_aggr_cfg; #ifdef UAP_SUPPORT t_u8 wacp_mode; #endif t_u32 ips_ctrl; + mlan_ds_ch_load ch_load; } param; } mlan_ds_misc_cfg, *pmlan_ds_misc_cfg; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_join.c b/mxm_wifiex/wlan_src/mlan/mlan_join.c index b20f187..c43b1e8 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_join.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_join.c @@ -1027,7 +1027,7 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv, pchan_tlv->chan_scan_param[0].chan_number); pchan_tlv->chan_scan_param[0].bandcfg.chanBand = - wlan_band_to_radio_type((t_u8)pbss_desc->bss_band); + wlan_band_to_radio_type(pbss_desc->bss_band); PRINTM(MINFO, "Assoc: TLV Bandcfg = %x\n", pchan_tlv->chan_scan_param[0].bandcfg); @@ -1205,8 +1205,8 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv, wlan_11ac_bandconfig_allowed(pmpriv, pbss_desc->bss_band)) wlan_cmd_append_11ac_tlv(pmpriv, pbss_desc, &pos); - if ((IS_FW_SUPPORT_11AX(pmadapter)) && (!pbss_desc->disable_11n) && - wlan_11ax_bandconfig_allowed(pmpriv, pbss_desc->bss_band)) + if ((IS_FW_SUPPORT_11AX(pmadapter)) && + wlan_11ax_bandconfig_allowed(pmpriv, pbss_desc)) wlan_cmd_append_11ax_tlv(pmpriv, pbss_desc, &pos); wlan_wmm_process_association_req(pmpriv, &pos, &pbss_desc->wmm_ie, @@ -1248,8 +1248,7 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv, pos += sizeof(prev_bssid_tlv->header) + MLAN_MAC_ADDR_LENGTH; } - if (wlan_11d_create_dnld_countryinfo(pmpriv, - (t_u8)pbss_desc->bss_band)) { + if (wlan_11d_create_dnld_countryinfo(pmpriv, pbss_desc->bss_band)) { PRINTM(MERROR, "Dnld_countryinfo_11d failed\n"); ret = MLAN_STATUS_FAILURE; goto done; @@ -2111,7 +2110,7 @@ mlan_status wlan_cmd_802_11_ad_hoc_join(mlan_private *pmpriv, pchan_tlv->chan_scan_param[0].chan_number); pchan_tlv->chan_scan_param[0].bandcfg.chanBand = - wlan_band_to_radio_type((t_u8)pbss_desc->bss_band); + wlan_band_to_radio_type(pbss_desc->bss_band); PRINTM(MINFO, "ADHOC_J_CMD: TLV Bandcfg = %x\n", pchan_tlv->chan_scan_param[0].bandcfg); @@ -2120,8 +2119,7 @@ mlan_status wlan_cmd_802_11_ad_hoc_join(mlan_private *pmpriv, sizeof(pchan_tlv->header) + sizeof(ChanScanParamSet_t); } - if (wlan_11d_create_dnld_countryinfo(pmpriv, - (t_u8)pbss_desc->bss_band)) { + if (wlan_11d_create_dnld_countryinfo(pmpriv, pbss_desc->bss_band)) { PRINTM(MERROR, "Dnld_countryinfo_11d failed\n"); ret = MLAN_STATUS_FAILURE; goto done; @@ -2639,7 +2637,7 @@ mlan_status wlan_disconnect(mlan_private *pmpriv, mlan_ioctl_req *pioctl_req, * * @return Radio type designator for use in a channel TLV */ -t_u8 wlan_band_to_radio_type(t_u8 band) +t_u8 wlan_band_to_radio_type(t_u16 band) { t_u8 ret_radio_type; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_join.h b/mxm_wifiex/wlan_src/mlan/mlan_join.h index 44d9e84..5a90761 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_join.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_join.h @@ -8,7 +8,7 @@ * both adhoc and infrastructure networks * * - * Copyright 2008-2020 NXP + * Copyright 2008-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mxm_wifiex/wlan_src/mlan/mlan_main.h b/mxm_wifiex/wlan_src/mlan/mlan_main.h index 9d0da97..78bfe02 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_main.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_main.h @@ -5,7 +5,7 @@ * in MLAN module. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -308,48 +308,6 @@ extern t_u32 mlan_drvdbg; (t_u64)(((t_u64)(x)&0x00ff000000000000ULL) >> 40) | \ (t_u64)(((t_u64)(x)&0xff00000000000000ULL) >> 56))) -#ifdef BIG_ENDIAN_SUPPORT -/** Convert ulong n/w to host */ -#define mlan_ntohl(x) x -/** Convert host ulong to n/w */ -#define mlan_htonl(x) x -/** Convert n/w to host */ -#define mlan_ntohs(x) x -/** Convert host to n/w */ -#define mlan_htons(x) x -/** Convert from 16 bit little endian format to CPU format */ -#define wlan_le16_to_cpu(x) swap_byte_16(x) -/** Convert from 32 bit little endian format to CPU format */ -#define wlan_le32_to_cpu(x) swap_byte_32(x) -/** Convert from 64 bit little endian format to CPU format */ -#define wlan_le64_to_cpu(x) swap_byte_64(x) -/** Convert to 16 bit little endian format from CPU format */ -#define wlan_cpu_to_le16(x) swap_byte_16(x) -/** Convert to 32 bit little endian format from CPU format */ -#define wlan_cpu_to_le32(x) swap_byte_32(x) -/** Convert to 64 bit little endian format from CPU format */ -#define wlan_cpu_to_le64(x) swap_byte_64(x) - -/** Convert TxPD to little endian format from CPU format */ -#define endian_convert_TxPD(x) \ - { \ - (x)->tx_pkt_length = wlan_cpu_to_le16((x)->tx_pkt_length); \ - (x)->tx_pkt_offset = wlan_cpu_to_le16((x)->tx_pkt_offset); \ - (x)->tx_pkt_type = wlan_cpu_to_le16((x)->tx_pkt_type); \ - (x)->tx_control = wlan_cpu_to_le32((x)->tx_control); \ - (x)->tx_control_1 = wlan_cpu_to_le32((x)->tx_control_1); \ - } -/** Convert RxPD from little endian format to CPU format */ -#define endian_convert_RxPD(x) \ - { \ - (x)->rx_pkt_length = wlan_le16_to_cpu((x)->rx_pkt_length); \ - (x)->rx_pkt_offset = wlan_le16_to_cpu((x)->rx_pkt_offset); \ - (x)->rx_pkt_type = wlan_le16_to_cpu((x)->rx_pkt_type); \ - (x)->seq_num = wlan_le16_to_cpu((x)->seq_num); \ - (x)->rx_info = wlan_le32_to_cpu((x)->rx_info); -} - -#else /** Convert ulong n/w to host */ #define mlan_ntohl(x) swap_byte_32(x) /** Convert host ulong to n/w */ @@ -379,7 +337,10 @@ extern t_u32 mlan_drvdbg; #define endian_convert_RxPD(x) \ do { \ } while (0) -#endif /* BIG_ENDIAN_SUPPORT */ +/** Convert RxPD extra header from little endian format to CPU format */ +#define endian_convert_RxPD_extra_header(x) \ + do { \ + } while (0) /** Global moal_assert_callback */ extern t_void (*assert_callback)(t_void *pmoal_handle, t_u32 cond); @@ -558,7 +519,7 @@ extern t_void (*assert_callback)(t_void *pmoal_handle, t_u32 cond); /** Maximum numbfer of registers to read for multiple port */ #if defined(SD8887) || defined(SD8997) || defined(SD8977) || \ defined(SD8987) || defined(SD9098) || defined(SD9097) || \ - defined(SD8978) || defined(SD9177) + defined(SDNW62X) || defined(SD8978) || defined(SD9177) #define MAX_MP_REGS 196 #else /* upto 0xB7 */ @@ -754,7 +715,7 @@ struct _raListTbl { /** packet count threshold to setup BA */ t_u8 ba_packet_threshold; /** is 11n enabled */ - t_u8 is_11n_enabled; + t_u8 is_wmm_enabled; /** max amsdu size */ t_u16 max_amsdu; /** BA stream status */ @@ -852,7 +813,7 @@ typedef struct { /** Uapsd enable?*/ t_u8 wmm_uapsd_enabled; /** Band */ - t_u8 band; + t_u16 band; /** Number of rates supported */ t_u32 num_of_rates; /** Supported rates*/ @@ -909,7 +870,7 @@ typedef struct _region_chan_t { /** Region code for US, Japan ... */ t_u8 region; /** Band B/G/A, used for BAND_CONFIG cmd */ - t_u8 band; + t_u16 band; /** Actual No. of elements in the array below */ t_u8 num_cfp; /** chan-freq-txpower mapping table */ @@ -926,10 +887,12 @@ typedef enum _state_11d_t { /** Domain regulatory information */ typedef struct _wlan_802_11d_domain_reg { + /** dfs_region */ + t_u8 dfs_region; /** Country Code */ t_u8 country_code[COUNTRY_CODE_LEN]; /** band that channels in sub_band belong to */ - t_u8 band; + t_u16 band; /** No. of subband in below */ t_u8 no_of_sub_band; /** Subband data to send/last sent */ @@ -1172,6 +1135,7 @@ typedef struct _mlan_private { /** AdHoc previous ssid used for Start */ mlan_802_11_ssid adhoc_last_start_ssid; #endif + mlan_ds_11h_chan_rep_req chan_rep_req; /** FSM variable for 11d support */ wlan_802_11d_state_t state_11d; /** FSM variable for 11h support */ @@ -1545,6 +1509,10 @@ struct _sta_node { IEEEtypes_VHTCap_t vht_cap; /** VHT Operations IE */ IEEEtypes_VHTOprat_t vht_oprat; + /** HE Capabilities IE */ + IEEEtypes_HECap_t tdls_he_cap; + /** HE Operations IE */ + IEEEtypes_HeOp_t he_op; /** wapi key on off flag */ t_u8 wapi_key_on; /** tx pause status */ @@ -2369,7 +2337,8 @@ typedef struct _mlan_adapter { /** Extended firmware capability information */ t_u32 fw_cap_ext; #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) /** High byte for 5G, low byte for 2G, like 0x2211 0x22 for 5G, 0x11 for * 2G */ t_u16 user_htstream; @@ -2461,6 +2430,8 @@ typedef struct _mlan_adapter { mlan_list_head cmd_pending_q; /** Command queue for scanning */ mlan_list_head scan_pending_q; + /** Command pending queue while scanning */ + mlan_list_head ext_cmd_pending_q; /** ioctl pending queue */ mlan_list_head ioctl_pending_q; /** pending_ioctl flag */ @@ -2468,6 +2439,10 @@ typedef struct _mlan_adapter { pmlan_private pending_disconnect_priv; /** mlan_processing */ t_u32 scan_processing; + /** firmware support for roaming*/ + t_u8 fw_roaming; + /** User set passphrase*/ + t_u8 userset_passphrase; /** ext_scan enh support flag */ t_u8 ext_scan_enh; /** scan type: 0 legacy, 1: enhance scan*/ @@ -2757,6 +2732,8 @@ typedef struct _mlan_adapter { /** tdls status */ /* TDLS_NOT_SETUP|TDLS_SWITCHING_CHANNEL|TDLS_IN_BASE_CHANNEL|TDLS_IN_SWITCH_CHANNEL*/ tdlsStatus_e tdls_status; + /** NetMon enabled */ + t_u32 enable_net_mon; /** Feature control bitmask */ t_u32 feature_control; @@ -2768,6 +2745,7 @@ typedef struct _mlan_adapter { #if defined(PCIE) mlan_buffer *ssu_buf; #endif + t_u8 csi_enabled; /** maximum sta connection */ t_u8 max_sta_conn; otp_region_info_t *otp_region; @@ -2810,6 +2788,18 @@ typedef struct _mlan_adapter { /** Ethernet packet type offset */ #define MLAN_ETHER_PKT_TYPE_OFFSET (12) +mlan_status wlan_cmd_net_monitor(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, + t_u16 cmd_action, t_void *pdata_buf); + +mlan_status wlan_ret_net_monitor(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf); + +mlan_status wlan_misc_ioctl_net_monitor(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req); + +void wlan_rxpdinfo_to_radiotapinfo(pmlan_private priv, RxPD *prx_pd, + radiotap_info *prt_info); + mlan_status wlan_init_lock_list(pmlan_adapter pmadapter); mlan_status wlan_init_priv_lock_list(pmlan_adapter pmadapter, t_u8 start_index); t_void wlan_free_lock_list(pmlan_adapter pmadapter); @@ -2893,6 +2883,9 @@ mlan_status wlan_bss_ioctl_bss_role(pmlan_adapter pmadapter, mlan_status wlan_misc_ssu(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); #endif +mlan_status wlan_misc_csi(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); +mlan_status wlan_process_csi_event(pmlan_private pmpriv); + mlan_status wlan_misc_hal_phy_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); @@ -3365,9 +3358,9 @@ t_void wlan_reset_connect_state(pmlan_private priv, t_u8 drv_disconnect); t_void wlan_2040_coex_event(pmlan_private pmpriv); /** convert band to radio type */ -t_u8 wlan_band_to_radio_type(t_u8 band); +t_u8 wlan_band_to_radio_type(t_u16 band); /** convert radio_type to band */ -t_u8 radio_type_to_band(t_u8 chanBand); +t_u16 radio_type_to_band(t_u8 chanBand); /** Disconnect */ mlan_status wlan_disconnect(mlan_private *pmpriv, mlan_ioctl_req *pioctl_req, @@ -3413,18 +3406,19 @@ mlan_status wlan_ret_802_11_bgscan_query(mlan_private *pmpriv, /** Get Channel-Frequency-Power by band and channel */ chan_freq_power_t * -wlan_get_cfp_by_band_and_channel(pmlan_adapter pmadapter, t_u8 band, +wlan_get_cfp_by_band_and_channel(pmlan_adapter pmadapter, t_u16 band, t_u16 channel, region_chan_t *region_channel); /** Find Channel-Frequency-Power by band and channel */ chan_freq_power_t *wlan_find_cfp_by_band_and_channel(mlan_adapter *pmadapter, - t_u8 band, t_u16 channel); + t_u16 band, t_u16 channel); /** Find Channel-Frequency-Power by band and frequency */ chan_freq_power_t *wlan_find_cfp_by_band_and_freq(mlan_adapter *pmadapter, - t_u8 band, t_u32 freq); + t_u16 band, t_u32 freq); /** Get Tx power of channel from Channel-Frequency-Power */ -t_u8 wlan_get_txpwr_of_chan_from_cfp(mlan_private *pmpriv, t_u8 channel); +t_u8 wlan_get_txpwr_of_chan_from_cfp(mlan_private *pmpriv, t_u16 band, + t_u8 channel); /** find frequency from band and channel */ -t_u32 wlan_find_freq_from_band_chan(t_u8, t_u8); +t_u32 wlan_find_freq_from_band_chan(t_u16 band, t_u8 chan); /* Save a beacon buffer of the current bss descriptor */ t_void wlan_save_curr_bcn(mlan_private *pmpriv); @@ -3528,27 +3522,28 @@ mlan_status wlan_misc_ioctl_tp_state(pmlan_adapter pmadapter, /* CFP related functions */ /** Region code index table */ extern t_u16 region_code_index[MRVDRV_MAX_REGION_CODE]; -/** The table to keep CFP code for BG */ -extern t_u16 cfp_code_index_bg[MRVDRV_MAX_CFP_CODE_BG]; /** The table to keep CFP code for A */ extern t_u16 cfp_code_index_a[MRVDRV_MAX_CFP_CODE_A]; /** Set region table */ -mlan_status wlan_set_regiontable(mlan_private *pmpriv, t_u8 region, t_u8 band); +mlan_status wlan_set_regiontable(mlan_private *pmpriv, t_u8 region, t_u16 band); /** Get radar detection requirements*/ t_bool wlan_get_cfp_radar_detect(mlan_private *priv, t_u8 chnl); /** check if scan type is passive for b/g band*/ t_bool wlan_bg_scan_type_is_passive(mlan_private *priv, t_u8 chnl); /** check if channel is NO_IR (passive) */ -t_bool wlan_is_chan_passive(mlan_private *priv, t_u8 band, t_u8 chan); +t_bool wlan_is_chan_passive(mlan_private *priv, t_u16 band, t_u8 chan); /** check if channel is disabled */ -t_bool wlan_is_chan_disabled(mlan_private *priv, t_u8 band, t_u8 chan); +t_bool wlan_is_chan_disabled(mlan_private *priv, t_u16 band, t_u8 chan); /** check if channel is blacklisted */ -t_bool wlan_is_chan_blacklisted(mlan_private *priv, t_u8 band, t_u8 chan); +t_bool wlan_is_chan_blacklisted(mlan_private *priv, t_u16 band, t_u8 chan); /** set blacklist setting for a channel */ -t_bool wlan_set_chan_blacklist(mlan_private *priv, t_u8 band, t_u8 chan, +t_bool wlan_set_chan_blacklist(mlan_private *priv, t_u16 band, t_u8 chan, t_bool bl); +dfs_state_t wlan_get_chan_dfs_state(mlan_private *priv, t_u16 band, t_u8 chan); +t_void wlan_set_chan_dfs_state(mlan_private *priv, t_u16 band, t_u8 chan, + dfs_state_t dfs_state); /* 802.11D related functions */ /** Initialize 11D */ t_void wlan_11d_priv_init(mlan_private *pmpriv); @@ -3571,16 +3566,16 @@ mlan_status wlan_cmd_802_11d_domain_info(mlan_private *pmpriv, mlan_status wlan_ret_802_11d_domain_info(mlan_private *pmpriv, HostCmd_DS_COMMAND *resp); /** Convert channel to frequency */ -t_u32 wlan_11d_chan_2_freq(pmlan_adapter pmadapter, t_u8 chan, t_u8 band); +t_u32 wlan_11d_chan_2_freq(pmlan_adapter pmadapter, t_u8 chan, t_u16 band); #ifdef STA_SUPPORT /** Set 11D universal table */ -mlan_status wlan_11d_set_universaltable(mlan_private *pmpriv, t_u8 band); +mlan_status wlan_11d_set_universaltable(mlan_private *pmpriv, t_u16 band); /** Clear 11D region table */ mlan_status wlan_11d_clear_parsedtable(mlan_private *pmpriv); /** Create 11D country information for downloading */ -mlan_status wlan_11d_create_dnld_countryinfo(mlan_private *pmpriv, t_u8 band); +mlan_status wlan_11d_create_dnld_countryinfo(mlan_private *pmpriv, t_u16 band); /** Get scan type from 11D info */ -t_u8 wlan_11d_get_scan_type(pmlan_adapter pmadapter, t_u8 band, t_u8 chan, +t_u8 wlan_11d_get_scan_type(pmlan_adapter pmadapter, t_u16 band, t_u8 chan, parsed_region_chan_11d_t *parsed_region_chan); /** Parse 11D country info */ mlan_status wlan_11d_parse_dnld_countryinfo(mlan_private *pmpriv, @@ -3590,11 +3585,11 @@ mlan_status wlan_11d_prepare_dnld_domain_info_cmd(mlan_private *pmpriv); /** Parse 11D country information into domain info */ mlan_status wlan_11d_parse_domain_info( pmlan_adapter pmadapter, IEEEtypes_CountryInfoFullSet_t *country_info, - t_u8 band, parsed_region_chan_11d_t *parsed_region_chan); + t_u16 band, parsed_region_chan_11d_t *parsed_region_chan); #endif /* STA_SUPPORT */ #ifdef UAP_SUPPORT /** Handle 11D domain information from UAP */ -mlan_status wlan_11d_handle_uap_domain_info(mlan_private *pmpriv, t_u8 band, +mlan_status wlan_11d_handle_uap_domain_info(mlan_private *pmpriv, t_u16 band, t_u8 *domain_tlv, t_void *pioctl_buf); #endif @@ -3959,6 +3954,19 @@ mlan_status wlan_ret_802_11_supplicant_pmk(pmlan_private pmpriv, mlan_status wlan_sec_ioctl_passphrase(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); +mlan_status wlan_cmd_mc_aggr_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, + t_u16 cmd_action, t_void *pdata_buf); +mlan_status wlan_ret_mc_aggr_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf); +mlan_status wlan_misc_ioctl_mc_aggr_cfg(pmlan_adapter pmadapter, + mlan_ioctl_req *pioctl_req); +mlan_status wlan_misc_ioctl_ch_load(pmlan_adapter pmadapter, + mlan_ioctl_req *pioctl_req); +mlan_status wlan_cmd_get_ch_load(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, + t_u16 cmd_action, t_void *pdata_buf); +mlan_status wlan_ret_ch_load(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf); + mlan_status wlan_misc_ioctl_get_tsf(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); void wlan_add_fw_cfp_tables(pmlan_private pmpriv, t_u8 *buf, t_u16 buf_left); @@ -3980,6 +3988,8 @@ mlan_status wlan_ret_get_tsf(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, t_u8 wlan_ft_akm_is_used(mlan_private *pmpriv, t_u8 *rsn_ie); +mlan_status wlan_clear_fw_roaming_pmk(pmlan_private pmpriv); + mlan_status wlan_get_rgchnpwr_cfg(pmlan_adapter pmadapter, mlan_ioctl_req *pioctl_req); mlan_status wlan_get_chan_trpc_cfg(pmlan_adapter pmadapter, @@ -4044,6 +4054,14 @@ mlan_status wlan_cmd_range_ext(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, mlan_status wlan_ret_range_ext(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf); +mlan_status wlan_misc_ioctl_get_sensor_temp(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req); +mlan_status wlan_cmd_get_sensor_temp(pmlan_private pmpriv, + HostCmd_DS_COMMAND *cmd, t_u16 cmd_action); +mlan_status wlan_ret_get_sensor_temp(pmlan_private pmpriv, + HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf); + /** * @brief RA based queueing * diff --git a/mxm_wifiex/wlan_src/mlan/mlan_meas.c b/mxm_wifiex/wlan_src/mlan/mlan_meas.c index 435c704..5ed4776 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_meas.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_meas.c @@ -12,7 +12,7 @@ * - ENABLE_MEAS * * - * Copyright 2008-2020 NXP + * Copyright 2008-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mxm_wifiex/wlan_src/mlan/mlan_meas.h b/mxm_wifiex/wlan_src/mlan/mlan_meas.h index f353bd6..2106391 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_meas.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_meas.h @@ -9,7 +9,7 @@ * @sa mlan_meas.c * * - * Copyright 2008-2020 NXP + * Copyright 2008-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mxm_wifiex/wlan_src/mlan/mlan_misc.c b/mxm_wifiex/wlan_src/mlan/mlan_misc.c index 16480bc..a57a66f 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_misc.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_misc.c @@ -4,7 +4,7 @@ * @brief This file include miscellaneous functions for MLAN module * * - * Copyright 2009-2021 NXP + * Copyright 2009-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -785,6 +785,8 @@ mlan_status wlan_pm_ioctl_hscfg(pmlan_adapter pmadapter, pmadapter->gpio_wave = pm->param.hs_cfg.gpio_wave; pmadapter->hs_wake_interval = pm->param.hs_cfg.hs_wake_interval; + pmadapter->min_wake_holdoff = + pm->param.hs_cfg.min_wake_holdoff; } break; case MLAN_ACT_GET: @@ -802,6 +804,7 @@ mlan_status wlan_pm_ioctl_hscfg(pmlan_adapter pmadapter, pm->param.hs_cfg.ext_gap = pmadapter->ext_gap; pm->param.hs_cfg.gpio_wave = pmadapter->gpio_wave; pm->param.hs_cfg.hs_wake_interval = pmadapter->hs_wake_interval; + pm->param.hs_cfg.min_wake_holdoff = pmadapter->min_wake_holdoff; break; default: pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID; @@ -949,6 +952,54 @@ mlan_status wlan_misc_hal_phy_cfg(pmlan_adapter pmadapter, return ret; } +/** + * @brief Enable/disable CSI support + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req A pointer to ioctl request buffer + * + * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success, + * otherwise fail + */ +mlan_status wlan_misc_csi(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req) +{ + mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; + mlan_status ret = MLAN_STATUS_SUCCESS; + mlan_ds_misc_cfg *csi_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf; + t_u16 cmd_act; + + ENTER(); + + if (csi_cfg->param.csi_params.csi_enable == 1) { + if (pmadapter->csi_enabled) { + PRINTM(MERROR, + "Enable CSI: CSI was already enabled.\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + cmd_act = CSI_CMD_ENABLE; + } else { + if (!pmadapter->csi_enabled) { + PRINTM(MERROR, + "Disable CSI: CSI was already disabled.\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + cmd_act = CSI_CMD_DISABLE; + } + + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_CSI, cmd_act, 0, + (t_void *)pioctl_req, + &csi_cfg->param.csi_params); + + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; + +done: + LEAVE(); + return ret; +} + /** * @brief This function allocates a mlan_buffer. * @@ -1586,21 +1637,24 @@ mlan_status wlan_reg_mem_ioctl_reg_rw(pmlan_adapter pmadapter, switch (reg_mem->param.reg_rw.type) { case MLAN_REG_MAC: #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(USB9097) || defined(SD9097) + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) case MLAN_REG_MAC2: #endif cmd_no = HostCmd_CMD_MAC_REG_ACCESS; break; case MLAN_REG_BBP: #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(USB9097) || defined(SD9097) + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) case MLAN_REG_BBP2: #endif cmd_no = HostCmd_CMD_BBP_REG_ACCESS; break; case MLAN_REG_RF: #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(USB9097) || defined(SD9097) + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) case MLAN_REG_RF2: #endif cmd_no = HostCmd_CMD_RF_REG_ACCESS; @@ -1613,11 +1667,20 @@ mlan_status wlan_reg_mem_ioctl_reg_rw(pmlan_adapter pmadapter, break; case MLAN_REG_BCA: #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(USB9097) || defined(SD9097) + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) case MLAN_REG_BCA2: #endif cmd_no = HostCmd_CMD_BCA_REG_ACCESS; break; +#if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) || \ + defined(SD9177) + case MLAN_REG_CIU: + cmd_no = HostCmd_CMD_REG_ACCESS; + break; +#endif default: pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID; ret = MLAN_STATUS_FAILURE; @@ -1878,6 +1941,7 @@ int wlan_get_tdls_list(mlan_private *priv, tdls_peer_info *buf) tdls_peer_info *peer_info = buf; sta_node *sta_ptr = MNULL; int count = 0; + IEEEtypes_Header_t *ieee_hdr; ENTER(); if (priv->bss_type != MLAN_BSS_TYPE_STA) { LEAVE(); @@ -1908,6 +1972,11 @@ int wlan_get_tdls_list(mlan_private *priv, tdls_peer_info *buf) &sta_ptr->vht_cap, sizeof(IEEEtypes_VHTCap_t), sizeof(peer_info->vht_cap)); + ieee_hdr = (IEEEtypes_Header_t *)peer_info->he_cap; + memcpy_ext(priv->adapter, peer_info->he_cap, + &sta_ptr->he_cap, + sizeof(IEEEtypes_Header_t) + ieee_hdr->len, + sizeof(peer_info->he_cap)); peer_info++; count++; } @@ -2523,6 +2592,8 @@ mlan_status wlan_misc_ioctl_tdls_get_ies(pmlan_adapter pmadapter, IEEEtypes_VHTOprat_t *vht_oprat = MNULL; IEEEtypes_AssocRsp_t *passoc_rsp = MNULL; IEEEtypes_AID_t *aid_info = MNULL; + IEEEtypes_HECap_t *he_cap = MNULL; + IEEEtypes_HeOp_t *he_op = MNULL; t_u8 supp_chan[] = {1, 11}; t_u8 regulatory_class[] = {1, /**current class*/ 1, 2, 3, 4, 12, 22, 23, 24, @@ -2629,7 +2700,7 @@ mlan_status wlan_misc_ioctl_tdls_get_ies(pmlan_adapter pmadapter, wlan_fill_vht_cap_ie(pmpriv, vht_cap, pbss_desc->bss_band); if (ht_cap) SETHT_SUPPCHANWIDTH(ht_cap->ht_cap.ht_cap_info); - DBG_HEXDUMP(MCMD_D, "TDLS vhtcap", tdls_ies->vht_cap, + DBG_HEXDUMP(MCMD_D, "TDLS VHT Cap IE", tdls_ies->vht_cap, sizeof(IEEEtypes_VHTCap_t)); } /** fill the vhtoperation based on hwspec */ @@ -2646,8 +2717,8 @@ mlan_status wlan_misc_ioctl_tdls_get_ies(pmlan_adapter pmadapter, tdls_ies->vht_oprat, sizeof(IEEEtypes_VHTOprat_t), sizeof(IEEEtypes_VHTOprat_t)); - DBG_HEXDUMP(MCMD_D, "TDLS vht_oprat", tdls_ies->vht_oprat, - sizeof(IEEEtypes_VHTOprat_t)); + DBG_HEXDUMP(MCMD_D, "TDLS VHT Operation IE", + tdls_ies->vht_oprat, sizeof(IEEEtypes_VHTOprat_t)); } /** fill the AID info */ if (tdls_ies->flags & TDLS_IE_FLAGS_AID) { @@ -2665,6 +2736,26 @@ mlan_status wlan_misc_ioctl_tdls_get_ies(pmlan_adapter pmadapter, aid_info->AID = wlan_le16_to_cpu(passoc_rsp->a_id); PRINTM(MCMND, "TDLS AID=0x%x\n", aid_info->AID); } + /** fill the hecap based on hwspec */ + if (tdls_ies->flags & TDLS_IE_FLAGS_HECAP) { + he_cap = (IEEEtypes_HECap_t *)tdls_ies->he_cap; + memset(pmadapter, he_cap, 0, sizeof(IEEEtypes_HECap_t)); + wlan_fill_he_cap_ie(pmpriv, he_cap, pbss_desc->bss_band); + DBG_HEXDUMP(MCMD_D, "TDLS HE Cap IE", tdls_ies->he_cap, + sizeof(IEEEtypes_Header_t) + he_cap->ieee_hdr.len); + } + + if (tdls_ies->flags & TDLS_IE_FLAGS_HEOP) { + he_op = (IEEEtypes_HeOp_t *)tdls_ies->he_op; + memset(pmadapter, he_op, 0, sizeof(IEEEtypes_HeOp_t)); + wlan_fill_he_op_ie(pmpriv, he_op); + } + if (sta_ptr) { + memcpy_ext(pmadapter, &sta_ptr->he_op, tdls_ies->he_op, + sizeof(IEEEtypes_HeOp_t), sizeof(IEEEtypes_HeOp_t)); + DBG_HEXDUMP(MCMD_D, "TDLS HE Operation IE", tdls_ies->he_op, + sizeof(IEEEtypes_HeOp_t)); + } /** fill the htinfo */ if (tdls_ies->flags & TDLS_IE_FLAGS_HTINFO) { ht_info = (IEEEtypes_HTInfo_t *)tdls_ies->ht_info; @@ -3874,7 +3965,8 @@ mlan_status wlan_radio_ioctl_ant_cfg(pmlan_adapter pmadapter, /* User input validation */ if (IS_STREAM_2X2(pmadapter->feature_control)) { #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if (IS_CARD9098(pmadapter->card_type) || IS_CARD9097(pmadapter->card_type)) { ant_cfg->tx_antenna &= 0x0303; @@ -3920,7 +4012,8 @@ mlan_status wlan_radio_ioctl_ant_cfg(pmlan_adapter pmadapter, ant_cfg->tx_antenna &= 0x0003; ant_cfg->rx_antenna &= 0x0003; #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) } #endif if (!ant_cfg->tx_antenna || @@ -5936,6 +6029,72 @@ mlan_status wlan_get_rgchnpwr_cfg(pmlan_adapter pmadapter, return ret; } +/** + * @brief Get/Set mc_aggr_cfg + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req A pointer to ioctl request buffer + * + * @return MLAN_STATUS_PENDING --success, otherwise fail + */ +mlan_status wlan_misc_ioctl_mc_aggr_cfg(pmlan_adapter pmadapter, + mlan_ioctl_req *pioctl_req) +{ + mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; + mlan_status ret = MLAN_STATUS_SUCCESS; + t_u16 cmd_action = 0; + mlan_ds_misc_cfg *misc = MNULL; + + ENTER(); + + misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf; + cmd_action = pioctl_req->action; + + /* Send request to firmware */ + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MC_AGGR_CFG, cmd_action, 0, + (t_void *)pioctl_req, + (t_void *)&misc->param.mc_aggr_cfg); + + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; + + LEAVE(); + return ret; +} + +/** + * @brief get channel load + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req A pointer to ioctl request buffer + * + * @return MLAN_STATUS_PENDING --success, otherwise fail + */ +mlan_status wlan_misc_ioctl_ch_load(pmlan_adapter pmadapter, + mlan_ioctl_req *pioctl_req) +{ + mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; + mlan_status ret = MLAN_STATUS_SUCCESS; + t_u16 cmd_action = 0; + mlan_ds_misc_cfg *misc = MNULL; + + ENTER(); + + misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf; + cmd_action = pioctl_req->action; + + /* Send request to firmware */ + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_GET_CH_LOAD, cmd_action, 0, + (t_void *)pioctl_req, + (t_void *)&misc->param.ch_load); + + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; + + LEAVE(); + return ret; +} + /** * @brief Get CHAN_TPRC setting * @@ -6056,6 +6215,60 @@ mlan_status wlan_misc_ioctl_fw_dump_event(pmlan_adapter pmadapter, return ret; } +/** + * @brief Set/Get the network monitor configuration. + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req A pointer to ioctl request buffer + * + * @return MLAN_STATUS_PENDING --success, otherwise fail + */ +mlan_status wlan_misc_ioctl_net_monitor(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req) +{ + mlan_private *pmpriv; + mlan_ds_misc_cfg *misc; + mlan_status ret = MLAN_STATUS_SUCCESS; + t_u16 cmd_action = 0; + + ENTER(); + + if (!pioctl_req) { + LEAVE(); + return MLAN_STATUS_FAILURE; + } + pmpriv = pmadapter->priv[pioctl_req->bss_index]; + + misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf; + + if (misc->param.net_mon.enable_net_mon == CHANNEL_SPEC_SNIFFER_MODE) { + /* Net monitor IOCTL not allowed in connected state */ + if (pmpriv->media_connected == MTRUE) { + PRINTM(MERROR, + "IOCTL not allowed in connected state\n"); + pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID; + LEAVE(); + return MLAN_STATUS_FAILURE; + } + } + + if (pioctl_req->action == MLAN_ACT_SET) + cmd_action = HostCmd_ACT_GEN_SET; + else + cmd_action = HostCmd_ACT_GEN_GET; + + /* Send command to firmware */ + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_NET_MONITOR, + cmd_action, 0, (t_void *)pioctl_req, + &misc->param.net_mon); + + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; + + LEAVE(); + return ret; +} + /** * @brief config boot sleep * @@ -6639,3 +6852,31 @@ mlan_status wlan_misc_ioctl_wacp_mode(IN pmlan_adapter pmadapter, return ret; } #endif + +mlan_status wlan_misc_ioctl_get_sensor_temp(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req) +{ + mlan_status ret = MLAN_STATUS_SUCCESS; + t_u16 cmd_action = 0; + mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; + + ENTER(); + + if (pioctl_req->action == MLAN_ACT_GET) + cmd_action = HostCmd_ACT_GEN_GET; + else { + PRINTM(MERROR, " Sensor temp only support get operation \n"); + LEAVE(); + return MLAN_STATUS_FAILURE; + } + + /* Send request to firmware */ + ret = wlan_prepare_cmd(pmpriv, HostCmd_DS_GET_SENSOR_TEMP, cmd_action, + 0, (t_void *)pioctl_req, MNULL); + + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; + + LEAVE(); + return ret; +} diff --git a/mxm_wifiex/wlan_src/mlan/mlan_module.c b/mxm_wifiex/wlan_src/mlan/mlan_module.c index 724c794..2281d45 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_module.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_module.c @@ -3,7 +3,7 @@ * @brief This file declares the exported symbols from MLAN. * * - * Copyright 2008-2020 NXP + * Copyright 2008-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mxm_wifiex/wlan_src/mlan/mlan_pcie.c b/mxm_wifiex/wlan_src/mlan/mlan_pcie.c index 0c703fe..213b721 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_pcie.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_pcie.c @@ -118,7 +118,7 @@ static const struct _mlan_card_info mlan_card_info_pcie8997 = { }; #endif -#ifdef PCIE9097 +#if defined(PCIE9097) || defined(PCIENW62X) static const struct _mlan_pcie_card_reg mlan_reg_pcie9097_b0 = { .reg_txbd_rdptr = PCIE9098_TXBD_RDPTR, .reg_txbd_wrptr = PCIE9098_TXBD_WRPTR, @@ -152,7 +152,7 @@ static const struct _mlan_pcie_card_reg mlan_reg_pcie9097_b0 = { }; #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) static const struct _mlan_pcie_card_reg mlan_reg_pcie9098 = { .reg_txbd_rdptr = PCIE9098_TXBD_RDPTR, .reg_txbd_wrptr = PCIE9098_TXBD_WRPTR, @@ -204,7 +204,7 @@ static const struct _mlan_card_info mlan_card_info_pcie9098 = { static mlan_status wlan_pcie_delete_evtbd_ring(pmlan_adapter pmadapter); static mlan_status wlan_pcie_delete_rxbd_ring(pmlan_adapter pmadapter); -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) /** * @brief This function init the adma setting * @@ -542,7 +542,7 @@ static void wlan_pcie_init_adma_ring_size(mlan_adapter *pmadapter) #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) /** * @brief This function set the host interrupt select mask * @@ -590,7 +590,7 @@ static mlan_status wlan_pcie_set_host_int_select_mask(mlan_adapter *pmadapter, } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) /** * @brief This function handles command response completion * @@ -761,8 +761,9 @@ static mlan_status wlan_disable_pcie_host_int(mlan_adapter *pmadapter) LEAVE(); return ret; } -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if ((pmadapter->card_type == CARD_TYPE_PCIE9098) || + (pmadapter->card_type == CARD_TYPE_PCIENW62X) || (pmadapter->card_type == CARD_TYPE_PCIE9097)) { ret = wlan_pcie_set_host_int_select_mask(pmadapter, MFALSE); if (ret) { @@ -838,8 +839,9 @@ static mlan_status wlan_enable_pcie_host_int(mlan_adapter *pmadapter) LEAVE(); return ret; } -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if ((pmadapter->card_type == CARD_TYPE_PCIE9098) || + (pmadapter->card_type == CARD_TYPE_PCIENW62X) || (pmadapter->card_type == CARD_TYPE_PCIE9097)) { ret = wlan_pcie_set_host_int_select_mask(pmadapter, MTRUE); if (ret) { @@ -868,7 +870,7 @@ static mlan_status wlan_pcie_create_txbd_ring(mlan_adapter *pmadapter) #if defined(PCIE8997) || defined(PCIE8897) pmlan_pcie_data_buf ptx_bd_buf; #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) padma_dual_desc_buf padma_bd_buf; #endif @@ -890,7 +892,7 @@ static mlan_status wlan_pcie_create_txbd_ring(mlan_adapter *pmadapter) pmadapter->pcard_pcie->txrx_bd_size; #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) pmadapter->pcard_pcie->txbd_ring_size = sizeof(adma_dual_desc_buf) * @@ -921,7 +923,7 @@ static mlan_status wlan_pcie_create_txbd_ring(mlan_adapter *pmadapter) for (i = 0; i < pmadapter->pcard_pcie->txrx_bd_size; i++) { pmadapter->pcard_pcie->tx_buf_list[i] = MNULL; -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { padma_bd_buf = (adma_dual_desc_buf @@ -976,7 +978,7 @@ static mlan_status wlan_pcie_delete_txbd_ring(mlan_adapter *pmadapter) #if defined(PCIE8997) || defined(PCIE8897) mlan_pcie_data_buf *ptx_bd_buf; #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) adma_dual_desc_buf *padma_bd_buf; #endif @@ -1010,7 +1012,7 @@ static mlan_status wlan_pcie_delete_txbd_ring(mlan_adapter *pmadapter) } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { padma_bd_buf = (adma_dual_desc_buf *) @@ -1062,7 +1064,7 @@ static mlan_status wlan_pcie_create_rxbd_ring(mlan_adapter *pmadapter) #if defined(PCIE8997) || defined(PCIE8897) mlan_pcie_data_buf *prxbd_buf; #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) adma_dual_desc_buf *padma_bd_buf; #endif @@ -1086,7 +1088,7 @@ static mlan_status wlan_pcie_create_rxbd_ring(mlan_adapter *pmadapter) } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) /* * driver maintaines the write pointer and firmware maintaines the read * pointer. The read pointer starts at 0 (zero) while the write pointer @@ -1175,7 +1177,7 @@ static mlan_status wlan_pcie_create_rxbd_ring(mlan_adapter *pmadapter) } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { padma_bd_buf = (adma_dual_desc_buf @@ -1214,7 +1216,7 @@ static mlan_status wlan_pcie_delete_rxbd_ring(mlan_adapter *pmadapter) #if defined(PCIE8997) || defined(PCIE8897) mlan_pcie_data_buf *prxbd_buf; #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) adma_dual_desc_buf *padma_bd_buf; #endif @@ -1245,7 +1247,7 @@ static mlan_status wlan_pcie_delete_rxbd_ring(mlan_adapter *pmadapter) } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { padma_bd_buf = (adma_dual_desc_buf *) @@ -1296,7 +1298,7 @@ static mlan_status wlan_pcie_create_evtbd_ring(mlan_adapter *pmadapter) pmlan_pcie_evt_buf pevtbd_buf; #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) adma_dual_desc_buf *padma_bd_buf; #endif @@ -1315,7 +1317,7 @@ static mlan_status wlan_pcie_create_evtbd_ring(mlan_adapter *pmadapter) } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { pmadapter->pcard_pcie->evtbd_wrptr = MLAN_MAX_EVT_BD; pmadapter->pcard_pcie->evtbd_ring_size = @@ -1386,7 +1388,7 @@ static mlan_status wlan_pcie_create_evtbd_ring(mlan_adapter *pmadapter) } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { padma_bd_buf = (adma_dual_desc_buf @@ -1425,7 +1427,7 @@ static mlan_status wlan_pcie_delete_evtbd_ring(mlan_adapter *pmadapter) #if defined(PCIE8997) || defined(PCIE8897) mlan_pcie_evt_buf *pevtbd_buf; #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) adma_dual_desc_buf *padma_bd_buf; #endif @@ -1455,7 +1457,7 @@ static mlan_status wlan_pcie_delete_evtbd_ring(mlan_adapter *pmadapter) } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { padma_bd_buf = (adma_dual_desc_buf *) @@ -1652,7 +1654,7 @@ static t_u8 wlan_check_tx_pending_buffer(mlan_adapter *pmadapter, t_u32 rdptr) return MFALSE; } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { if ((pmadapter->pcard_pcie->txbd_rdptr & ADMA_RW_PTR_WRAP_MASK) != (rdptr & ADMA_RW_PTR_WRAP_MASK)) @@ -1686,7 +1688,7 @@ static mlan_status wlan_pcie_send_data_complete(mlan_adapter *pmadapter) pmadapter->pcard_pcie->reg->txrx_rw_ptr_rollover_ind; mlan_pcie_data_buf *ptx_bd_buf; #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) adma_dual_desc_buf *padma_bd_buf; t_u32 wrptr; #endif @@ -1710,7 +1712,7 @@ static mlan_status wlan_pcie_send_data_complete(mlan_adapter *pmadapter) rdptr = rdptr >> TXBD_RW_PTR_START; #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { wrptr = rdptr & 0xffff; rdptr = rdptr >> ADMA_RPTR_START; @@ -1770,7 +1772,7 @@ static mlan_status wlan_pcie_send_data_complete(mlan_adapter *pmadapter) txrx_rw_ptr_rollover_ind); } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { padma_bd_buf = (adma_dual_desc_buf *)pmadapter->pcard_pcie @@ -1810,7 +1812,7 @@ done: ((wrptr & rollover_ind) == (rdptr & rollover_ind))) #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) #define ADMA_TXBD_IS_FULL(wrptr, rdptr, mask, rollover_ind) \ (((wrptr & mask) == (rdptr & mask)) && \ ((wrptr & rollover_ind) != (rdptr & rollover_ind))) @@ -1834,7 +1836,7 @@ static t_u8 wlan_check_txbd_not_full(mlan_adapter *pmadapter) return MFALSE; } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { txrx_rw_ptr_mask = pmadapter->pcard_pcie->txrx_bd_size - 1; txrx_rw_ptr_rollover_ind = pmadapter->pcard_pcie->txrx_bd_size; @@ -1872,7 +1874,7 @@ static mlan_status wlan_pcie_send_data(mlan_adapter *pmadapter, t_u8 type, pmadapter->pcard_pcie->reg->txrx_rw_ptr_rollover_ind; mlan_pcie_data_buf *ptx_bd_buf = MNULL; #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) adma_dual_desc_buf *padma_bd_buf = MNULL; #endif const t_u32 num_tx_buffs = pmadapter->pcard_pcie->txrx_bd_size; @@ -1952,7 +1954,7 @@ static mlan_status wlan_pcie_send_data(mlan_adapter *pmadapter, t_u8 type, } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { wr_ptr_start = ADMA_WPTR_START; padma_bd_buf = (adma_dual_desc_buf *)pmadapter @@ -2043,7 +2045,7 @@ done_unmap: ptx_bd_buf->offset = 0; } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma && padma_bd_buf) { padma_bd_buf->paddr = 0; padma_bd_buf->len = 0; @@ -2083,7 +2085,7 @@ static t_u8 wlan_check_rx_pending_buffer(mlan_adapter *pmadapter, t_u32 rdptr) } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { if ((pmadapter->pcard_pcie->rxbd_rdptr & ADMA_RW_PTR_WRAP_MASK) != (rdptr & ADMA_RW_PTR_WRAP_MASK)) @@ -2129,7 +2131,7 @@ static t_u8 wlan_is_rx_pending_full(mlan_adapter *pmadapter, t_u32 rdptr) } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { PRINTM(MDATA, "local wrptr: 0x%x -> reg rdptr: 0x%x\n", (pmadapter->pcard_pcie->rxbd_wrptr & @@ -2169,7 +2171,7 @@ static mlan_status wlan_pcie_process_recv_data(mlan_adapter *pmadapter) pmadapter->pcard_pcie->reg->txrx_rw_ptr_rollover_ind; mlan_pcie_data_buf *prxbd_buf; #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) adma_dual_desc_buf *padma_bd_buf; #endif t_u32 in_ts_sec, in_ts_usec; @@ -2183,7 +2185,7 @@ static mlan_status wlan_pcie_process_recv_data(mlan_adapter *pmadapter) ret = MLAN_STATUS_FAILURE; goto done; } -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) rdptr = rdptr >> ADMA_RPTR_START; #endif @@ -2341,7 +2343,7 @@ static mlan_status wlan_pcie_process_recv_data(mlan_adapter *pmadapter) txbd_val = txbd_val << TXBD_RW_PTR_START; } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { padma_bd_buf = (adma_dual_desc_buf *)pmadapter->pcard_pcie @@ -2383,7 +2385,7 @@ static mlan_status wlan_pcie_process_recv_data(mlan_adapter *pmadapter) ret = MLAN_STATUS_FAILURE; goto done; } -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) rdptr = rdptr >> ADMA_RPTR_START; #endif @@ -2529,7 +2531,7 @@ static mlan_status wlan_pcie_send_cmd(mlan_adapter *pmadapter, } } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { /* To send a command, the driver will: 1. driver prepare the cmdrep buffer for adma @@ -2697,7 +2699,7 @@ static mlan_status wlan_pcie_process_cmd_resp(mlan_adapter *pmadapter) } } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { /* Clear the cmd-rsp buffer address in adma registers. This will prevent firmware from writing to the same @@ -2765,7 +2767,7 @@ static t_u8 wlan_check_evt_buffer(mlan_adapter *pmadapter, t_u32 rdptr) return MFALSE; } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { if ((pmadapter->pcard_pcie->evtbd_rdptr & ADMA_RW_PTR_WRAP_MASK) != (rdptr & ADMA_RW_PTR_WRAP_MASK)) @@ -2793,7 +2795,7 @@ static mlan_status wlan_pcie_process_event_ready(mlan_adapter *pmadapter) #if defined(PCIE8997) || defined(PCIE8897) mlan_pcie_evt_buf *pevtbd_buf; #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) adma_dual_desc_buf *padma_bd_buf; #endif ENTER(); @@ -2819,7 +2821,7 @@ static mlan_status wlan_pcie_process_event_ready(mlan_adapter *pmadapter) LEAVE(); return MLAN_STATUS_FAILURE; } -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) rdptr = rdptr >> ADMA_RPTR_START; #endif @@ -2850,7 +2852,7 @@ static mlan_status wlan_pcie_process_event_ready(mlan_adapter *pmadapter) } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { padma_bd_buf = (adma_dual_desc_buf *)pmadapter->pcard_pcie @@ -2899,7 +2901,7 @@ static mlan_status wlan_pcie_process_event_ready(mlan_adapter *pmadapter) } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) pmadapter->pcard_pcie->evtbd_rdptr &= ADMA_RW_PTR_WRAP_MASK; @@ -2944,7 +2946,7 @@ static mlan_status wlan_pcie_event_complete(mlan_adapter *pmadapter, #if defined(PCIE8997) || defined(PCIE8897) mlan_pcie_evt_buf *pevtbd_buf; #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) adma_dual_desc_buf *padma_bd_buf; #endif @@ -2968,7 +2970,7 @@ static mlan_status wlan_pcie_event_complete(mlan_adapter *pmadapter, ret = MLAN_STATUS_FAILURE; goto done; } -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) rdptr = rdptr >> ADMA_RPTR_START; #endif @@ -2998,7 +3000,7 @@ static mlan_status wlan_pcie_event_complete(mlan_adapter *pmadapter, } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { padma_bd_buf = (adma_dual_desc_buf *)pmadapter ->pcard_pcie->evtbd_ring[wrptr]; @@ -3034,7 +3036,7 @@ static mlan_status wlan_pcie_event_complete(mlan_adapter *pmadapter, } } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) pmadapter->pcard_pcie->evtbd_wrptr &= ADMA_RW_PTR_WRAP_MASK; #endif @@ -3267,6 +3269,10 @@ static mlan_status wlan_pcie_prog_fw_w_helper(mlan_adapter *pmadapter, if (IS_PCIE9097(pmadapter->card_type)) check_fw_status = MTRUE; #endif +#if defined(PCIENW62X) + if (IS_PCIENW62X(pmadapter->card_type)) + check_fw_status = MTRUE; +#endif /* Perform firmware data transfer */ do { @@ -3475,18 +3481,21 @@ mlan_status wlan_get_pcie_device(pmlan_adapter pmadapter) pmadapter->pcard_pcie->txrx_bd_size = MAX_TXRX_BD; break; #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) case CARD_TYPE_PCIE9097: case CARD_TYPE_PCIE9098: + case CARD_TYPE_PCIENW62X: pmadapter->pcard_pcie->reg = &mlan_reg_pcie9098; pmadapter->pcard_info = &mlan_card_info_pcie9098; pmadapter->pcard_pcie->txrx_bd_size = ADMA_DEF_TXRX_BD; pmadapter->pcard_pcie->txrx_num_desc = TXRX_DEF_NUM_DESC; -#ifdef PCIE9097 - if (card_type == CARD_TYPE_PCIE9097 && - pmadapter->card_rev == CHIP_9097_REV_B0) +#if defined(PCIE9097) || defined(PCIENW62X) + if ((card_type == CARD_TYPE_PCIE9097 && + pmadapter->card_rev == CHIP_9097_REV_B0) || + (card_type == CARD_TYPE_PCIENW62X)) pmadapter->pcard_pcie->reg = &mlan_reg_pcie9097_b0; #endif + break; #endif default: @@ -3662,7 +3671,7 @@ mlan_status wlan_process_msix_int(mlan_adapter *pmadapter) if (ret) goto done; } -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->host_intr_cmd_dnld && (pcie_ireg & pmadapter->pcard_pcie->reg->host_intr_cmd_dnld)) { if (pmadapter->cmd_sent) @@ -3786,7 +3795,7 @@ static mlan_status wlan_process_pcie_int_status(mlan_adapter *pmadapter) if (ret) goto done; } -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->host_intr_cmd_dnld && (pcie_ireg & pmadapter->pcard_pcie->reg->host_intr_cmd_dnld)) { @@ -3947,7 +3956,7 @@ static mlan_status wlan_pcie_check_fw_status(mlan_adapter *pmadapter, ret = MLAN_STATUS_SUCCESS; break; } else { - wlan_mdelay(pmadapter, 100); + wlan_mdelay(pmadapter, 10); ret = MLAN_STATUS_FAILURE; } } @@ -4082,7 +4091,7 @@ mlan_status wlan_pcie_host_to_card(pmlan_private pmpriv, t_u8 type, ret = wlan_pcie_send_data(pmadapter, type, pmbuf, tx_param); else if (type == MLAN_TYPE_CMD) ret = wlan_pcie_send_cmd(pmadapter, pmbuf); -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) else if (type == MLAN_TYPE_VDLL) ret = wlan_pcie_send_vdll(pmadapter, pmbuf); #endif @@ -4210,8 +4219,9 @@ mlan_status wlan_alloc_pcie_ring_buf(pmlan_adapter pmadapter) mlan_status ret = MLAN_STATUS_SUCCESS; ENTER(); -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if ((pmadapter->card_type == CARD_TYPE_PCIE9098) || + (pmadapter->card_type == CARD_TYPE_PCIENW62X) || (pmadapter->card_type == CARD_TYPE_PCIE9097)) { wlan_pcie_init_adma_ring_size(pmadapter); } @@ -4267,7 +4277,8 @@ mlan_status wlan_free_pcie_ring_buf(pmlan_adapter pmadapter) pmadapter->pcard_pcie->cmdrsp_buf = MNULL; #ifdef RPTR_MEM_COP if ((pmadapter->card_type == CARD_TYPE_PCIE9098) || - (pmadapter->card_type == CARD_TYPE_PCIE9097)) + (pmadapter->card_type == + CARD_TYPE_PCIENW62X)(pmadapter->card_type == CARD_TYPE_PCIE9097)) wlan_pcie_free_rdptrs(pmadapter); #endif @@ -4351,7 +4362,7 @@ mlan_status wlan_set_pcie_buf_config(mlan_private *pmpriv) } } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (pmadapter->pcard_pcie->reg->use_adma) { /** config ADMA for Tx Data */ wlan_init_adma(pmadapter, ADMA_TX_DATA, diff --git a/mxm_wifiex/wlan_src/mlan/mlan_pcie.h b/mxm_wifiex/wlan_src/mlan/mlan_pcie.h index 18915d4..bd17a18 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_pcie.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_pcie.h @@ -182,7 +182,7 @@ Change log: /** PF start bit */ #define ADMA_MSIX_PF_BIT 24 -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) /** PCIE9098 dev_id/vendor id reg */ #define PCIE9098_DEV_ID_REG 0x0000 /** PCIE revision ID register */ diff --git a/mxm_wifiex/wlan_src/mlan/mlan_scan.c b/mxm_wifiex/wlan_src/mlan/mlan_scan.c index 389ad67..9b5fc7e 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_scan.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_scan.c @@ -6,7 +6,7 @@ * for sending scan commands to the firmware. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -150,9 +150,9 @@ static t_u8 rsn_oui[CIPHER_SUITE_MAX][4] = { * @return Band type conversion of scanBand used in join/assoc cmds * */ -t_u8 radio_type_to_band(t_u8 radio_type) +t_u16 radio_type_to_band(t_u8 radio_type) { - t_u8 ret_band; + t_u16 ret_band; switch (radio_type) { case BAND_5GHZ: @@ -375,7 +375,7 @@ static t_u8 is_wpa_oui_present(mlan_adapter *pmadapter, */ static t_u8 wlan_is_band_compatible(t_u8 cfg_band, t_u8 scan_band) { - t_u8 band; + t_u16 band; switch (scan_band) { case BAND_A: band = BAND_A | BAND_AN | BAND_AAC; @@ -466,7 +466,7 @@ static t_u8 wlan_scan_create_channel_list( t_u32 next_chan; t_u8 scan_type; t_u8 radio_type; - t_u8 band; + t_u16 band; t_u16 scan_dur = 0; ENTER(); @@ -573,6 +573,7 @@ static t_u8 wlan_scan_create_channel_list( .chan_scan_mode.passive_to_active_scan = MTRUE; } + pscan_chan_list[chan_idx].max_scan_time = wlan_cpu_to_le16(scan_dur); @@ -680,6 +681,14 @@ wlan_scan_channel_list(mlan_private *pmpriv, t_void *pioctl_buf, t_u32 done_early; t_u32 cmd_no; t_u32 first_chan = 1; + t_u8 *ptlv_pos; + MrvlIETypes_HTCap_t *pht_cap; + + MrvlIETypes_VHTCap_t *pvht_cap; + MrvlIEtypes_Extension_t *phe_cap; + t_u16 len = 0; + t_u8 radio_type = 0; + mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks; ENTER(); @@ -753,7 +762,7 @@ wlan_scan_channel_list(mlan_private *pmpriv, t_void *pioctl_buf, MTRUE; first_chan = 0; } - + radio_type = ptmp_chan_list->bandcfg.chanBand; PRINTM(MCMD_D, "Scan: Chan(%3d), bandcfg(%x), Mode(%d,%d), Dur(%d)\n", ptmp_chan_list->chan_number, @@ -966,9 +975,10 @@ wlan_scan_channel_list(mlan_private *pmpriv, t_void *pioctl_buf, /* The total scan time should be less than scan command timeout * value */ - if (total_scan_time > MRVDRV_MAX_TOTAL_SCAN_TIME) { + if (!total_scan_time || + total_scan_time > MRVDRV_MAX_TOTAL_SCAN_TIME) { PRINTM(MMSG, - "Total scan time %d ms is over limit (%d ms), scan skipped\n", + "Total scan time %d ms is invalid, limit (%d ms), scan skipped\n", total_scan_time, MRVDRV_MAX_TOTAL_SCAN_TIME); if (pioctl_req) pioctl_req->status_code = @@ -976,10 +986,59 @@ wlan_scan_channel_list(mlan_private *pmpriv, t_void *pioctl_buf, ret = MLAN_STATUS_FAILURE; break; } + ptlv_pos = (t_u8 *)pchan_tlv_out + pchan_tlv_out->header.len + + sizeof(MrvlIEtypesHeader_t); pchan_tlv_out->header.len = wlan_cpu_to_le16(pchan_tlv_out->header.len); + if (ISSUPP_11NENABLED(pmpriv->adapter->fw_cap_info) && + (pmpriv->config_bands & BAND_GN || + pmpriv->config_bands & BAND_AN)) { + pht_cap = (MrvlIETypes_HTCap_t *)ptlv_pos; + memset(pmadapter, pht_cap, 0, + sizeof(MrvlIETypes_HTCap_t)); + pht_cap->header.type = wlan_cpu_to_le16(HT_CAPABILITY); + pht_cap->header.len = sizeof(HTCap_t); + wlan_fill_ht_cap_tlv(pmpriv, pht_cap, + pmpriv->config_bands, MTRUE); + HEXDUMP("SCAN: HT_CAPABILITIES IE", (t_u8 *)pht_cap, + sizeof(MrvlIETypes_HTCap_t)); + ptlv_pos += sizeof(MrvlIETypes_HTCap_t); + pht_cap->header.len = + wlan_cpu_to_le16(pht_cap->header.len); + } + + if (ISSUPP_11ACENABLED(pmpriv->adapter->fw_cap_info) && + (pmpriv->config_bands & BAND_AAC)) { + pvht_cap = (MrvlIETypes_VHTCap_t *)ptlv_pos; + memset(pmadapter, pvht_cap, 0, + sizeof(MrvlIETypes_VHTCap_t)); + pvht_cap->header.type = + wlan_cpu_to_le16(VHT_CAPABILITY); + pvht_cap->header.len = sizeof(VHT_capa_t); + wlan_fill_vht_cap_tlv(pmpriv, pvht_cap, + pmpriv->config_bands, MFALSE, + MFALSE); + HEXDUMP("SCAN: VHT_CAPABILITIES IE", (t_u8 *)pvht_cap, + sizeof(MrvlIETypes_VHTCap_t)); + ptlv_pos += sizeof(MrvlIETypes_VHTCap_t); + pvht_cap->header.len = + wlan_cpu_to_le16(pvht_cap->header.len); + } + + if (IS_FW_SUPPORT_11AX(pmadapter)) { + phe_cap = (MrvlIEtypes_Extension_t *)ptlv_pos; + len = wlan_fill_he_cap_tlv(pmpriv, pmpriv->config_bands, + phe_cap, MFALSE); + HEXDUMP("SCAN: HE_CAPABILITIES IE", (t_u8 *)phe_cap, + len); + ptlv_pos += len; + } + + pscan_cfg_out->tlv_buf_len = + (t_u32)((t_u8 *)ptlv_pos - pscan_cfg_out->tlv_buf); + pmadapter->pscan_channels = pstart_chan; /* Send the scan command to the firmware with the specified cfg @@ -1076,13 +1135,8 @@ static mlan_status wlan_scan_setup_scan_config( t_u8 ssid_filter; WLAN_802_11_RATES rates; t_u32 rates_size; - MrvlIETypes_HTCap_t *pht_cap; - - MrvlIETypes_VHTCap_t *pvht_cap; MrvlIEtypes_ScanChanGap_t *pscan_gap_tlv; MrvlIEtypes_BssMode_t *pbss_mode; - MrvlIEtypes_Extension_t *phe_cap; - t_u16 len = 0; t_u8 num_of_channel = 0; ENTER(); @@ -1337,43 +1391,6 @@ static mlan_status wlan_scan_setup_scan_config( PRINTM(MINFO, "SCAN_CMD: Rates size = %d\n", rates_size); - if (ISSUPP_11NENABLED(pmpriv->adapter->fw_cap_info) && - (pmpriv->config_bands & BAND_GN || - pmpriv->config_bands & BAND_AN)) { - pht_cap = (MrvlIETypes_HTCap_t *)ptlv_pos; - memset(pmadapter, pht_cap, 0, sizeof(MrvlIETypes_HTCap_t)); - pht_cap->header.type = wlan_cpu_to_le16(HT_CAPABILITY); - pht_cap->header.len = sizeof(HTCap_t); - wlan_fill_ht_cap_tlv(pmpriv, pht_cap, pmpriv->config_bands, - MTRUE); - HEXDUMP("SCAN: HT_CAPABILITIES IE", (t_u8 *)pht_cap, - sizeof(MrvlIETypes_HTCap_t)); - ptlv_pos += sizeof(MrvlIETypes_HTCap_t); - pht_cap->header.len = wlan_cpu_to_le16(pht_cap->header.len); - } - - if (ISSUPP_11ACENABLED(pmpriv->adapter->fw_cap_info) && - (pmpriv->config_bands & BAND_AAC)) { - pvht_cap = (MrvlIETypes_VHTCap_t *)ptlv_pos; - memset(pmadapter, pvht_cap, 0, sizeof(MrvlIETypes_VHTCap_t)); - pvht_cap->header.type = wlan_cpu_to_le16(VHT_CAPABILITY); - pvht_cap->header.len = sizeof(VHT_capa_t); - wlan_fill_vht_cap_tlv(pmpriv, pvht_cap, pmpriv->config_bands, - MFALSE, MFALSE); - HEXDUMP("SCAN: VHT_CAPABILITIES IE", (t_u8 *)pvht_cap, - sizeof(MrvlIETypes_VHTCap_t)); - ptlv_pos += sizeof(MrvlIETypes_VHTCap_t); - pvht_cap->header.len = wlan_cpu_to_le16(pvht_cap->header.len); - } - - if (IS_FW_SUPPORT_11AX(pmadapter) && - (pmpriv->config_bands & BAND_AAX)) { - phe_cap = (MrvlIEtypes_Extension_t *)ptlv_pos; - len = wlan_fill_he_cap_tlv(pmpriv, BAND_A, phe_cap, MFALSE); - HEXDUMP("SCAN: HE_CAPABILITIES IE", (t_u8 *)phe_cap, len); - ptlv_pos += len; - } - if (wlan_is_ext_capa_support(pmpriv)) wlan_add_ext_capa_info_ie(pmpriv, MNULL, &ptlv_pos); if (pmpriv->adapter->ecsa_enable) { @@ -1480,7 +1497,9 @@ static mlan_status wlan_scan_setup_scan_config( } } - if (wlan_is_chan_passive(pmpriv, radio_type, channel)) { + if (wlan_is_chan_passive(pmpriv, + radio_type_to_band(radio_type), + channel)) { /* do not send probe requests on this channel */ scan_type = MLAN_SCAN_TYPE_PASSIVE; } @@ -1576,8 +1595,6 @@ static mlan_status wlan_scan_setup_scan_config( *pfiltered_scan); PRINTM(MCMND, "Scan: Creating full region channel list %d\n", num_of_channel); - if (num_of_channel > MRVDRV_MAX_CHANNELS_PER_SCAN) - pmadapter->ext_scan_type = EXT_SCAN_DEFAULT; } LEAVE(); @@ -4193,28 +4210,18 @@ mlan_status wlan_scan_networks(mlan_private *pmpriv, t_void *pioctl_buf, /* Get scan command from scan_pending_q and put to cmd_pending_q */ if (ret == MLAN_STATUS_SUCCESS) { - if (pmadapter->ext_scan && pmadapter->ext_scan_enh && - pmadapter->ext_scan_type == EXT_SCAN_ENHANCE) { - wlan_request_cmd_lock(pmadapter); + wlan_request_cmd_lock(pmadapter); + if (util_peek_list(pmadapter->pmoal_handle, + &pmadapter->scan_pending_q, MNULL, MNULL)) { + pcmd_node = (cmd_ctrl_node *)util_dequeue_list( + pmadapter->pmoal_handle, + &pmadapter->scan_pending_q, MNULL, MNULL); pmadapter->pscan_ioctl_req = pioctl_req; pmadapter->scan_processing = MTRUE; - wlan_release_cmd_lock(pmadapter); - } else { - wlan_request_cmd_lock(pmadapter); - if (util_peek_list(pmadapter->pmoal_handle, - &pmadapter->scan_pending_q, MNULL, - MNULL)) { - pcmd_node = (cmd_ctrl_node *)util_dequeue_list( - pmadapter->pmoal_handle, - &pmadapter->scan_pending_q, MNULL, - MNULL); - pmadapter->pscan_ioctl_req = pioctl_req; - pmadapter->scan_processing = MTRUE; - wlan_insert_cmd_to_pending_q(pmadapter, - pcmd_node, MTRUE); - } - wlan_release_cmd_lock(pmadapter); + wlan_insert_cmd_to_pending_q(pmadapter, pcmd_node, + MTRUE); } + wlan_release_cmd_lock(pmadapter); } if (pscan_cfg_out) pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)pscan_cfg_out); @@ -4476,7 +4483,7 @@ mlan_status wlan_ret_802_11_scan(mlan_private *pmpriv, HostCmd_DS_COMMAND *resp, chan_freq_power_t *cfp; MrvlIEtypes_ChanBandListParamSet_t *pchan_band_tlv = MNULL; ChanBandParamSet_t *pchan_band; - t_u8 band; + t_u16 band; t_u8 is_bgscan_resp; t_u32 age_ts_usec; t_u8 null_ssid[MLAN_MAX_SSID_LENGTH] = {0}; @@ -4598,7 +4605,7 @@ mlan_status wlan_ret_802_11_scan(mlan_private *pmpriv, HostCmd_DS_COMMAND *resp, bss_new_entry->bss_band = band; bss_new_entry->age_in_secs = pmadapter->age_in_secs; cfp = wlan_find_cfp_by_band_and_channel( - pmadapter, (t_u8)bss_new_entry->bss_band, + pmadapter, bss_new_entry->bss_band, (t_u16)bss_new_entry->channel); if (cfp) bss_new_entry->freq = cfp->freq; @@ -5509,7 +5516,7 @@ static mlan_status wlan_parse_ext_scan_result(mlan_private *pmpriv, MrvlIEtypes_Data_t *ptlv = MNULL; MrvlIEtypes_Bss_Scan_Rsp_t *pscan_rsp_tlv = MNULL; MrvlIEtypes_Bss_Scan_Info_t *pscan_info_tlv = MNULL; - t_u8 band; + t_u16 band; t_u32 age_ts_usec; ENTER(); @@ -5666,7 +5673,7 @@ static mlan_status wlan_parse_ext_scan_result(mlan_private *pmpriv, bss_new_entry->age_in_secs = pmadapter->age_in_secs; cfp = wlan_find_cfp_by_band_and_channel( - pmadapter, (t_u8)bss_new_entry->bss_band, + pmadapter, bss_new_entry->bss_band, (t_u16)bss_new_entry->channel); if (cfp) bss_new_entry->freq = cfp->freq; @@ -5849,6 +5856,7 @@ mlan_status wlan_handle_event_ext_scan_status(mlan_private *pmpriv, MrvlIEtypesHeader_t *tlv; MrvlIEtypes_ChannelStats_t *tlv_chan_stats; t_u8 status; + cmd_ctrl_node *pcmd_node = MNULL; ENTER(); @@ -5892,6 +5900,46 @@ mlan_status wlan_handle_event_ext_scan_status(mlan_private *pmpriv, } done: + wlan_request_cmd_lock(pmadapter); + if (util_peek_list(pmadapter->pmoal_handle, &pmadapter->scan_pending_q, + MNULL, MNULL)) { + /* If firmware not ready, do not issue any more scan + * commands */ + if (pmadapter->hw_status != WlanHardwareStatusReady) { + wlan_release_cmd_lock(pmadapter); + /* Flush all pending scan commands */ + wlan_flush_scan_queue(pmadapter); + wlan_request_cmd_lock(pmadapter); + pmadapter->scan_processing = MFALSE; + pioctl_req = pmadapter->pscan_ioctl_req; + pmadapter->pscan_ioctl_req = MNULL; + /* Indicate IOCTL complete */ + if (pioctl_req != MNULL) { + pioctl_req->status_code = + MLAN_ERROR_FW_NOT_READY; + + /* Indicate ioctl complete */ + pcb->moal_ioctl_complete( + pmadapter->pmoal_handle, + (pmlan_ioctl_req)pioctl_req, + MLAN_STATUS_FAILURE); + } + wlan_release_cmd_lock(pmadapter); + } else { + /* Get scan command from scan_pending_q and put + * to cmd_pending_q */ + pcmd_node = (cmd_ctrl_node *)util_dequeue_list( + pmadapter->pmoal_handle, + &pmadapter->scan_pending_q, MNULL, MNULL); + wlan_insert_cmd_to_pending_q(pmadapter, pcmd_node, + MTRUE); + wlan_release_cmd_lock(pmadapter); + } + LEAVE(); + return ret; + } + wlan_release_cmd_lock(pmadapter); + /* Now we got response from FW, cancel the command timer */ if (!pmadapter->curr_cmd && pmadapter->cmd_timer_is_set) { /* Cancel command timeout timer */ @@ -5995,7 +6043,7 @@ wlan_bgscan_create_channel_list(mlan_private *pmpriv, t_u32 next_chan; t_u8 scan_type; t_u8 radio_type; - t_u8 band; + t_u16 band; ENTER(); @@ -6154,7 +6202,7 @@ mlan_status wlan_cmd_bgscan_config(mlan_private *pmpriv, t_u8 radio_type; t_u16 scan_dur; t_u8 scan_type; - t_u8 band; + t_u16 band; const t_u8 zero_mac[6] = {0, 0, 0, 0, 0, 0}; ENTER(); @@ -6378,10 +6426,10 @@ mlan_status wlan_cmd_bgscan_config(mlan_private *pmpriv, pvht_cap->header.len = wlan_cpu_to_le16(pvht_cap->header.len); } - if (IS_FW_SUPPORT_11AX(pmadapter) && - (pmpriv->config_bands & BAND_AAX)) { + if (IS_FW_SUPPORT_11AX(pmadapter)) { phe_cap = (MrvlIEtypes_Extension_t *)tlv; - len = wlan_fill_he_cap_tlv(pmpriv, BAND_A, phe_cap, MFALSE); + len = wlan_fill_he_cap_tlv(pmpriv, pmpriv->config_bands, + phe_cap, MFALSE); DBG_HEXDUMP(MCMD_D, "BGSCAN: HE_CAPABILITIES IE", (t_u8 *)phe_cap, len); tlv += len; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sdio.c b/mxm_wifiex/wlan_src/mlan/mlan_sdio.c index fed31b0..ab06d6c 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sdio.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sdio.c @@ -221,8 +221,8 @@ static const struct _mlan_card_info mlan_card_info_sd8897 = { #endif #if defined(SD8977) || defined(SD8997) || defined(SD8987) || \ - defined(SD9098) || defined(SD9097) || defined(SD8978) || \ - defined(SD9177) + defined(SD9098) || defined(SD9097) || defined(SDNW62X) || \ + defined(SD8978) || defined(SD9177) static const struct _mlan_sdio_card_reg mlan_reg_sd8977_sd8997 = { .start_rd_port = 0, .start_wr_port = 0, @@ -309,6 +309,17 @@ static const struct _mlan_card_info mlan_card_info_sd9097 = { .default_11n_tx_bf_cap = DEFAULT_11N_TX_BF_CAP_2X2, }; #endif + +#ifdef SDNW62X +static const struct _mlan_card_info mlan_card_info_sdnw62x = { + .max_tx_buf_size = MLAN_TX_DATA_BUF_SIZE_4K, + .v16_fw_api = 1, + .v17_fw_api = 1, + .supp_ps_handshake = 0, + .default_11n_tx_bf_cap = DEFAULT_11N_TX_BF_CAP_2X2, +}; +#endif + #ifdef SD9098 static const struct _mlan_card_info mlan_card_info_sd9098 = { .max_tx_buf_size = MLAN_TX_DATA_BUF_SIZE_4K, @@ -1024,14 +1035,12 @@ static mlan_status wlan_sdio_prog_fw_w_helper(pmlan_adapter pmadapter, t_u8 *fw, check_fw_status = MTRUE; } #endif -#if defined(SD9097) - if (IS_SD9097(pmadapter->card_type)) - check_fw_status = MTRUE; -#endif -#if defined(SD9177) - if (IS_SD9177(pmadapter->card_type)) +#if defined(SD9097) || defined(SD9177) || defined(SDNW62X) + if (IS_SD9097(pmadapter->card_type) || + IS_SDNW62X(pmadapter->card_type) || IS_SD9177(pmadapter->card_type)) check_fw_status = MTRUE; #endif + /* Perform firmware data transfer */ do { /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY bits @@ -2408,6 +2417,12 @@ mlan_status wlan_get_sdio_device(pmlan_adapter pmadapter) pmadapter->pcard_info = &mlan_card_info_sd9097; break; #endif +#ifdef SDNW62X + case CARD_TYPE_SDNW62X: + pmadapter->pcard_sd->reg = &mlan_reg_sd8977_sd8997; + pmadapter->pcard_info = &mlan_card_info_sdnw62x; + break; +#endif #ifdef SD9177 case CARD_TYPE_SD9177: pmadapter->pcard_sd->reg = &mlan_reg_sd8977_sd8997; @@ -3017,7 +3032,7 @@ exit: return ret; } -#if (defined(SD9098) || defined(SD9097) || defined(SD9177)) +#if (defined(SD9098) || defined(SD9097) || defined(SDNW62X) || defined(SD9177)) /** * @brief This function sends vdll data to the card. * @@ -3078,7 +3093,7 @@ static mlan_status wlan_sdio_host_to_card_ext(pmlan_private pmpriv, t_u8 type, mlan_status ret = MLAN_STATUS_SUCCESS; mlan_adapter *pmadapter = pmpriv->adapter; -#if (defined(SD9098) || defined(SD9097) || defined(SD9177)) +#if (defined(SD9098) || defined(SD9097) || defined(SDNW62X) || defined(SD9177)) if (type == MLAN_TYPE_VDLL) return wlan_sdio_send_vdll(pmadapter, pmbuf); #endif @@ -3541,8 +3556,8 @@ mlan_status wlan_reset_fw(pmlan_adapter pmadapter) goto done; } #if defined(SD8997) || defined(SD8977) || defined(SD8987) || \ - defined(SD9098) || defined(SD9097) || defined(SD8978) || \ - defined(SD9177) + defined(SD9098) || defined(SD9097) || defined(SDNW62X) || \ + defined(SD8978) || defined(SD9177) if (MFALSE #ifdef SD8997 || IS_SD8997(pmadapter->card_type) @@ -3562,6 +3577,9 @@ mlan_status wlan_reset_fw(pmlan_adapter pmadapter) #ifdef SD9097 || IS_SD9097(pmadapter->card_type) #endif +#ifdef SDNW62X + || IS_SDNW62X(pmadapter->card_type) +#endif #ifdef SD9177 || IS_SD9177(pmadapter->card_type) #endif diff --git a/mxm_wifiex/wlan_src/mlan/mlan_shim.c b/mxm_wifiex/wlan_src/mlan/mlan_shim.c index e513638..f4689d2 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_shim.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_shim.c @@ -481,24 +481,40 @@ mlan_status mlan_register(pmlan_device pmdevice, t_void **ppmlan_adapter) memset(pmadapter, pmadapter->priv[0], 0, sizeof(mlan_private)); pmadapter->priv[0]->adapter = pmadapter; - pmadapter->priv[0]->bss_type = (t_u8)pmdevice->bss_attr[0].bss_type; - pmadapter->priv[0]->frame_type = (t_u8)pmdevice->bss_attr[0].frame_type; - pmadapter->priv[0]->bss_priority = - (t_u8)pmdevice->bss_attr[0].bss_priority; - if (pmdevice->bss_attr[0].bss_type == MLAN_BSS_TYPE_STA) + if (pmdevice->drv_mode & DRV_MODE_MASK) { + /* Save bss_type, frame_type & bss_priority */ + pmadapter->priv[0]->bss_type = 0xff; + pmadapter->priv[0]->frame_type = MLAN_DATA_FRAME_TYPE_ETH_II; + pmadapter->priv[0]->bss_priority = 0; pmadapter->priv[0]->bss_role = MLAN_BSS_ROLE_STA; - else if (pmdevice->bss_attr[0].bss_type == MLAN_BSS_TYPE_UAP) - pmadapter->priv[0]->bss_role = MLAN_BSS_ROLE_UAP; + + /* Save bss_index and bss_num */ + pmadapter->priv[0]->bss_index = 0; + pmadapter->priv[0]->bss_num = 0xff; + } else { + pmadapter->priv[0]->bss_type = + (t_u8)pmdevice->bss_attr[0].bss_type; + pmadapter->priv[0]->frame_type = + (t_u8)pmdevice->bss_attr[0].frame_type; + pmadapter->priv[0]->bss_priority = + (t_u8)pmdevice->bss_attr[0].bss_priority; + if (pmdevice->bss_attr[0].bss_type == MLAN_BSS_TYPE_STA) + pmadapter->priv[0]->bss_role = MLAN_BSS_ROLE_STA; + else if (pmdevice->bss_attr[0].bss_type == MLAN_BSS_TYPE_UAP) + pmadapter->priv[0]->bss_role = MLAN_BSS_ROLE_UAP; #ifdef WIFI_DIRECT_SUPPORT - else if (pmdevice->bss_attr[0].bss_type == MLAN_BSS_TYPE_WIFIDIRECT) { - pmadapter->priv[0]->bss_role = MLAN_BSS_ROLE_STA; - if (pmdevice->bss_attr[0].bss_virtual) - pmadapter->priv[0]->bss_virtual = MTRUE; - } + else if (pmdevice->bss_attr[0].bss_type == + MLAN_BSS_TYPE_WIFIDIRECT) { + pmadapter->priv[0]->bss_role = MLAN_BSS_ROLE_STA; + if (pmdevice->bss_attr[0].bss_virtual) + pmadapter->priv[0]->bss_virtual = MTRUE; + } #endif - /* Save bss_index and bss_num */ - pmadapter->priv[0]->bss_index = 0; - pmadapter->priv[0]->bss_num = (t_u8)pmdevice->bss_attr[0].bss_num; + /* Save bss_index and bss_num */ + pmadapter->priv[0]->bss_index = 0; + pmadapter->priv[0]->bss_num = + (t_u8)pmdevice->bss_attr[0].bss_num; + } /* init function table */ for (j = 0; mlan_ops[j]; j++) { diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sta_cmd.c b/mxm_wifiex/wlan_src/mlan/mlan_sta_cmd.c index e312810..7e9c00f 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sta_cmd.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sta_cmd.c @@ -5,7 +5,7 @@ * it is ready. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -291,6 +291,16 @@ static mlan_status wlan_cmd_802_11_snmp_mib(pmlan_private pmpriv, cmd->size += sizeof(t_u8); } break; + case ChanTrackParam_i: + psnmp_mib->oid = wlan_cpu_to_le16((t_u16)ChanTrackParam_i); + if (cmd_action == HostCmd_ACT_GEN_SET) { + psnmp_mib->query_type = + wlan_cpu_to_le16(HostCmd_ACT_GEN_SET); + psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u8)); + psnmp_mib->value[0] = *(t_u8 *)pdata_buf; + cmd->size += sizeof(t_u8); + } + break; default: break; } @@ -1620,6 +1630,11 @@ static mlan_status wlan_cmd_mgmt_ie_list(pmlan_private pmpriv, pmgmt_ie_list->ds_mgmt_ie.len = wlan_cpu_to_le16(cust_ie->len); req_len = cust_ie->len; + if (req_len > sizeof(cust_ie->ie_data_list)) { + PRINTM(MERROR, "Invalid cust_ie->len=%d\n", req_len); + LEAVE(); + return MLAN_STATUS_FAILURE; + } travel_len = 0; /* conversion for index, mask, len */ if (req_len == sizeof(t_u16)) @@ -1864,6 +1879,8 @@ static mlan_status wlan_cmd_tdls_oper(pmlan_private pmpriv, MrvlIETypes_VHTCap_t *VHTcap_tlv = MNULL; MrvlIETypes_VHTOprat_t *VHTOper_tlv = MNULL; MrvlIETypes_AID_t *AidInfo = MNULL; + MrvlIEtypes_Extension_t *hecap_tlv = MNULL; + MrvlIEtypes_He_Op_t *heop_tlv = MNULL; MrvlIEtypes_TDLS_Idle_Timeout_t *TdlsIdleTimeout = MNULL; ENTER(); @@ -2058,6 +2075,7 @@ static mlan_status wlan_cmd_tdls_oper(pmlan_private pmpriv, sta_ptr->aid_info.ieee_hdr.len); AidInfo->AID = wlan_cpu_to_le16( sta_ptr->aid_info.AID); + travel_len += sizeof(MrvlIETypes_AID_t); } /* Vht capability */ if (sta_ptr->vht_cap.ieee_hdr.element_id == @@ -2087,7 +2105,8 @@ static mlan_status wlan_cmd_tdls_oper(pmlan_private pmpriv, pbss_desc->bss_band, MTRUE, MTRUE); DBG_HEXDUMP( - MCMD_D, "FW Vhtcap", + MCMD_D, + "TDLS Config Link: VHT Capability", (t_u8 *)VHTcap_tlv, sizeof(MrvlIETypes_VHTCap_t)); } @@ -2104,15 +2123,82 @@ static mlan_status wlan_cmd_tdls_oper(pmlan_private pmpriv, &VHTOper_tlv->chan_width, &sta_ptr->vht_oprat.chan_width, sta_ptr->vht_oprat.ieee_hdr.len, - sizeof(VHTOper_tlv->chan_width)); + (sizeof(MrvlIETypes_VHTOprat_t) - + sizeof(MrvlIEtypesHeader_t))); VHTOper_tlv->basic_MCS_map = wlan_cpu_to_le16( VHTOper_tlv->basic_MCS_map); travel_len += sta_ptr->vht_oprat.ieee_hdr.len + sizeof(MrvlIEtypesHeader_t); - DBG_HEXDUMP(MCMD_D, "VHT operation", + DBG_HEXDUMP(MCMD_D, + "TDLS Config Link: VHT operation", (t_u8 *)VHTOper_tlv, sizeof(MrvlIETypes_VHTOprat_t)); } + /* Check if we need enable the 11AX */ + if (sta_ptr && + (sta_ptr->he_op.ieee_hdr.element_id == EXTENSION) && + (sta_ptr->he_op.ext_id == HE_OPERATION)) { + /* HE Capability */ + hecap_tlv = + (MrvlIEtypes_Extension_t *)(pos + + travel_len); + /* fill the peer HE CAP IE */ + memcpy_ext(pmpriv->adapter, &hecap_tlv->ext_id, + &sta_ptr->tdls_he_cap.ext_id, + sta_ptr->tdls_he_cap.ieee_hdr.len, + sizeof(MrvlIEtypes_He_cap_t) - + sizeof(MrvlIEtypesHeader_t)); + hecap_tlv->type = + wlan_cpu_to_le16(TLV_TYPE_EXTENSION_ID); + hecap_tlv->len = MIN( + sta_ptr->tdls_he_cap.ieee_hdr.len, + sizeof(MrvlIEtypes_He_cap_t) - + sizeof(MrvlIEtypesHeader_t)); + hecap_tlv->len = + wlan_cpu_to_le16(hecap_tlv->len); +#if 0 + wlan_fill_he_cap_tlv(pmpriv, + pmpriv->config_bands, + hecap_tlv, MFALSE); +#endif + + travel_len += wlan_le16_to_cpu(hecap_tlv->len) + + sizeof(MrvlIEtypesHeader_t); + + DBG_HEXDUMP( + MCMD_D, + "TDLS Config Link: HE Capability", + (t_u8 *)hecap_tlv, + wlan_le16_to_cpu(hecap_tlv->len) + + sizeof(MrvlIEtypesHeader_t)); + + /* HE Operation */ + heop_tlv = (MrvlIEtypes_He_Op_t *)(pos + + travel_len); + heop_tlv->header.type = + wlan_cpu_to_le16(EXTENSION); + heop_tlv->header.len = wlan_cpu_to_le16( + sta_ptr->he_op.ieee_hdr.len); + memcpy_ext(pmpriv->adapter, &heop_tlv->ext_id, + &sta_ptr->he_op.ext_id, + sta_ptr->he_op.ieee_hdr.len, + sizeof(MrvlIEtypes_He_Op_t) - + sizeof(MrvlIEtypesHeader_t)); + heop_tlv->he_op_param1 = wlan_cpu_to_le16( + heop_tlv->he_op_param1); + heop_tlv->basic_he_mcs_nss = wlan_cpu_to_le16( + heop_tlv->basic_he_mcs_nss); + travel_len += + wlan_le16_to_cpu(heop_tlv->header.len) + + sizeof(MrvlIEtypesHeader_t); + DBG_HEXDUMP( + MCMD_D, + "TDLS Config Link: HE Operation", + (t_u8 *)heop_tlv, + wlan_le16_to_cpu(heop_tlv->header.len) + + sizeof(MrvlIEtypesHeader_t)); + } + TdlsIdleTimeout = (MrvlIEtypes_TDLS_Idle_Timeout_t *)(pos + travel_len); @@ -2516,6 +2602,87 @@ static mlan_status wlan_cmd_inactivity_timeout(HostCmd_DS_COMMAND *cmd, return MLAN_STATUS_SUCCESS; } +/** + * @brief This function prepares network monitor command + * + * @param pmpriv A pointer to mlan_private structure + * @param cmd A pointer to HostCmd_DS_COMMAND structure + * @param cmd_action the action: GET or SET + * @param pdata_buf A pointer to data buffer + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_cmd_net_monitor(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, + t_u16 cmd_action, t_void *pdata_buf) +{ + mlan_ds_misc_net_monitor *net_mon; + HostCmd_DS_802_11_NET_MONITOR *cmd_net_mon = &cmd->params.net_mon; + ChanBandParamSet_t *pchan_band = MNULL; + t_u8 sec_chan_offset = 0; + t_u32 bw_offset = 0; + + ENTER(); + + net_mon = (mlan_ds_misc_net_monitor *)pdata_buf; + + cmd->size = wlan_cpu_to_le16(S_DS_GEN + + sizeof(HostCmd_DS_802_11_NET_MONITOR)); + cmd->command = wlan_cpu_to_le16(cmd->command); + cmd_net_mon->action = wlan_cpu_to_le16(cmd_action); + if (cmd_action == HostCmd_ACT_GEN_SET) { + cmd_net_mon->enable_net_mon = + wlan_cpu_to_le16((t_u16)net_mon->enable_net_mon); + if (net_mon->enable_net_mon) { + pchan_band = + &cmd_net_mon->monitor_chan.chan_band_param[0]; + cmd_net_mon->filter_flag = + wlan_cpu_to_le16((t_u16)net_mon->filter_flag); + cmd_net_mon->monitor_chan.header.type = + wlan_cpu_to_le16(TLV_TYPE_CHANNELBANDLIST); + cmd_net_mon->monitor_chan.header.len = + wlan_cpu_to_le16(sizeof(ChanBandParamSet_t)); + pchan_band->chan_number = (t_u8)net_mon->channel; + pchan_band->bandcfg.chanBand = + wlan_band_to_radio_type((t_u16)net_mon->band); + + if (net_mon->band & BAND_GN || + net_mon->band & BAND_AN || + net_mon->band & BAND_GAC || + net_mon->band & BAND_AAC) { + bw_offset = net_mon->chan_bandwidth; + if (bw_offset == CHANNEL_BW_40MHZ_ABOVE) { + pchan_band->bandcfg.chan2Offset = + SEC_CHAN_ABOVE; + pchan_band->bandcfg.chanWidth = + CHAN_BW_40MHZ; + } else if (bw_offset == + CHANNEL_BW_40MHZ_BELOW) { + pchan_band->bandcfg.chan2Offset = + SEC_CHAN_BELOW; + pchan_band->bandcfg.chanWidth = + CHAN_BW_40MHZ; + } else if (bw_offset == CHANNEL_BW_80MHZ) { + sec_chan_offset = + wlan_get_second_channel_offset( + pmpriv, + net_mon->channel); + if (sec_chan_offset == SEC_CHAN_ABOVE) + pchan_band->bandcfg.chan2Offset = + SEC_CHAN_ABOVE; + else if (sec_chan_offset == + SEC_CHAN_BELOW) + pchan_band->bandcfg.chan2Offset = + SEC_CHAN_BELOW; + pchan_band->bandcfg.chanWidth = + CHAN_BW_80MHZ; + } + } + } + } + + LEAVE(); + return MLAN_STATUS_SUCCESS; +} + /** * @brief This function prepares Low Power Mode * @@ -2670,25 +2837,6 @@ static mlan_status wlan_cmd_coalesce_config(pmlan_private pmpriv, * Global Functions ********************************************************/ -static mlan_status wlan_cmd_get_sensor_temp(pmlan_private pmpriv, - HostCmd_DS_COMMAND *cmd, - t_u16 cmd_action) -{ - ENTER(); - - if (cmd_action != HostCmd_ACT_GEN_GET) { - PRINTM(MERROR, "wlan_cmd_get_sensor_temp: support GET only.\n"); - LEAVE(); - return MLAN_STATUS_FAILURE; - } - - cmd->command = wlan_cpu_to_le16(HostCmd_DS_GET_SENSOR_TEMP); - cmd->size = wlan_cpu_to_le16(S_DS_GEN + 4); - - LEAVE(); - return MLAN_STATUS_SUCCESS; -} - /** * @brief This function prepares command of arb cfg * @@ -2821,6 +2969,379 @@ static mlan_status wlan_cmd_sta_config(pmlan_private pmpriv, return ret; } +/** + * @brief This function prepare the config tlvs of roam offload. + * + * @param priv A pointer to mlan_private structure + * @param tlv_no TLV type + * @param value Pointer to mlan_ds_misc_roam_offload structure + * @param pointer Value of trigger_condition + * @param size Pointer to the buffer of HostCmd_DS_ROAM_OFFLOAD + * @return N/A + */ +static t_u16 mlan_prepare_roam_offload_tlv(pmlan_private pmpriv, t_u32 type, + mlan_ds_misc_roam_offload *roam, + t_u8 trigger_condition, t_u8 *pos) +{ + MrvlIEtypes_fw_roam_enable_t *enable_tlv = MNULL; + MrvlIEtypes_fw_roam_trigger_condition_t *trigger_condition_tlv = MNULL; + MrvlIEtypes_Bssid_t *bssid_tlv = MNULL; + MrvlIEtypes_SsIdParamSet_t *ssid_tlv = MNULL; + MrvlIEtypes_fw_roam_retry_count_t *retry_count_tlv = MNULL; + MrvlIEtypes_para_rssi_t *rssi_para_tlv = MNULL; + MrvlIEtypes_fw_roam_bgscan_setting_t *bgscan_set_tlv = MNULL; + MrvlIEtypes_roam_blacklist_t *blacklist_tlv = MNULL; + MrvlIEtypes_ees_param_set_t *ees_param_tlv = MNULL; + MrvlIEtypes_band_rssi_t *band_rssi_tlv = MNULL; + MrvlIEtypes_beacon_miss_threshold_t *bcn_miss_threshold_tlv = MNULL; + MrvlIEtypes_pre_beacon_miss_threshold_t *pre_bcn_miss_threshold_tlv = + MNULL; + MrvlIEtypes_RepeatCount_t *tlv_repeat = MNULL; + t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = {0}, *begin; + int i = 0; + + ENTER(); + + begin = pos; + if (type & FW_ROAM_ENABLE) { + enable_tlv = (MrvlIEtypes_fw_roam_enable_t *)pos; + enable_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_ROAM); + enable_tlv->header.len = + wlan_cpu_to_le16(sizeof(MrvlIEtypes_fw_roam_enable_t) - + sizeof(MrvlIEtypesHeader_t)); + if (roam->enable <= ROAM_OFFLOAD_WITHOUT_APLIST) + enable_tlv->roam_enable = roam->enable; + else + enable_tlv->roam_enable = ROAM_OFFLOAD_WITHOUT_APLIST; + pos += sizeof(MrvlIEtypes_fw_roam_enable_t); + } + if (type & FW_ROAM_TRIGGER_COND) { + trigger_condition_tlv = + (MrvlIEtypes_fw_roam_trigger_condition_t *)pos; + trigger_condition_tlv->header.type = + wlan_cpu_to_le16(TLV_TYPE_ROM_TRIGGER); + trigger_condition_tlv->header.len = wlan_cpu_to_le16( + sizeof(trigger_condition_tlv->trigger_condition)); + trigger_condition_tlv->trigger_condition = + wlan_cpu_to_le16(trigger_condition); + pos += sizeof(trigger_condition_tlv->header) + + sizeof(trigger_condition_tlv->trigger_condition); + } + if (type & FW_ROAM_BSSID) { + bssid_tlv = (MrvlIEtypes_Bssid_t *)pos; + bssid_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_BSSID); + bssid_tlv->header.len = + wlan_cpu_to_le16(sizeof(bssid_tlv->bssid)); + if (memcmp(pmpriv->adapter, roam->bssid_reconnect, zero_mac, + sizeof(zero_mac)) != 0) + memcpy_ext(pmpriv->adapter, bssid_tlv->bssid, + roam->bssid_reconnect, + sizeof(bssid_tlv->bssid), + sizeof(bssid_tlv->bssid)); + else { + if (roam->config_mode == ROAM_OFFLOAD_SUSPEND_CFG) + memcpy_ext(pmpriv->adapter, bssid_tlv->bssid, + pmpriv->curr_bss_params + .bss_descriptor.mac_address, + sizeof(bssid_tlv->bssid), + sizeof(bssid_tlv->bssid)); + else if (roam->config_mode == ROAM_OFFLOAD_RESUME_CFG) + memcpy_ext(pmpriv->adapter, bssid_tlv->bssid, + zero_mac, sizeof(bssid_tlv->bssid), + sizeof(bssid_tlv->bssid)); + } + pos += sizeof(bssid_tlv->header) + sizeof(bssid_tlv->bssid); + } + if (type & FW_ROAM_SSID) { + for (i = 0; i < roam->ssid_list.ssid_num; i++) { + ssid_tlv = (MrvlIEtypes_SsIdParamSet_t *)pos; + ssid_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_SSID); + memcpy_ext(pmpriv->adapter, ssid_tlv->ssid, + roam->ssid_list.ssids[i].ssid, + roam->ssid_list.ssids[i].ssid_len, + roam->ssid_list.ssids[i].ssid_len); + pos += sizeof(ssid_tlv->header) + + wlan_strlen(ssid_tlv->ssid); + ssid_tlv->header.len = + wlan_cpu_to_le16(wlan_strlen(ssid_tlv->ssid)); + } + if (!roam->ssid_list.ssid_num) { + ssid_tlv = (MrvlIEtypes_SsIdParamSet_t *)pos; + ssid_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_SSID); + memcpy_ext( + pmpriv->adapter, ssid_tlv->ssid, + pmpriv->curr_bss_params.bss_descriptor.ssid.ssid, + pmpriv->curr_bss_params.bss_descriptor.ssid + .ssid_len, + pmpriv->curr_bss_params.bss_descriptor.ssid + .ssid_len); + ssid_tlv->header.len = + wlan_cpu_to_le16(wlan_strlen(ssid_tlv->ssid)); + pos += sizeof(ssid_tlv->header) + ssid_tlv->header.len; + } + } + if (type & FW_ROAM_RETRY_COUNT) { + retry_count_tlv = (MrvlIEtypes_fw_roam_retry_count_t *)pos; + retry_count_tlv->header.type = + wlan_cpu_to_le16(TLV_TYPE_ROM_RETRY_COUNT); + retry_count_tlv->header.len = + wlan_cpu_to_le16(sizeof(retry_count_tlv->retry_count)); + if (roam->retry_count) + retry_count_tlv->retry_count = + wlan_cpu_to_le16(roam->retry_count); + else + retry_count_tlv->retry_count = + wlan_cpu_to_le16(RETRY_UNLIMITED_TIME); + pos += sizeof(retry_count_tlv->header) + + sizeof(retry_count_tlv->retry_count); + } + if (type & FW_ROAM_RSSI_PARA) { + rssi_para_tlv = (MrvlIEtypes_para_rssi_t *)pos; + rssi_para_tlv->header.type = + wlan_cpu_to_le16(TLV_TYPE_ROM_PARA_RSSI); + rssi_para_tlv->header.len = + wlan_cpu_to_le16(sizeof(rssi_para_tlv->max_rssi) + + sizeof(rssi_para_tlv->min_rssi) + + sizeof(rssi_para_tlv->step_rssi)); + rssi_para_tlv->max_rssi = roam->para_rssi.max_rssi; + rssi_para_tlv->min_rssi = roam->para_rssi.min_rssi; + rssi_para_tlv->step_rssi = roam->para_rssi.step_rssi; + pos += sizeof(rssi_para_tlv->header) + + sizeof(rssi_para_tlv->max_rssi) + + sizeof(rssi_para_tlv->min_rssi) + + sizeof(rssi_para_tlv->step_rssi); + } + if (type & FW_ROAM_BAND_RSSI) { + band_rssi_tlv = (MrvlIEtypes_band_rssi_t *)pos; + band_rssi_tlv->header.type = + wlan_cpu_to_le16(TLV_TYPE_BAND_RSSI); + band_rssi_tlv->header.len = + wlan_cpu_to_le16(sizeof(MrvlIEtypes_band_rssi_t) - + sizeof(MrvlIEtypesHeader_t)); + band_rssi_tlv->band_rssi.band_preferred = + roam->band_rssi.band_preferred; + band_rssi_tlv->band_rssi.rssi_hysteresis = + roam->band_rssi.rssi_hysteresis; + pos += sizeof(MrvlIEtypes_band_rssi_t); + } + + if (type & FW_ROAM_BGSCAN_PARAM) { + bgscan_set_tlv = (MrvlIEtypes_fw_roam_bgscan_setting_t *)pos; + bgscan_set_tlv->header.type = + wlan_cpu_to_le16(TLV_TYPE_ROM_BGSCAN); + bgscan_set_tlv->header.len = wlan_cpu_to_le16( + sizeof(MrvlIEtypes_fw_roam_bgscan_setting_t) - + sizeof(MrvlIEtypesHeader_t)); + bgscan_set_tlv->bss_type = roam->bgscan_cfg.bss_type; + bgscan_set_tlv->channels_perscan = + roam->bgscan_cfg.channels_per_scan; + bgscan_set_tlv->scan_interval = + wlan_cpu_to_le32(roam->bgscan_cfg.scan_interval); + bgscan_set_tlv->report_condition = + wlan_cpu_to_le32(roam->bgscan_cfg.bg_rpt_condition); + pos += sizeof(MrvlIEtypes_fw_roam_bgscan_setting_t); + } + + if (type & FW_ROAM_EES_PARAM) { + ees_param_tlv = (MrvlIEtypes_ees_param_set_t *)pos; + ees_param_tlv->header.type = + wlan_cpu_to_le16(TLV_TYPE_ENERGYEFFICIENTSCAN); + ees_param_tlv->header.len = + wlan_cpu_to_le16(sizeof(MrvlIEtypes_ees_param_set_t) - + sizeof(MrvlIEtypesHeader_t)); + ees_param_tlv->ees_cfg.ees_mode = + wlan_cpu_to_le16(roam->ees_cfg.ees_mode); + ees_param_tlv->ees_cfg.ees_rpt_condition = + wlan_cpu_to_le16(roam->ees_cfg.ees_rpt_condition); + ees_param_tlv->ees_cfg.high_scan_period = + wlan_cpu_to_le16(roam->ees_cfg.high_scan_period); + ees_param_tlv->ees_cfg.high_scan_count = + wlan_cpu_to_le16(roam->ees_cfg.high_scan_count); + ees_param_tlv->ees_cfg.mid_scan_period = + wlan_cpu_to_le16(roam->ees_cfg.mid_scan_period); + ees_param_tlv->ees_cfg.mid_scan_count = + wlan_cpu_to_le16(roam->ees_cfg.mid_scan_count); + ees_param_tlv->ees_cfg.low_scan_period = + wlan_cpu_to_le16(roam->ees_cfg.low_scan_period); + ees_param_tlv->ees_cfg.low_scan_count = + wlan_cpu_to_le16(roam->ees_cfg.low_scan_count); + pos += sizeof(MrvlIEtypes_ees_param_set_t); + } + + if (type & FW_ROAM_BCN_MISS_THRESHOLD) { + bcn_miss_threshold_tlv = + (MrvlIEtypes_beacon_miss_threshold_t *)pos; + bcn_miss_threshold_tlv->header.type = + wlan_cpu_to_le16(TLV_TYPE_BCNMISS); + bcn_miss_threshold_tlv->header.len = wlan_cpu_to_le16( + sizeof(MrvlIEtypes_beacon_miss_threshold_t) - + sizeof(MrvlIEtypesHeader_t)); + bcn_miss_threshold_tlv->bcn_miss_threshold = + roam->bcn_miss_threshold; + pos += sizeof(MrvlIEtypes_beacon_miss_threshold_t); + } + + if (type & FW_ROAM_PRE_BCN_MISS_THRESHOLD) { + pre_bcn_miss_threshold_tlv = + (MrvlIEtypes_pre_beacon_miss_threshold_t *)pos; + pre_bcn_miss_threshold_tlv->header.type = + wlan_cpu_to_le16(TLV_TYPE_PRE_BCNMISS); + pre_bcn_miss_threshold_tlv->header.len = wlan_cpu_to_le16( + sizeof(MrvlIEtypes_pre_beacon_miss_threshold_t) - + sizeof(MrvlIEtypesHeader_t)); + pre_bcn_miss_threshold_tlv->pre_bcn_miss_threshold = + roam->pre_bcn_miss_threshold; + pos += sizeof(MrvlIEtypes_pre_beacon_miss_threshold_t); + } + + if (type & FW_ROAM_BLACKLIST) { + blacklist_tlv = (MrvlIEtypes_roam_blacklist_t *)pos; + blacklist_tlv->header.type = + wlan_cpu_to_le16(TLV_TYPE_BLACKLIST_BSSID); + blacklist_tlv->header.len = + roam->black_list.ap_num * MLAN_MAC_ADDR_LENGTH + + sizeof(roam->black_list.ap_num); + memcpy_ext(pmpriv->adapter, (t_u8 *)&blacklist_tlv->blacklist, + (t_u8 *)&roam->black_list, blacklist_tlv->header.len, + sizeof(blacklist_tlv->blacklist)); + pos += sizeof(MrvlIEtypesHeader_t) + blacklist_tlv->header.len; + blacklist_tlv->header.len = + wlan_cpu_to_le16(blacklist_tlv->header.len); + } + + if (type & FW_ROAM_REPEAT_CNT) { + tlv_repeat = (MrvlIEtypes_RepeatCount_t *)pos; + tlv_repeat->header.type = + wlan_cpu_to_le16(TLV_TYPE_REPEAT_COUNT); + tlv_repeat->header.len = + wlan_cpu_to_le16(sizeof(MrvlIEtypes_RepeatCount_t) - + sizeof(MrvlIEtypesHeader_t)); + tlv_repeat->repeat_count = wlan_cpu_to_le16(roam->repeat_count); + pos += sizeof(MrvlIEtypes_RepeatCount_t); + } + LEAVE(); + return (pos - begin); +} +/** + * @brief This function sends enable/disable roam offload command to firmware. + * + * @param pmpriv A pointer to mlan_private structure + * @param pcmd Hostcmd ID + * @param cmd_action Command action + * @return N/A + */ +static mlan_status wlan_cmd_roam_offload(pmlan_private pmpriv, + HostCmd_DS_COMMAND *cmd, + t_u16 cmd_action, t_void *pdata_buf) +{ + HostCmd_DS_ROAM_OFFLOAD *roam_cmd = &cmd->params.roam_offload; + MrvlIEtypes_roam_aplist_t *aplist = MNULL; + t_u8 *pos = (t_u8 *)roam_cmd + sizeof(roam_cmd->action); + mlan_ds_misc_roam_offload *roam = MNULL; + t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = {0}; + t_u32 type = 0; + t_u8 trigger_condition = 0; + + ENTER(); + + cmd->command = wlan_cpu_to_le16(HostCmd_CMD_ROAM_OFFLOAD); + cmd->size = S_DS_GEN + sizeof(HostCmd_DS_ROAM_OFFLOAD); + roam_cmd->action = wlan_cpu_to_le16(cmd_action); + + roam = (mlan_ds_misc_roam_offload *)pdata_buf; + + if (roam->config_mode) { + switch (roam->config_mode) { + case ROAM_OFFLOAD_ENABLE: + type |= FW_ROAM_ENABLE; + if (roam->enable && roam->enable != AUTO_RECONNECT) { + type |= FW_ROAM_TRIGGER_COND; + trigger_condition |= RSSI_LOW_TRIGGER | + PRE_BEACON_LOST_TRIGGER; + } + break; + case ROAM_OFFLOAD_SUSPEND_CFG: + type |= FW_ROAM_TRIGGER_COND | FW_ROAM_RETRY_COUNT; + if (roam->enable == AUTO_RECONNECT) { + type |= FW_ROAM_BSSID | FW_ROAM_SSID; + trigger_condition = LINK_LOST_TRIGGER | + DEAUTH_WITH_EXT_AP_TRIGGER; + } else + trigger_condition = LINK_LOST_TRIGGER | + DEAUTH_WITH_EXT_AP_TRIGGER | + RSSI_LOW_TRIGGER | + PRE_BEACON_LOST_TRIGGER; + + if (roam->enable == ROAM_OFFLOAD_WITH_BSSID) + type |= FW_ROAM_BSSID; + if (roam->enable == ROAM_OFFLOAD_WITH_SSID) + type |= FW_ROAM_SSID; + break; + case ROAM_OFFLOAD_RESUME_CFG: + type |= FW_ROAM_TRIGGER_COND; + if (roam->enable == AUTO_RECONNECT) + trigger_condition = NO_TRIGGER; + else + trigger_condition = RSSI_LOW_TRIGGER | + PRE_BEACON_LOST_TRIGGER; + if (roam->enable == ROAM_OFFLOAD_WITH_BSSID || + roam->enable == AUTO_RECONNECT) + type |= FW_ROAM_BSSID; + break; + case ROAM_OFFLOAD_PARAM_CFG: + if (roam->enable && roam->enable != AUTO_RECONNECT) { + if (roam->retry_count != 0) + type |= FW_ROAM_RETRY_COUNT; + if (roam->ssid_list.ssid_num) + type |= FW_ROAM_SSID; + if (roam->para_rssi.set_flag) + type |= FW_ROAM_RSSI_PARA; + if (memcmp(pmpriv->adapter, + roam->bssid_reconnect, zero_mac, + sizeof(zero_mac)) != 0) + type |= FW_ROAM_BSSID; + if (roam->band_rssi_flag) + type |= FW_ROAM_BAND_RSSI; + if (roam->bgscan_set_flag) + type |= FW_ROAM_BGSCAN_PARAM; + if (roam->ees_param_set_flag) + type |= FW_ROAM_EES_PARAM; + if (roam->bcn_miss_threshold) + type |= FW_ROAM_BCN_MISS_THRESHOLD; + if (roam->pre_bcn_miss_threshold) + type |= FW_ROAM_PRE_BCN_MISS_THRESHOLD; + if (roam->black_list.ap_num) + type |= FW_ROAM_BLACKLIST; + if (roam->trigger_condition != 0xff) { + type |= FW_ROAM_TRIGGER_COND; + trigger_condition = + roam->trigger_condition; + } + if (roam->repeat_count) + type |= FW_ROAM_REPEAT_CNT; + } + break; + } + cmd->size += mlan_prepare_roam_offload_tlv( + pmpriv, type, roam, trigger_condition, pos); + } + if (roam->aplist.ap_num) { + aplist = (MrvlIEtypes_roam_aplist_t *)pos; + aplist->header.type = wlan_cpu_to_le16(TLV_TYPE_APLIST); + aplist->header.len = roam->aplist.ap_num * MLAN_MAC_ADDR_LENGTH; + memcpy_ext(pmpriv->adapter, aplist->ap_mac, roam->aplist.ap_mac, + roam->aplist.ap_num * MLAN_MAC_ADDR_LENGTH, + roam->aplist.ap_num * MLAN_MAC_ADDR_LENGTH); + pos += sizeof(aplist->header) + aplist->header.len; + cmd->size += sizeof(aplist->header) + aplist->header.len; + aplist->header.len = wlan_cpu_to_le16(aplist->header.len); + } + cmd->size = wlan_cpu_to_le16(cmd->size); + + LEAVE(); + return MLAN_STATUS_SUCCESS; +} + /** * @brief This function sends set and get auto tx command to firmware. * @@ -2908,6 +3429,11 @@ static mlan_status wlan_cmd_auto_tx(pmlan_private pmpriv, .h803_len, eth_ip, sizeof(t_u16), sizeof(t_u16)); + memcpy_ext(pmpriv->adapter, + (t_u8 *)&pkt_tlv->ip_packet, + misc_keep_alive->packet, + misc_keep_alive->pkt_len, + MKEEP_ALIVE_IP_PKT_MAX); pkt_tlv->header.len = wlan_cpu_to_le16( sizeof(Eth803Hdr_t) + misc_keep_alive->pkt_len); @@ -2974,6 +3500,55 @@ static mlan_status wlan_is_cmd_allowed(mlan_private *priv, t_u16 cmd_no) return ret; } +/** + * @brief This function enable/disable CSI support. + * + * @param pmpriv A pointer to mlan_private structure + * @param cmd A pointer to HostCmd_DS_COMMAND structure + * @param cmd_action The action: GET or SET + * @param pdata_buf A pointer to data buffer + * + * @return MLAN_STATUS_SUCCESS + */ +static mlan_status wlan_cmd_csi(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, + t_u16 cmd_action, t_u16 *pdata_buf) +{ + HostCmd_DS_CSI_CFG *csi_cfg_cmd = &cmd->params.csi_params; + mlan_ds_csi_params *csi_params = MNULL; + + ENTER(); + + cmd->command = wlan_cpu_to_le16(HostCmd_CMD_CSI); + cmd->size = sizeof(HostCmd_DS_CSI_CFG) + S_DS_GEN; + csi_cfg_cmd->action = wlan_cpu_to_le16(cmd_action); + switch (cmd_action) { + case CSI_CMD_ENABLE: + csi_params = (mlan_ds_csi_params *)pdata_buf; + csi_cfg_cmd->head_id = wlan_cpu_to_le32(csi_params->head_id); + csi_cfg_cmd->tail_id = wlan_cpu_to_le32(csi_params->tail_id); + csi_cfg_cmd->chip_id = csi_params->chip_id; + csi_cfg_cmd->csi_filter_cnt = csi_params->csi_filter_cnt; + if (csi_cfg_cmd->csi_filter_cnt > CSI_FILTER_MAX) + csi_cfg_cmd->csi_filter_cnt = CSI_FILTER_MAX; + memcpy_ext(pmpriv->adapter, (t_u8 *)csi_cfg_cmd->csi_filter, + (t_u8 *)csi_params->csi_filter, + sizeof(mlan_csi_filter_t) * + csi_cfg_cmd->csi_filter_cnt, + sizeof(csi_cfg_cmd->csi_filter)); + DBG_HEXDUMP(MCMD_D, "Enable CSI", csi_cfg_cmd, + sizeof(HostCmd_DS_CSI_CFG)); + break; + case CSI_CMD_DISABLE: + DBG_HEXDUMP(MCMD_D, "Disable CSI", csi_cfg_cmd, + sizeof(HostCmd_DS_CSI_CFG)); + default: + break; + } + cmd->size = wlan_cpu_to_le16(cmd->size); + LEAVE(); + return MLAN_STATUS_SUCCESS; +} + /** * @brief This function prepare the command before sending to firmware. * @@ -3068,6 +3643,9 @@ mlan_status wlan_ops_sta_prepare_cmd(t_void *priv, t_u16 cmd_no, ret = wlan_cmd_ssu(pmpriv, cmd_ptr, cmd_action, pdata_buf); break; #endif + case HostCmd_CMD_CSI: + ret = wlan_cmd_csi(pmpriv, cmd_ptr, cmd_action, pdata_buf); + break; case HostCmd_CMD_HAL_PHY_CFG: ret = wlan_cmd_hal_phy_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf); @@ -3301,6 +3879,7 @@ mlan_status wlan_ops_sta_prepare_cmd(t_void *priv, t_u16 cmd_no, case HostCmd_CMD_TARGET_ACCESS: case HostCmd_CMD_802_11_EEPROM_ACCESS: case HostCmd_CMD_BCA_REG_ACCESS: + case HostCmd_CMD_REG_ACCESS: ret = wlan_cmd_reg_access(pmpriv, cmd_ptr, cmd_action, pdata_buf); break; @@ -3337,6 +3916,10 @@ mlan_status wlan_ops_sta_prepare_cmd(t_void *priv, t_u16 cmd_no, sizeof(HostCmd_DS_SET_BSS_MODE) + S_DS_GEN); ret = MLAN_STATUS_SUCCESS; break; + case HostCmd_CMD_802_11_NET_MONITOR: + ret = wlan_cmd_net_monitor(pmpriv, cmd_ptr, cmd_action, + pdata_buf); + break; case HostCmd_CMD_MEASUREMENT_REQUEST: case HostCmd_CMD_MEASUREMENT_REPORT: ret = wlan_meas_cmd_process(pmpriv, cmd_ptr, pdata_buf); @@ -3420,6 +4003,11 @@ mlan_status wlan_ops_sta_prepare_cmd(t_void *priv, t_u16 cmd_no, ret = wlan_cmd_ind_rst_cfg(cmd_ptr, cmd_action, pdata_buf); break; + case HostCmd_CMD_ROAM_OFFLOAD: + ret = wlan_cmd_roam_offload(pmpriv, cmd_ptr, cmd_action, + pdata_buf); + break; + case HostCmd_CMD_802_11_PS_INACTIVITY_TIMEOUT: ret = wlan_cmd_ps_inactivity_timeout(pmpriv, cmd_ptr, cmd_action, pdata_buf); @@ -3511,6 +4099,14 @@ mlan_status wlan_ops_sta_prepare_cmd(t_void *priv, t_u16 cmd_no, case HostCmd_CMD_MFG_COMMAND: ret = wlan_cmd_mfg(pmpriv, cmd_ptr, cmd_action, pdata_buf); break; + case HostCmd_CMD_MC_AGGR_CFG: + ret = wlan_cmd_mc_aggr_cfg(pmpriv, cmd_ptr, cmd_action, + pdata_buf); + break; + case HostCmd_CMD_GET_CH_LOAD: + ret = wlan_cmd_get_ch_load(pmpriv, cmd_ptr, cmd_action, + pdata_buf); + break; default: PRINTM(MERROR, "PREP_CMD: unknown command- %#x\n", cmd_no); ret = MLAN_STATUS_FAILURE; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c b/mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c index dd70a7e..4cba8ee 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c @@ -4,7 +4,7 @@ * responses generated by firmware. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -320,6 +320,11 @@ static mlan_status wlan_process_cmdresp_error(mlan_private *pmpriv, } } } break; + case HostCmd_CMD_ROAM_OFFLOAD: + wlan_clear_fw_roaming_pmk(pmpriv); + pmpriv->adapter->fw_roaming = MFALSE; + PRINTM(MERROR, "FW do not support roaming!\n"); + break; case HostCmd_CMD_CHAN_REGION_CFG: ret = MLAN_STATUS_SUCCESS; PRINTM(MCMND, "FW don't support chan region cfg command!\n"); @@ -2110,6 +2115,61 @@ static mlan_status wlan_ret_inactivity_timeout(pmlan_private pmpriv, return MLAN_STATUS_SUCCESS; } +/** + * @brief This function handles the command response of + * network monitor + * + * @param pmpriv A pointer to mlan_private structure + * @param resp A pointer to HostCmd_DS_COMMAND + * @param pioctl_buf A pointer to command buffer + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_ret_net_monitor(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf) +{ + mlan_ds_misc_cfg *pmisc = MNULL; + mlan_ds_misc_net_monitor *net_mon = MNULL; + HostCmd_DS_802_11_NET_MONITOR *cmd_net_mon = + (HostCmd_DS_802_11_NET_MONITOR *)&resp->params.net_mon; + ChanBandParamSet_t *pchan_band = MNULL; + t_u16 band_info = 0; + + ENTER(); + + if (pioctl_buf && (pioctl_buf->action == MLAN_ACT_GET)) { + pmisc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; + net_mon = &pmisc->param.net_mon; + net_mon->enable_net_mon = + wlan_le16_to_cpu(cmd_net_mon->enable_net_mon); + net_mon->filter_flag = + wlan_le16_to_cpu(cmd_net_mon->filter_flag); + pchan_band = &cmd_net_mon->monitor_chan.chan_band_param[0]; + /* Band information in the TLV is bits[1:0] */ + band_info = pchan_band->bandcfg.chanBand; + net_mon->channel = pchan_band->chan_number; + if (band_info == BAND_2GHZ) + net_mon->band |= (BAND_B | BAND_G); + if (band_info == BAND_5GHZ) + net_mon->band |= BAND_A; + net_mon->chan_bandwidth = + GET_SECONDARYCHAN(pchan_band->bandcfg.chan2Offset); + if (band_info == BAND_2GHZ) + net_mon->band |= BAND_GN; + if (band_info == BAND_5GHZ) + net_mon->band |= BAND_AN; + if (band_info == BAND_2GHZ) + net_mon->band |= BAND_GAC; + if (band_info == BAND_5GHZ) + net_mon->band |= BAND_AAC; + } + pmpriv->adapter->enable_net_mon = + wlan_le16_to_cpu(cmd_net_mon->enable_net_mon); + + LEAVE(); + return MLAN_STATUS_SUCCESS; +} + /** * @brief This function handles the command response of * subscribe event @@ -2432,27 +2492,6 @@ static mlan_status wlan_ret_coalesce_config(pmlan_private pmpriv, return MLAN_STATUS_SUCCESS; } -static mlan_status wlan_ret_get_sensor_temp(pmlan_private pmpriv, - const HostCmd_DS_COMMAND *resp, - mlan_ioctl_req *pioctl_buf) -{ - mlan_ds_misc_cfg *pcfg = MNULL; - const HostCmd_DS_SENSOR_TEMP *pSensorT = &resp->params.temp_sensor; - - ENTER(); - - if (pioctl_buf) { - pcfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; - pcfg->param.sensor_temp.temperature = - wlan_le32_to_cpu(pSensorT->temperature); - PRINTM(MCMND, "get SOC temperature %u C \n", - pSensorT->temperature); - } - - LEAVE(); - return MLAN_STATUS_SUCCESS; -} - /** * @brief This function handles the command response of arb Cfg * @@ -2571,6 +2610,71 @@ static mlan_status wlan_ret_sta_config(pmlan_private pmpriv, return MLAN_STATUS_SUCCESS; } +/** + * @brief This function clears PMK in fw for fw roaming + * + * @param pmpriv A pointer to mlan_private structure + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_clear_fw_roaming_pmk(pmlan_private pmpriv) +{ + mlan_status ret = MLAN_STATUS_SUCCESS; + + ENTER(); + + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_SUPPLICANT_PMK, + HostCmd_ACT_GEN_REMOVE, 0, MNULL, MNULL); + + if (ret == MLAN_STATUS_SUCCESS) { + ret = MLAN_STATUS_FAILURE; + } + + LEAVE(); + return ret; +} + +/** + * @brief This function handles the command response of enable/disable roaming + * offload to fw + * + * @param pmpriv A pointer to mlan_private structure + * @param resp A pointer to HostCmd_DS_COMMAND + * @param pioctl_buf A pointer to mlan_ioctl_req structure + * + * @return MLAN_STATUS_SUCCESS + */ +static mlan_status wlan_ret_roam_offload(pmlan_private pmpriv, + HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf) +{ + HostCmd_DS_ROAM_OFFLOAD *cmdrsp_roam_offload = + (HostCmd_DS_ROAM_OFFLOAD *)&resp->params.roam_offload; + mlan_status status = MLAN_STATUS_SUCCESS; + MrvlIEtypesHeader_t *header = MNULL; + MrvlIEtypes_fw_roam_enable_t *roam_offload_enable = MNULL; + + ENTER(); + + if (resp->result == HostCmd_RESULT_OK) { + header = (MrvlIEtypesHeader_t *)cmdrsp_roam_offload->tlv; + header->type = wlan_le16_to_cpu(header->type); + if (header->type == TLV_TYPE_ROAM) { + roam_offload_enable = (MrvlIEtypes_fw_roam_enable_t *) + cmdrsp_roam_offload->tlv; + if ((t_u8)roam_offload_enable->roam_enable) + pmpriv->adapter->fw_roaming = MTRUE; + else { + pmpriv->adapter->fw_roaming = MFALSE; + wlan_clear_fw_roaming_pmk(pmpriv); + } + } + } + + LEAVE(); + return status; +} + /** * @brief This function handles the command response of set/get auto tx * @@ -2976,6 +3080,15 @@ mlan_status wlan_ops_sta_process_cmdresp(t_void *priv, t_u16 cmdresp_no, resp->params.ssu_params.rec_len); break; #endif + case HostCmd_CMD_CSI: + if (resp->params.csi_params.action == CSI_CMD_ENABLE) { + pmadapter->csi_enabled = 1; + PRINTM(MCMND, "CSI ENABLE cmdresp\n"); + } else { + pmadapter->csi_enabled = 0; + PRINTM(MCMND, "CSI DISABLE cmdresp\n"); + } + break; case HostCmd_CMD_802_11_ASSOCIATE: ret = wlan_ret_802_11_associate(pmpriv, resp, pioctl_buf); break; @@ -3163,6 +3276,7 @@ mlan_status wlan_ops_sta_process_cmdresp(t_void *priv, t_u16 cmdresp_no, case HostCmd_CMD_TARGET_ACCESS: case HostCmd_CMD_802_11_EEPROM_ACCESS: case HostCmd_CMD_BCA_REG_ACCESS: + case HostCmd_CMD_REG_ACCESS: ret = wlan_ret_reg_access(pmpriv->adapter, cmdresp_no, resp, pioctl_buf); break; @@ -3182,6 +3296,9 @@ mlan_status wlan_ops_sta_process_cmdresp(t_void *priv, t_u16 cmdresp_no, case HostCmd_CMD_MEASUREMENT_REPORT: ret = wlan_meas_cmdresp_process(pmpriv, resp); break; + case HostCmd_CMD_802_11_NET_MONITOR: + ret = wlan_ret_net_monitor(pmpriv, resp, pioctl_buf); + break; #if defined(PCIE) #if defined(PCIE8997) || defined(PCIE8897) case HostCmd_CMD_PCIE_HOST_BUF_DETAILS: @@ -3251,6 +3368,9 @@ mlan_status wlan_ops_sta_process_cmdresp(t_void *priv, t_u16 cmdresp_no, break; case HostCmd_CMD_802_11_PS_INACTIVITY_TIMEOUT: break; + case HostCmd_CMD_ROAM_OFFLOAD: + ret = wlan_ret_roam_offload(pmpriv, resp, pioctl_buf); + break; case HostCmd_CMD_GET_TSF: ret = wlan_ret_get_tsf(pmpriv, resp, pioctl_buf); break; @@ -3326,6 +3446,12 @@ mlan_status wlan_ops_sta_process_cmdresp(t_void *priv, t_u16 cmdresp_no, case HostCmd_CMD_MFG_COMMAND: ret = wlan_ret_mfg(pmpriv, resp, pioctl_buf); break; + case HostCmd_CMD_MC_AGGR_CFG: + ret = wlan_ret_mc_aggr_cfg(pmpriv, resp, pioctl_buf); + break; + case HostCmd_CMD_GET_CH_LOAD: + ret = wlan_ret_ch_load(pmpriv, resp, pioctl_buf); + break; default: PRINTM(MERROR, "CMD_RESP: Unknown command response %#x\n", resp->command); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sta_event.c b/mxm_wifiex/wlan_src/mlan/mlan_sta_event.c index aa2a879..95b2663 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sta_event.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sta_event.c @@ -3,7 +3,7 @@ * @brief This file contains MLAN event handling. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -444,8 +444,6 @@ t_void wlan_reset_connect_state(pmlan_private priv, t_u8 drv_disconnect) pmadapter->tx_lock_flag = MFALSE; pmadapter->pps_uapsd_mode = MFALSE; pmadapter->delay_null_pkt = MFALSE; - if (priv->bss_type == MLAN_BSS_TYPE_STA) - pmadapter->hs_wake_interval = 0; if ((wlan_fw_11d_is_enabled(priv)) && (priv->state_11d.user_enable_11d == DISABLE_11D)) { @@ -669,6 +667,7 @@ mlan_status wlan_ops_sta_process_event(t_void *priv) t_u16 reason_code; pmlan_callbacks pcb = &pmadapter->callbacks; mlan_event *pevent = MNULL; + t_u8 addr[MLAN_MAC_ADDR_LENGTH]; chan_band_info *pchan_band_info = MNULL; t_u8 radar_chan; t_u16 enable = 0; @@ -1305,6 +1304,10 @@ mlan_status wlan_ops_sta_process_event(t_void *priv) wlan_free_ssu_pcie_buf(pmadapter); break; #endif + case EVENT_CSI: + PRINTM(MEVENT, "EVENT: EVENT_CSI on STA\n"); + wlan_process_csi_event(pmpriv); + break; case EVENT_MEF_HOST_WAKEUP: PRINTM(MEVENT, "EVENT: EVENT_MEF_HOST_WAKEUP len=%d\n", pmbuf->data_len); @@ -1312,6 +1315,41 @@ mlan_status wlan_ops_sta_process_event(t_void *priv) case EVENT_MANAGEMENT_FRAME_WAKEUP: PRINTM(MEVENT, "EVENT: EVENT_MANAGEMENT_FRAME_WAKEUP HOST\n"); break; + case EVENT_ROAM_OFFLOAD: + memcpy_ext(pmadapter, addr, + pmpriv->curr_bss_params.bss_descriptor.mac_address, + MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH); + memcpy_ext(pmadapter, + pmpriv->curr_bss_params.bss_descriptor.mac_address, + (t_u8 *)(pmadapter->event_body + 2), + MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH); + /** replace ralist's mac address with new mac address */ + if (0 == + wlan_ralist_update( + pmpriv, addr, + pmpriv->curr_bss_params.bss_descriptor.mac_address)) + wlan_ralist_add(pmpriv, + pmpriv->curr_bss_params.bss_descriptor + .mac_address); + wlan_11n_cleanup_reorder_tbl(pmpriv); + wlan_11n_deleteall_txbastream_tbl(pmpriv); + /*Update the BSS for inform kernel, otherwise kernel will give + * warning for not find BSS*/ + memcpy_ext(pmadapter, (t_u8 *)&pmadapter->pscan_table[0], + (t_u8 *)&pmpriv->curr_bss_params.bss_descriptor, + sizeof(BSSDescriptor_t), sizeof(BSSDescriptor_t)); + if (!pmadapter->num_in_scan_table) + pmadapter->num_in_scan_table = 1; + PRINTM(MEVENT, "EVENT: ROAM OFFLOAD IN FW SUCCESS\n"); + pevent->bss_index = pmpriv->bss_index; + pevent->event_id = MLAN_EVENT_ID_FW_ROAM_OFFLOAD_RESULT; + /** Drop event id length and 2 bytes reverved length*/ + pevent->event_len = pmbuf->data_len - sizeof(eventcause) - 2; + memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf, + pmadapter->event_body + 2, pevent->event_len, + pevent->event_len); + wlan_recv_event(pmpriv, pevent->event_id, pevent); + break; case EVENT_CLOUD_KEEP_ALIVE_RETRY_FAIL: break; case EVENT_VDLL_IND: diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c b/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c index 6779eb2..745959e 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c @@ -3,7 +3,7 @@ * @brief This file contains the functions for station ioctl. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -460,6 +460,9 @@ static mlan_status wlan_get_info_ioctl(pmlan_adapter pmadapter, pget_info->param.fw_info.antinfo = pmadapter->antinfo; pget_info->param.fw_info.max_ap_assoc_sta = pmadapter->max_sta_conn; + pget_info->param.fw_info.fw_roaming_support = + (pmadapter->fw_cap_info & FW_ROAMING_SUPPORT) ? 0x01 : + 0x00; pget_info->param.fw_info.fw_beacon_prot = IS_FW_SUPPORT_BEACON_PROT(pmadapter) ? 0x01 : 0x00; break; @@ -542,6 +545,13 @@ static mlan_status wlan_snmp_mib_ioctl(pmlan_adapter pmadapter, value = mib->param.signalext_enable; cmd_oid = SignalextEnable_i; break; + case MLAN_OID_SNMP_MIB_CHAN_TRACK: + if (!IS_FW_SUPPORT_CHAN_TRACK(pmadapter)) { + goto exit; + } + value = mib->param.chan_track; + cmd_oid = ChanTrackParam_i; + break; } /* Send request to firmware */ @@ -764,7 +774,7 @@ static mlan_status wlan_bss_ioctl_get_channel_list(pmlan_adapter pmadapter, (pmpriv->bss_mode == MLAN_BSS_MODE_IBSS && pmpriv->adhoc_state != ADHOC_STARTED))) { t_u8 chan_no; - t_u8 band; + t_u16 band; parsed_region_chan_11d_t *parsed_region_chan = MNULL; parsed_region_chan_11d_t region_chan; @@ -781,7 +791,7 @@ static mlan_status wlan_bss_ioctl_get_channel_list(pmlan_adapter pmadapter, if (wlan_11d_parse_domain_info( pmadapter, &pbss_desc->country_info, - (t_u8)pbss_desc->bss_band, + pbss_desc->bss_band, ®ion_chan) == MLAN_STATUS_SUCCESS) { parsed_region_chan = ®ion_chan; } else { @@ -1004,6 +1014,12 @@ static mlan_status wlan_bss_ioctl_start(pmlan_adapter pmadapter, ENTER(); + if (pmadapter->enable_net_mon == CHANNEL_SPEC_SNIFFER_MODE) { + PRINTM(MINFO, + "Association is blocked in Channel Specified Network Monitor mode...\n"); + LEAVE(); + return MLAN_STATUS_FAILURE; + } /* Before ASSOC REQ, If "port ctrl" mode is enabled, * move the port to CLOSED state */ if (pmpriv->port_ctrl_mode == MTRUE) { @@ -1480,8 +1496,7 @@ wlan_bss_ioctl_bss_11d_check_channel(pmlan_adapter pmadapter, (t_u32)ssid_bssid->channel); /* check if this channel is supported in the region */ - if (!wlan_find_cfp_by_band_and_channel(pmadapter, - (t_u8)ssid_bssid->bss_band, + if (!wlan_find_cfp_by_band_and_channel(pmadapter, ssid_bssid->bss_band, (t_u32)ssid_bssid->channel)) { PRINTM(MERROR, "Unsupported Channel for region 0x%x\n", pmadapter->region_code); @@ -4888,34 +4903,6 @@ static mlan_status wlan_misc_ioctl_ips_cfg(pmlan_adapter pmadapter, return ret; } -static mlan_status wlan_misc_ioctl_get_sensor_temp(pmlan_adapter pmadapter, - pmlan_ioctl_req pioctl_req) -{ - mlan_status ret = MLAN_STATUS_SUCCESS; - t_u16 cmd_action = 0; - mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; - - ENTER(); - - if (pioctl_req->action == MLAN_ACT_GET) - cmd_action = HostCmd_ACT_GEN_GET; - else { - PRINTM(MERROR, " sensor temp only support get operation \n"); - LEAVE(); - return MLAN_STATUS_FAILURE; - } - - /* Send request to firmware */ - ret = wlan_prepare_cmd(pmpriv, HostCmd_DS_GET_SENSOR_TEMP, cmd_action, - 0, (t_void *)pioctl_req, MNULL); - - if (ret == MLAN_STATUS_SUCCESS) - ret = MLAN_STATUS_PENDING; - - LEAVE(); - return ret; -} - /** * @brief IPv6 Router Advertisement offload configuration * @@ -4996,6 +4983,106 @@ static mlan_status wlan_misc_ioctl_gtk_rekey_offload(pmlan_adapter pmadapter, return ret; } +/** + * @brief enable/disable roam offload in firmware + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req Pointer to the IOCTL request buffer + * + * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE + */ +static mlan_status wlan_misc_roam_offload(pmlan_adapter pmadapter, + mlan_ioctl_req *pioctl_req) +{ + pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index]; + mlan_ds_misc_cfg *misc = MNULL; + t_u16 cmd_action = 0; + mlan_status ret = MLAN_STATUS_SUCCESS; + + ENTER(); + + misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf; + + if (!(pmadapter->fw_cap_info & FW_ROAMING_SUPPORT)) { + PRINTM(MERROR, "Firmware roaming not support\n"); + LEAVE(); + return MLAN_STATUS_FAILURE; + } + + if (!IS_FW_SUPPORT_SUPPLICANT(pmadapter)) { + PRINTM(MERROR, "Embedded supplicant do not enable\n"); + LEAVE(); + return MLAN_STATUS_FAILURE; + } + + if ((misc->param.roam_offload.config_mode == ROAM_OFFLOAD_ENABLE) && + misc->param.roam_offload.userset_passphrase) { + pmpriv->adapter->userset_passphrase = + misc->param.roam_offload.userset_passphrase; + if (!misc->param.roam_offload.enable) { + LEAVE(); + return MLAN_STATUS_SUCCESS; + } + } + + if (pioctl_req->action == MLAN_ACT_SET) + cmd_action = HostCmd_ACT_GEN_SET; + else { + PRINTM(MERROR, "Unsupported cmd_action\n"); + LEAVE(); + return MLAN_STATUS_FAILURE; + } + + /* Send request to firmware */ + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_ROAM_OFFLOAD, cmd_action, 0, + (t_void *)pioctl_req, &misc->param.roam_offload); + + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; + + LEAVE(); + return ret; +} + +/** + * @brief set roam offload aplist to firmware + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req Pointer to the IOCTL request buffer + * + * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE + */ +static mlan_status wlan_misc_roam_offload_aplist(pmlan_adapter pmadapter, + mlan_ioctl_req *pioctl_req) +{ + pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index]; + mlan_ds_misc_cfg *misc = MNULL; + t_u16 cmd_action = 0; + mlan_status ret = MLAN_STATUS_SUCCESS; + + ENTER(); + + misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf; + + if (pioctl_req->action == MLAN_ACT_SET) + cmd_action = HostCmd_ACT_GEN_SET; + else { + PRINTM(MERROR, "Unsupported cmd_action\n"); + LEAVE(); + return MLAN_STATUS_FAILURE; + } + + /* Send request to firmware */ + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_ROAM_OFFLOAD, cmd_action, 0, + (t_void *)pioctl_req, &misc->param.roam_offload); + + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; + + LEAVE(); + return ret; +} + /** * @brief cloud keep alive * @@ -5132,6 +5219,9 @@ static mlan_status wlan_misc_cfg_ioctl(pmlan_adapter pmadapter, status = wlan_misc_ioctl_tdls_idle_time(pmadapter, pioctl_req); break; + case MLAN_OID_MISC_NET_MONITOR: + status = wlan_misc_ioctl_net_monitor(pmadapter, pioctl_req); + break; case MLAN_OID_MISC_MAC_CONTROL: status = wlan_misc_ioctl_mac_control(pmadapter, pioctl_req); break; @@ -5231,9 +5321,21 @@ static mlan_status wlan_misc_cfg_ioctl(pmlan_adapter pmadapter, case MLAN_OID_MISC_IND_RST_CFG: status = wlan_misc_ioctl_ind_rst_cfg(pmadapter, pioctl_req); break; + case MLAN_OID_MISC_MC_AGGR_CFG: + status = wlan_misc_ioctl_mc_aggr_cfg(pmadapter, pioctl_req); + break; + case MLAN_OID_MISC_CH_LOAD: + status = wlan_misc_ioctl_ch_load(pmadapter, pioctl_req); + break; case MLAN_OID_MISC_GET_TSF: status = wlan_misc_ioctl_get_tsf(pmadapter, pioctl_req); break; + case MLAN_OID_MISC_ROAM_OFFLOAD: + status = wlan_misc_roam_offload(pmadapter, pioctl_req); + break; + case MLAN_OID_MISC_ROAM_OFFLOAD_APLIST: + status = wlan_misc_roam_offload_aplist(pmadapter, pioctl_req); + break; case MLAN_OID_MISC_GET_CHAN_REGION_CFG: status = wlan_misc_chan_reg_cfg(pmadapter, pioctl_req); break; @@ -5272,6 +5374,9 @@ static mlan_status wlan_misc_cfg_ioctl(pmlan_adapter pmadapter, status = wlan_misc_ssu(pmadapter, pioctl_req); break; #endif + case MLAN_OID_MISC_CSI: + status = wlan_misc_csi(pmadapter, pioctl_req); + break; case MLAN_OID_MISC_HAL_PHY_CFG: status = wlan_misc_hal_phy_cfg(pmadapter, pioctl_req); break; @@ -5429,6 +5534,13 @@ static mlan_status wlan_scan_ioctl(pmlan_adapter pmadapter, return status; } + if (pmadapter->enable_net_mon == CHANNEL_SPEC_SNIFFER_MODE) { + PRINTM(MINFO, + "Scan is blocked in Channel Specified Network Monitor mode...\n"); + LEAVE(); + return MLAN_STATUS_FAILURE; + } + if (pmadapter->scan_block && pioctl_req->action == MLAN_ACT_SET) { PRINTM(MERROR, "Scan is blocked during association...\n"); LEAVE(); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sta_rx.c b/mxm_wifiex/wlan_src/mlan/mlan_sta_rx.c index 5cf92ec..1709656 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sta_rx.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sta_rx.c @@ -4,7 +4,7 @@ * module. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -176,6 +176,7 @@ void wlan_process_tdls_action_frame(pmlan_private priv, t_u8 *pbuf, t_u32 len) int ie_len = 0; t_u8 i; int rate_len; + IEEEtypes_Extension_t *ext_ie; #define TDLS_PAYLOAD_TYPE 2 #define TDLS_CATEGORY 0x0c @@ -329,7 +330,7 @@ void wlan_process_tdls_action_frame(pmlan_private priv, t_u8 *pbuf, t_u32 len) pos, sizeof(IEEEtypes_VHTCap_t), sizeof(IEEEtypes_VHTCap_t)); sta_ptr->is_11ac_enabled = 1; - DBG_HEXDUMP(MDAT_D, "TDLS VHT capability", + DBG_HEXDUMP(MCMD_D, "Rx TDLS VHT capability", (t_u8 *)(&sta_ptr->vht_cap), MIN(sizeof(IEEEtypes_VHTCap_t), MAX_DATA_DUMP_LEN)); @@ -338,7 +339,7 @@ void wlan_process_tdls_action_frame(pmlan_private priv, t_u8 *pbuf, t_u32 len) memcpy_ext(priv->adapter, (t_u8 *)&sta_ptr->vht_oprat, pos, sizeof(IEEEtypes_VHTOprat_t), sizeof(IEEEtypes_VHTOprat_t)); - DBG_HEXDUMP(MDAT_D, "TDLS VHT Operation", + DBG_HEXDUMP(MCMD_D, "Rx TDLS VHT Operation", (t_u8 *)(&sta_ptr->vht_oprat), MIN(sizeof(IEEEtypes_VHTOprat_t), MAX_DATA_DUMP_LEN)); @@ -347,11 +348,47 @@ void wlan_process_tdls_action_frame(pmlan_private priv, t_u8 *pbuf, t_u32 len) memcpy_ext(priv->adapter, (t_u8 *)&sta_ptr->aid_info, pos, sizeof(IEEEtypes_AID_t), sizeof(IEEEtypes_AID_t)); - DBG_HEXDUMP(MDAT_D, "TDLS AID Info", + DBG_HEXDUMP(MCMD_D, "Rx TDLS AID Info", (t_u8 *)(&sta_ptr->aid_info), MIN(sizeof(IEEEtypes_AID_t), MAX_DATA_DUMP_LEN)); break; + case EXTENSION: + ext_ie = (IEEEtypes_Extension_t *)pos; + if (ext_ie->ext_id == HE_CAPABILITY) { + memcpy_ext(priv->adapter, + (t_u8 *)&sta_ptr->tdls_he_cap, pos, + ext_ie->ieee_hdr.len + + sizeof(IEEEtypes_Header_t), + sizeof(IEEEtypes_HECap_t)); + sta_ptr->tdls_he_cap.ieee_hdr.len = + MIN(ext_ie->ieee_hdr.len, + sizeof(IEEEtypes_HECap_t) - + sizeof(IEEEtypes_Header_t)); + sta_ptr->is_11ax_enabled = 1; + DBG_HEXDUMP(MCMD_D, "Rx TDLS HE Capability", + (t_u8 *)(&sta_ptr->tdls_he_cap), + MIN(sizeof(IEEEtypes_Header_t) + + sta_ptr->tdls_he_cap + .ieee_hdr.len, + sizeof(IEEEtypes_HECap_t))); + } else if (ext_ie->ext_id == HE_OPERATION) { + memcpy_ext(priv->adapter, + (t_u8 *)&sta_ptr->he_op, pos, + ext_ie->ieee_hdr.len + + sizeof(IEEEtypes_Header_t), + sizeof(IEEEtypes_HeOp_t)); + ext_ie->ieee_hdr.len = + MIN(ext_ie->ieee_hdr.len, + sizeof(IEEEtypes_HeOp_t) - + sizeof(IEEEtypes_Header_t)); + DBG_HEXDUMP(MCMD_D, "Rx TDLS HE Operation", + (t_u8 *)(&sta_ptr->he_op), + MIN(sizeof(IEEEtypes_Header_t) + + ext_ie->ieee_hdr.len, + MAX_DATA_DUMP_LEN)); + } + break; default: break; } @@ -359,6 +396,81 @@ void wlan_process_tdls_action_frame(pmlan_private priv, t_u8 *pbuf, t_u32 len) return; } +/** + * @brief This function get pxpd info for radiotap info + * + * @param priv A pointer to pmlan_private + * @param prx_pd A pointer to RxPD + * @param prt_info A pointer to radiotap_info + * + * @return N/A + */ +void wlan_rxpdinfo_to_radiotapinfo(pmlan_private priv, RxPD *prx_pd, + radiotap_info *prt_info) +{ + radiotap_info rt_info_tmp; + t_u8 rx_rate_info = 0; + t_u8 mcs_index = 0; + t_u8 format = 0; + t_u8 bw = 0; + t_u8 gi = 0; + t_u8 ldpc = 0; + t_u8 ext_rate_info = 0; + + memset(priv->adapter, &rt_info_tmp, 0x00, sizeof(rt_info_tmp)); + rt_info_tmp.snr = prx_pd->snr; + rt_info_tmp.nf = prx_pd->nf; + rt_info_tmp.band_config = (prx_pd->rx_info & 0xf); + rt_info_tmp.chan_num = (prx_pd->rx_info & RXPD_CHAN_MASK) >> 5; + ext_rate_info = (t_u8)(prx_pd->rx_info >> 16); + + rt_info_tmp.antenna = prx_pd->antenna; + rx_rate_info = prx_pd->rate_info; + if ((rx_rate_info & 0x3) == MLAN_RATE_FORMAT_VHT) { + /* VHT rate */ + format = MLAN_RATE_FORMAT_VHT; + mcs_index = MIN(prx_pd->rx_rate & 0xF, 9); + /* 20M: bw=0, 40M: bw=1, 80M: bw=2, 160M: bw=3 */ + bw = (rx_rate_info & 0xC) >> 2; + /* LGI: gi =0, SGI: gi = 1 */ + gi = (rx_rate_info & 0x10) >> 4; + } else if ((rx_rate_info & 0x3) == MLAN_RATE_FORMAT_HT) { + /* HT rate */ + format = MLAN_RATE_FORMAT_HT; + mcs_index = prx_pd->rx_rate; + /* 20M: bw=0, 40M: bw=1 */ + bw = (rx_rate_info & 0xC) >> 2; + /* LGI: gi =0, SGI: gi = 1 */ + gi = (rx_rate_info & 0x10) >> 4; + } else { + /* LG rate */ + format = MLAN_RATE_FORMAT_LG; + mcs_index = (prx_pd->rx_rate > MLAN_RATE_INDEX_OFDM0) ? + prx_pd->rx_rate - 1 : + prx_pd->rx_rate; + } + ldpc = rx_rate_info & 0x40; + + rt_info_tmp.rate_info.mcs_index = mcs_index; + rt_info_tmp.rate_info.rate_info = + (ldpc << 5) | (format << 3) | (bw << 1) | gi; + rt_info_tmp.rate_info.bitrate = + wlan_index_to_data_rate(priv->adapter, prx_pd->rx_rate, + prx_pd->rate_info, ext_rate_info); + + if (prx_pd->flags & RXPD_FLAG_EXTRA_HEADER) + memcpy_ext(priv->adapter, &rt_info_tmp.extra_info, + (t_u8 *)prx_pd + sizeof(*prx_pd), + sizeof(rt_info_tmp.extra_info), + sizeof(rt_info_tmp.extra_info)); + + memset(priv->adapter, prt_info, 0x00, sizeof(radiotap_info)); + memcpy_ext(priv->adapter, prt_info, &rt_info_tmp, sizeof(rt_info_tmp), + sizeof(radiotap_info)); + + return; +} + /** * @brief This function processes received packet and forwards it * to kernel/upper layer @@ -498,6 +610,10 @@ mlan_status wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf) PRINTM(MDATA, "%lu.%06lu : Data => kernel seq_num=%d tid=%d\n", pmbuf->out_ts_sec, pmbuf->out_ts_usec, prx_pd->seq_num, prx_pd->priority); + if (pmadapter->enable_net_mon) { + pmbuf->flags |= MLAN_BUF_FLAG_NET_MONITOR; + goto mon_process; + } #ifdef DRV_EMBEDDED_SUPPLICANT if (supplicantIsEnabled(priv->psapriv) && @@ -516,6 +632,16 @@ mlan_status wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf) } #endif +mon_process: + if (pmbuf->flags & MLAN_BUF_FLAG_NET_MONITOR) { + // Use some rxpd space to save rxpd info for radiotap header + // We should insure radiotap_info is not bigger than RxPD + wlan_rxpdinfo_to_radiotapinfo( + priv, prx_pd, + (radiotap_info *)(pmbuf->pbuf + pmbuf->data_offset - + sizeof(radiotap_info))); + } + if (MFALSE || priv->rx_pkt_info) { ext_rate_info = (t_u8)(prx_pd->rx_info >> 16); pmbuf->u.rx_info.data_rate = @@ -576,6 +702,10 @@ mlan_status wlan_ops_sta_process_rx_packet(t_void *adapter, pmlan_buffer pmbuf) prx_pd = (RxPD *)(pmbuf->pbuf + pmbuf->data_offset); /* Endian conversion */ endian_convert_RxPD(prx_pd); + if (prx_pd->flags & RXPD_FLAG_EXTRA_HEADER) { + endian_convert_RxPD_extra_header( + (rxpd_extra_info *)((t_u8 *)prx_pd + sizeof(*prx_pd))); + } if (priv->adapter->pcard_info->v14_fw_api) { t_u8 rxpd_rate_info_orig = prx_pd->rate_info; prx_pd->rate_info = wlan_convert_v14_rx_rate_info( diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sta_tx.c b/mxm_wifiex/wlan_src/mlan/mlan_sta_tx.c index 6ef9ff6..f73f288 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sta_tx.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sta_tx.c @@ -4,7 +4,7 @@ * transmission in MLAN module. * * - * Copyright 2008-2020 NXP + * Copyright 2008-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -168,6 +168,37 @@ t_void *wlan_ops_sta_process_txpd(t_void *priv, pmlan_buffer pmbuf) plocal_tx_pd->tx_control |= TXPD_RETRY_ENABLE; } } + if (pmbuf->flags & MLAN_BUF_FLAG_MC_AGGR_PKT) { + tx_ctrl *ctrl = (tx_ctrl *)&plocal_tx_pd->tx_control; + mc_tx_ctrl *mc_ctrl = + (mc_tx_ctrl *)&plocal_tx_pd->pkt_delay_2ms; + plocal_tx_pd->tx_pkt_type = PKT_TYPE_802DOT11_MC_AGGR; + if (pmbuf->u.mc_tx_info.mc_pkt_flags & MC_FLAG_START_CYCLE) + ctrl->mc_cycle_start = MTRUE; + else + ctrl->mc_cycle_start = MFALSE; + if (pmbuf->u.mc_tx_info.mc_pkt_flags & MC_FLAG_END_CYCLE) + ctrl->mc_cycle_end = MTRUE; + else + ctrl->mc_cycle_end = MFALSE; + if (pmbuf->u.mc_tx_info.mc_pkt_flags & MC_FLAG_START_AMPDU) + ctrl->mc_ampdu_start = MTRUE; + else + ctrl->mc_ampdu_start = MFALSE; + if (pmbuf->u.mc_tx_info.mc_pkt_flags & MC_FLAG_END_AMPDU) + ctrl->mc_ampdu_end = MTRUE; + else + ctrl->mc_ampdu_end = MFALSE; + if (pmbuf->u.mc_tx_info.mc_pkt_flags & MC_FLAG_RETRY) + ctrl->mc_pkt_retry = MTRUE; + else + ctrl->mc_pkt_retry = MFALSE; + ctrl->bw = pmbuf->u.mc_tx_info.bandwidth & 0x7; + ctrl->tx_rate = pmbuf->u.mc_tx_info.mcs_index & 0x1f; + mc_ctrl->abs_tsf_expirytime = + wlan_cpu_to_le32(pmbuf->u.mc_tx_info.pkt_expiry); + mc_ctrl->mc_seq = wlan_cpu_to_le16(pmbuf->u.mc_tx_info.seq_num); + } endian_convert_TxPD(plocal_tx_pd); /* Adjust the data offset and length to include TxPD in pmbuf */ diff --git a/mxm_wifiex/wlan_src/mlan/mlan_uap.h b/mxm_wifiex/wlan_src/mlan/mlan_uap.h index 64fc4f9..2425ebc 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_uap.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_uap.h @@ -4,7 +4,7 @@ * of uap functionalities * * - * Copyright 2009-2020 NXP + * Copyright 2009-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c b/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c index 5f9e667..c847cf4 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c @@ -3,7 +3,7 @@ * @brief This file contains the handling of AP mode command and event * * - * Copyright 2009-2021 NXP + * Copyright 2009-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -714,7 +714,8 @@ static mlan_status wlan_uap_cmd_ap_config(pmlan_private pmpriv, t_u16 i; t_u16 ac; #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) int rx_mcs_supp = 0; #endif @@ -1099,7 +1100,9 @@ static mlan_status wlan_uap_cmd_ap_config(pmlan_private pmpriv, tlv_auth_type = (MrvlIEtypes_auth_type_t *)tlv; tlv_auth_type->header.type = wlan_cpu_to_le16(TLV_TYPE_AUTH_TYPE); - tlv_auth_type->header.len = wlan_cpu_to_le16(sizeof(t_u8)); + tlv_auth_type->header.len = + wlan_cpu_to_le16(sizeof(MrvlIEtypes_auth_type_t) - + sizeof(MrvlIEtypesHeader_t)); tlv_auth_type->auth_type = (t_u8)bss->param.bss_config.auth_mode; cmd_size += sizeof(MrvlIEtypes_auth_type_t); @@ -1342,8 +1345,10 @@ static mlan_status wlan_uap_cmd_ap_config(pmlan_private pmpriv, bss->param.bss_config.supported_mcs_set, 16, sizeof(tlv_htcap->ht_cap.supported_mcs_set)); #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(SD9097) || defined(USB9097) + defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \ + defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X) if (IS_CARD9098(pmpriv->adapter->card_type) || + IS_CARDNW62X(pmpriv->adapter->card_type) || IS_CARD9097(pmpriv->adapter->card_type)) { if (bss->param.bss_config.supported_mcs_set[0]) { if (bss->param.bss_config.bandcfg.chanBand == @@ -1842,6 +1847,8 @@ static mlan_status wlan_uap_cmd_sys_configure(pmlan_private pmpriv, MRVL_ACTION_CHAN_SWITCH_ANNOUNCE); // mode reserve for future use tlv_chan_switch->mode = 0; + tlv_chan_switch->num_pkt = + bss->param.chanswitch.chan_switch_count; if (bss->param.chanswitch.new_oper_class) { tlv_chan_switch->header.len = wlan_cpu_to_le16( sizeof(MrvlIEtypes_action_chan_switch_t) - @@ -1855,8 +1862,7 @@ static mlan_status wlan_uap_cmd_sys_configure(pmlan_private pmpriv, sizeof(IEEEtypes_Header_t); ecsa_ie->chan_switch_mode = bss->param.chanswitch.chan_switch_mode; - ecsa_ie->chan_switch_count = - bss->param.chanswitch.chan_switch_count; + ecsa_ie->chan_switch_count = 0; ecsa_ie->new_channel_num = bss->param.chanswitch.new_channel_num; ecsa_ie->new_oper_class = @@ -1876,8 +1882,7 @@ static mlan_status wlan_uap_cmd_sys_configure(pmlan_private pmpriv, sizeof(IEEEtypes_Header_t); csa_ie->chan_switch_mode = bss->param.chanswitch.chan_switch_mode; - csa_ie->chan_switch_count = - bss->param.chanswitch.chan_switch_count; + csa_ie->chan_switch_count = 0; csa_ie->new_channel_num = bss->param.chanswitch.new_channel_num; cmd->size += sizeof(IEEEtypes_ChanSwitchAnn_t); @@ -2250,6 +2255,13 @@ static mlan_status wlan_uap_ret_cmd_ap_config(pmlan_private pmpriv, tlv_auth_type = (MrvlIEtypes_auth_type_t *)tlv; bss->param.bss_config.auth_mode = tlv_auth_type->auth_type; + if (tlv_len == (sizeof(MrvlIEtypes_auth_type_t) - + sizeof(MrvlIEtypesHeader_t))) { + bss->param.bss_config.pwe_derivation = + tlv_auth_type->PWE_derivation; + bss->param.bss_config.transition_disable = + tlv_auth_type->transition_disable; + } break; case TLV_TYPE_UAP_ENCRYPT_PROTOCOL: tlv_encrypt_protocol = @@ -2934,6 +2946,10 @@ static mlan_status wlan_uap_cmd_snmp_mib(pmlan_private pmpriv, psnmp_mib->value[0] = *((t_u8 *)pdata_buf); cmd->size += sizeof(t_u8); break; + case Dot11H_fakeRadar: + psnmp_mib->oid = wlan_cpu_to_le16((t_u16)cmd_oid); + psnmp_mib->buf_size = 0; + break; default: PRINTM(MERROR, "Unsupported OID.\n"); ret = MLAN_STATUS_FAILURE; @@ -4661,6 +4677,7 @@ mlan_status wlan_ops_uap_prepare_cmd(t_void *priv, t_u16 cmd_no, case HostCmd_CMD_TARGET_ACCESS: case HostCmd_CMD_802_11_EEPROM_ACCESS: case HostCmd_CMD_BCA_REG_ACCESS: + case HostCmd_CMD_REG_ACCESS: ret = wlan_cmd_reg_access(pmpriv, cmd_ptr, cmd_action, pdata_buf); break; @@ -4699,6 +4716,10 @@ mlan_status wlan_ops_uap_prepare_cmd(t_void *priv, t_u16 cmd_no, sizeof(HostCmd_DS_CHAN_REGION_CFG) + S_DS_GEN); cmd_ptr->params.reg_cfg.action = wlan_cpu_to_le16(cmd_action); break; + case HostCmd_CMD_802_11_NET_MONITOR: + ret = wlan_cmd_net_monitor(pmpriv, cmd_ptr, cmd_action, + pdata_buf); + break; case HostCmd_CMD_PACKET_AGGR_CTRL: ret = wlan_cmd_packet_aggr_ctrl(pmpriv, cmd_ptr, cmd_action, pdata_buf); @@ -4791,6 +4812,17 @@ mlan_status wlan_ops_uap_prepare_cmd(t_void *priv, t_u16 cmd_no, ret = wlan_cmd_hal_phy_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf); break; + case HostCmd_CMD_MC_AGGR_CFG: + ret = wlan_cmd_mc_aggr_cfg(pmpriv, cmd_ptr, cmd_action, + pdata_buf); + break; + case HostCmd_CMD_GET_CH_LOAD: + ret = wlan_cmd_get_ch_load(pmpriv, cmd_ptr, cmd_action, + pdata_buf); + break; + case HostCmd_DS_GET_SENSOR_TEMP: + wlan_cmd_get_sensor_temp(pmpriv, cmd_ptr, cmd_action); + break; default: PRINTM(MERROR, "PREP_CMD: unknown command- %#x\n", cmd_no); if (pioctl_req) @@ -4966,6 +4998,9 @@ mlan_status wlan_ops_uap_process_cmdresp(t_void *priv, t_u16 cmdresp_no, break; case HostCmd_CMD_SET_BSS_MODE: break; + case HostCmd_CMD_802_11_NET_MONITOR: + ret = wlan_ret_net_monitor(pmpriv, resp, pioctl_buf); + break; case HostCmd_CMD_RECONFIGURE_TX_BUFF: wlan_set_tx_pause_flag(pmpriv, MFALSE); @@ -5067,6 +5102,7 @@ mlan_status wlan_ops_uap_process_cmdresp(t_void *priv, t_u16 cmdresp_no, case HostCmd_CMD_TARGET_ACCESS: case HostCmd_CMD_802_11_EEPROM_ACCESS: case HostCmd_CMD_BCA_REG_ACCESS: + case HostCmd_CMD_REG_ACCESS: ret = wlan_ret_reg_access(pmpriv->adapter, cmdresp_no, resp, pioctl_buf); break; @@ -5171,6 +5207,15 @@ mlan_status wlan_ops_uap_process_cmdresp(t_void *priv, t_u16 cmdresp_no, ret = wlan_ret_set_get_beacon_stuck_cfg(pmpriv, resp, pioctl_buf); break; + case HostCmd_CMD_MC_AGGR_CFG: + ret = wlan_ret_mc_aggr_cfg(pmpriv, resp, pioctl_buf); + break; + case HostCmd_CMD_GET_CH_LOAD: + ret = wlan_ret_ch_load(pmpriv, resp, pioctl_buf); + break; + case HostCmd_DS_GET_SENSOR_TEMP: + ret = wlan_ret_get_sensor_temp(pmpriv, resp, pioctl_buf); + break; default: PRINTM(MERROR, "CMD_RESP: Unknown command response %#x\n", resp->command); @@ -5457,14 +5502,20 @@ mlan_status wlan_ops_uap_process_event(t_void *priv) pevent->event_len, pevent->event_len); wlan_11h_print_event_radar_detected(pmpriv, pevent, &channel); *((t_u8 *)pevent->event_buf) = channel; + if (pmpriv->bss_type == MLAN_BSS_TYPE_DFS) { + wlan_recv_event(priv, MLAN_EVENT_ID_FW_RADAR_DETECTED, + pevent); + pevent->event_id = 0; /* clear to avoid + resending at end of fcn + */ + break; + } if (!pmpriv->intf_state_11h.is_11h_host) { if (pmadapter->state_rdh.stage == RDH_OFF) { pmadapter->state_rdh.stage = RDH_CHK_INTFS; wlan_11h_radar_detected_handling(pmadapter, pmpriv); - if (pmpriv->uap_host_based) - wlan_recv_event( - priv, + wlan_recv_event(priv, MLAN_EVENT_ID_FW_RADAR_DETECTED, pevent); } else { @@ -5515,6 +5566,17 @@ mlan_status wlan_ops_uap_process_event(t_void *priv) /* Handle / pass event data, and free buffer */ ret = wlan_11h_handle_event_chanrpt_ready(pmpriv, pevent, &channel); + if (pmpriv->bss_type == MLAN_BSS_TYPE_DFS) { + *((t_u8 *)pevent->event_buf) = + pmpriv->adapter->state_dfs.dfs_radar_found; + *((t_u8 *)pevent->event_buf + 1) = channel; + wlan_recv_event(pmpriv, + MLAN_EVENT_ID_FW_CHANNEL_REPORT_RDY, + pevent); + pevent->event_id = 0; /* clear to avoid resending at end + of fcn */ + break; + } if (pmpriv->intf_state_11h.is_11h_host) { *((t_u8 *)pevent->event_buf) = pmpriv->adapter->state_dfs.dfs_radar_found; @@ -5640,6 +5702,10 @@ mlan_status wlan_ops_uap_process_event(t_void *priv) case EVENT_VDLL_IND: wlan_process_vdll_event(pmpriv, pmbuf); break; + case EVENT_CSI: + PRINTM(MEVENT, "EVENT: EVENT_CSI on UAP\n"); + wlan_process_csi_event(pmpriv); + break; case EVENT_FW_HANG_REPORT: if (pmbuf->data_len < (sizeof(eventcause) + sizeof(t_u16))) { diff --git a/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c b/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c index 9606801..52cfad3 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c @@ -3,7 +3,7 @@ * @brief This file contains the handling of AP mode ioctls * * - * Copyright 2009-2021 NXP + * Copyright 2009-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -112,6 +112,7 @@ static mlan_status wlan_uap_callback_bss_ioctl_start(t_void *priv) wlan_uap_get_info_cb_t *puap_state_chan_cb = &pmpriv->uap_state_chan_cb; t_u8 old_channel; t_bool under_nop = MFALSE; + dfs_state_t dfs_state; ENTER(); /* clear callback now that we're here */ puap_state_chan_cb->get_chan_callback = MNULL; @@ -123,6 +124,10 @@ static mlan_status wlan_uap_callback_bss_ioctl_start(t_void *priv) !wlan_can_radar_det_skip(pmpriv) && wlan_11h_radar_detect_required(pmpriv, puap_state_chan_cb->channel)) { + dfs_state = wlan_get_chan_dfs_state( + pmpriv, BAND_A, puap_state_chan_cb->channel); + if (dfs_state == DFS_AVAILABLE) + goto prep_bss_start; /* If DFS repeater mode is on then before starting the uAP * make sure that mlan0 is connected to some external AP * for DFS channel operations. @@ -281,6 +286,13 @@ static mlan_status wlan_uap_bss_ioctl_start(pmlan_adapter pmadapter, ENTER(); + if (pmadapter->enable_net_mon == CHANNEL_SPEC_SNIFFER_MODE) { + PRINTM(MINFO, + "BSS start is blocked in Channel Specified Network Monitor mode...\n"); + LEAVE(); + return MLAN_STATUS_FAILURE; + } + bss = (mlan_ds_bss *)pioctl_req->pbuf; pmpriv->uap_host_based = bss->param.host_based; if (!pmpriv->intf_state_11h.is_11h_host && @@ -1311,7 +1323,7 @@ static mlan_status wlan_uap_callback_domain_info(t_void *priv) mlan_private *pmpriv = (mlan_private *)priv; wlan_uap_get_info_cb_t *puap_state_chan_cb = &pmpriv->uap_state_chan_cb; mlan_ds_11d_cfg *cfg11d; - t_u8 band; + t_u16 band; pmlan_adapter pmadapter = pmpriv->adapter; pmlan_callbacks pcb = &pmadapter->callbacks; @@ -1411,6 +1423,7 @@ static mlan_status wlan_uap_callback_11h_channel_check_req(t_void *priv) Band_Config_t *pband_cfg = &puap_state_chan_cb->bandcfg; /* keep copy as local variable */ pmlan_ioctl_req pioctl = puap_state_chan_cb->pioctl_req_curr; + dfs_state_t dfs_state; ENTER(); /* clear callback now that we're here */ puap_state_chan_cb->get_chan_callback = MNULL; @@ -1435,6 +1448,18 @@ static mlan_status wlan_uap_callback_11h_channel_check_req(t_void *priv) ret = wlan_11h_config_master_radar_det(pmpriv, MTRUE); ret = wlan_11h_check_update_radar_det_state(pmpriv); + dfs_state = wlan_get_chan_dfs_state( + pmpriv, BAND_A, puap_state_chan_cb->channel); + if (dfs_state == DFS_AVAILABLE) { + wlan_11h_set_dfs_check_chan( + pmpriv, puap_state_chan_cb->channel); + PRINTM(MCMND, "ZERODFS: Channel %d is Avaliable\n", + puap_state_chan_cb->channel); + pcb->moal_ioctl_complete(pmpriv->adapter->pmoal_handle, + pioctl, MLAN_STATUS_COMPLETE); + LEAVE(); + return ret; + } /* Check for radar on the channel */ ret = wlan_11h_issue_radar_detect(pmpriv, pioctl, puap_state_chan_cb->channel, @@ -1481,7 +1506,8 @@ static mlan_status wlan_uap_11h_channel_check_req(pmlan_adapter pmadapter, pmpriv->intf_state_11h.is_11h_host = p11h_cfg->param.chan_rpt_req.host_based; - if (!pmpriv->intf_state_11h.is_11h_host) { + if (!pmpriv->intf_state_11h.is_11h_host && + pmpriv->bss_type != MLAN_BSS_TYPE_DFS) { /* store params, issue command to get UAP channel, whose * CMD_RESP will callback remainder of 11H channel check * handling */ @@ -1499,7 +1525,8 @@ static mlan_status wlan_uap_11h_channel_check_req(pmlan_adapter pmadapter, ret = wlan_11h_config_master_radar_det(pmpriv, MTRUE); ret = wlan_11h_check_update_radar_det_state(pmpriv); } - if (p11h_cfg->param.chan_rpt_req.millisec_dwell_time) { + if (p11h_cfg->param.chan_rpt_req.millisec_dwell_time || + pmpriv->bss_type == MLAN_BSS_TYPE_DFS) { if (pmpriv->adapter->dfs_test_params .user_cac_period_msec) { PRINTM(MCMD_D, @@ -1636,6 +1663,42 @@ static mlan_status wlan_uap_snmp_mib_11h(pmlan_adapter pmadapter, return ret; } +/** + * @brief Set SNMP MIB for 11H + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req A pointer to ioctl request buffer + * + * @return MLAN_STATUS_PENDING --success, otherwise fail + * @sa wlan_uap_callback_snmp_mib_11h + */ +static mlan_status wlan_uap_snmp_mib_11h_fakeradar(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req) +{ + mlan_status ret = MLAN_STATUS_SUCCESS; + mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; + + ENTER(); + + if (pioctl_req->buf_len < sizeof(mlan_ds_snmp_mib)) { + PRINTM(MWARN, "MLAN snmp_mib IOCTL length is too short.\n"); + pioctl_req->data_read_written = 0; + pioctl_req->buf_len_needed = sizeof(mlan_ds_snmp_mib); + LEAVE(); + return MLAN_STATUS_RESOURCE; + } + /* Send cmd to FW to trigger fakeradar in firmware */ + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_SNMP_MIB, + HostCmd_ACT_GEN_SET, Dot11H_fakeRadar, + (t_void *)pioctl_req, MNULL); + + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; + + LEAVE(); + return ret; +} + /** * @brief ACS scan * @@ -1998,6 +2061,10 @@ mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req) break; case MLAN_IOCTL_MISC_CFG: misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf; + if (misc->sub_command == MLAN_OID_MISC_GET_SENSOR_TEMP) { + status = wlan_misc_ioctl_get_sensor_temp(pmadapter, + pioctl_req); + } if (misc->sub_command == MLAN_OID_MISC_INIT_SHUTDOWN) status = wlan_misc_ioctl_init_shutdown(pmadapter, pioctl_req); @@ -2060,6 +2127,11 @@ mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req) if (misc->sub_command == MLAN_OID_MISC_IND_RST_CFG) status = wlan_misc_ioctl_ind_rst_cfg(pmadapter, pioctl_req); + if (misc->sub_command == MLAN_OID_MISC_MC_AGGR_CFG) + status = wlan_misc_ioctl_mc_aggr_cfg(pmadapter, + pioctl_req); + if (misc->sub_command == MLAN_OID_MISC_CH_LOAD) + status = wlan_misc_ioctl_ch_load(pmadapter, pioctl_req); if (misc->sub_command == MLAN_OID_MISC_GET_TSF) status = wlan_misc_ioctl_get_tsf(pmadapter, pioctl_req); if (misc->sub_command == MLAN_OID_MISC_GET_CHAN_REGION_CFG) @@ -2075,6 +2147,9 @@ mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req) pioctl_req); if (misc->sub_command == MLAN_OID_MISC_PER_PKT_CFG) status = wlan_misc_per_pkt_cfg(pmadapter, pioctl_req); + if (misc->sub_command == MLAN_OID_MISC_NET_MONITOR) + status = wlan_misc_ioctl_net_monitor(pmadapter, + pioctl_req); if (misc->sub_command == MLAN_OID_MISC_FW_DUMP_EVENT) status = wlan_misc_ioctl_fw_dump_event(pmadapter, pioctl_req); @@ -2162,6 +2237,9 @@ mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req) status = wlan_uap_snmp_mib_11d(pmadapter, pioctl_req); if (snmp->sub_command == MLAN_OID_SNMP_MIB_DOT11H) status = wlan_uap_snmp_mib_11h(pmadapter, pioctl_req); + if (snmp->sub_command == MLAN_OID_SNMP_MIB_DOT11H_FAKERADAR) + status = wlan_uap_snmp_mib_11h_fakeradar(pmadapter, + pioctl_req); break; case MLAN_IOCTL_SEC_CFG: sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf; @@ -2203,6 +2281,9 @@ mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req) if (cfg11h->sub_command == MLAN_OID_11H_CHAN_SWITCH_COUNT) status = wlan_11h_ioctl_chan_switch_count(pmadapter, pioctl_req); + if (cfg11h->sub_command == MLAN_OID_11H_CHAN_DFS_STATE) + status = wlan_11h_ioctl_chan_dfs_state(pmadapter, + pioctl_req); if (cfg11h->sub_command == MLAN_OID_11H_DFS_W53_CFG) status = wlan_11h_ioctl_dfs_w53_cfg(pmadapter, pioctl_req); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_uap_txrx.c b/mxm_wifiex/wlan_src/mlan/mlan_uap_txrx.c index d152379..4d72869 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_uap_txrx.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_uap_txrx.c @@ -271,6 +271,37 @@ t_void *wlan_ops_uap_process_txpd(t_void *priv, pmlan_buffer pmbuf) plocal_tx_pd->tx_control |= TXPD_RETRY_ENABLE; } } + if (pmbuf->flags & MLAN_BUF_FLAG_MC_AGGR_PKT) { + tx_ctrl *ctrl = (tx_ctrl *)&plocal_tx_pd->tx_control; + mc_tx_ctrl *mc_ctrl = + (mc_tx_ctrl *)&plocal_tx_pd->pkt_delay_2ms; + plocal_tx_pd->tx_pkt_type = PKT_TYPE_802DOT11_MC_AGGR; + if (pmbuf->u.mc_tx_info.mc_pkt_flags & MC_FLAG_START_CYCLE) + ctrl->mc_cycle_start = MTRUE; + else + ctrl->mc_cycle_start = MFALSE; + if (pmbuf->u.mc_tx_info.mc_pkt_flags & MC_FLAG_END_CYCLE) + ctrl->mc_cycle_end = MTRUE; + else + ctrl->mc_cycle_end = MFALSE; + if (pmbuf->u.mc_tx_info.mc_pkt_flags & MC_FLAG_START_AMPDU) + ctrl->mc_ampdu_start = MTRUE; + else + ctrl->mc_ampdu_start = MFALSE; + if (pmbuf->u.mc_tx_info.mc_pkt_flags & MC_FLAG_END_AMPDU) + ctrl->mc_ampdu_end = MTRUE; + else + ctrl->mc_ampdu_end = MFALSE; + if (pmbuf->u.mc_tx_info.mc_pkt_flags & MC_FLAG_RETRY) + ctrl->mc_pkt_retry = MTRUE; + else + ctrl->mc_pkt_retry = MFALSE; + ctrl->bw = pmbuf->u.mc_tx_info.bandwidth & 0x7; + ctrl->tx_rate = pmbuf->u.mc_tx_info.mcs_index & 0x1f; + mc_ctrl->abs_tsf_expirytime = + wlan_cpu_to_le32(pmbuf->u.mc_tx_info.pkt_expiry); + mc_ctrl->mc_seq = wlan_cpu_to_le16(pmbuf->u.mc_tx_info.seq_num); + } endian_convert_TxPD(plocal_tx_pd); @@ -321,6 +352,11 @@ mlan_status wlan_ops_uap_process_rx_packet(t_void *adapter, pmlan_buffer pmbuf) /* Endian conversion */ endian_convert_RxPD(prx_pd); + if (prx_pd->flags & RXPD_FLAG_EXTRA_HEADER) { + endian_convert_RxPD_extra_header( + (rxpd_extra_info *)((t_u8 *)prx_pd + sizeof(*prx_pd))); + } + if (priv->adapter->pcard_info->v14_fw_api) { t_u8 rxpd_rate_info_orig = prx_pd->rate_info; prx_pd->rate_info = wlan_convert_v14_rx_rate_info( @@ -634,6 +670,11 @@ mlan_status wlan_process_uap_rx_packet(mlan_private *priv, pmlan_buffer pmbuf) PRINTM(MDATA, "Rx dest " MACSTR "\n", MAC2STR(prx_pkt->eth803_hdr.dest_addr)); + if (pmadapter->enable_net_mon) { + pmbuf->flags |= MLAN_BUF_FLAG_NET_MONITOR; + goto upload; + } + /* don't do packet forwarding in disconnected state */ /* don't do packet forwarding when packet > 1514 */ if (priv->media_connected == MFALSE) @@ -805,6 +846,14 @@ upload: PRINTM(MDATA, "%lu.%06lu : Data => kernel seq_num=%d tid=%d\n", pmbuf->out_ts_sec, pmbuf->out_ts_usec, prx_pd->seq_num, prx_pd->priority); + if (pmbuf->flags & MLAN_BUF_FLAG_NET_MONITOR) { + // Use some rxpd space to save rxpd info for radiotap header + // We should insure radiotap_info is not bigger than RxPD + wlan_rxpdinfo_to_radiotapinfo( + priv, (RxPD *)prx_pd, + (radiotap_info *)(pmbuf->pbuf + pmbuf->data_offset - + sizeof(radiotap_info))); + } ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle, pmbuf); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_usb.c b/mxm_wifiex/wlan_src/mlan/mlan_usb.c index 5e32dec..3185ff1 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_usb.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_usb.c @@ -93,6 +93,16 @@ static const struct _mlan_card_info mlan_card_info_usb9097 = { }; #endif +#ifdef USBNW62X +static const struct _mlan_card_info mlan_card_info_usbNW62X = { + .max_tx_buf_size = MLAN_TX_DATA_BUF_SIZE_4K, + .v16_fw_api = 1, + .v17_fw_api = 1, + .supp_ps_handshake = 1, + .default_11n_tx_bf_cap = DEFAULT_11N_TX_BF_CAP_2X2, +}; +#endif + /******************************************************** Global Variables ********************************************************/ @@ -245,6 +255,11 @@ static mlan_status wlan_usb_prog_fw_w_helper(pmlan_adapter pmadapter, if (IS_USB9097(pmadapter->card_type)) check_fw_status = MTRUE; #endif +#if defined(USBNW62X) + if (IS_USBNW62X(pmadapter->card_type)) + check_fw_status = MTRUE; +#endif + do { /* Send pseudo data to check winner status first */ if (check_winner) { @@ -767,6 +782,11 @@ mlan_status wlan_get_usb_device(pmlan_adapter pmadapter) case CARD_TYPE_USB9097: pmadapter->pcard_info = &mlan_card_info_usb9097; break; +#endif +#ifdef USBNW62X + case CARD_TYPE_USBNW62X: + pmadapter->pcard_info = &mlan_card_info_usbNW62X; + break; #endif default: PRINTM(MERROR, "can't get right USB card type \n"); @@ -1167,7 +1187,7 @@ static mlan_status wlan_usb_host_to_card(pmlan_private pmpriv, t_u8 type, return MLAN_STATUS_FAILURE; } if (type == MLAN_TYPE_CMD -#if (defined(USB9098) || defined(USB9097)) +#if (defined(USB9098) || defined(USB9097) || defined(USBNW62X)) || type == MLAN_TYPE_VDLL #endif ) { diff --git a/mxm_wifiex/wlan_src/mlan/mlan_wmm.c b/mxm_wifiex/wlan_src/mlan/mlan_wmm.c index 1ff9ac1..b25074d 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_wmm.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_wmm.c @@ -1110,13 +1110,13 @@ static int wlan_dequeue_tx_packet(pmlan_adapter pmadapter) } } } - if (!ptr->is_11n_enabled || + if (!ptr->is_wmm_enabled || (ptr->ba_status || ptr->del_ba_count >= DEL_BA_THRESHOLD) #ifdef STA_SUPPORT || priv->wps.session_enable #endif /* STA_SUPPORT */ ) { - if (ptr->is_11n_enabled && ptr->ba_status && + if (ptr->is_wmm_enabled && ptr->ba_status && ptr->amsdu_in_ampdu && wlan_is_amsdu_allowed(priv, ptr, tid) && (wlan_num_pkts_in_txq(priv, ptr, pmadapter->tx_buf_size) >= @@ -1668,8 +1668,8 @@ void wlan_ralist_add(mlan_private *priv, t_u8 *ra) ra_list->ba_status = BA_STREAM_NOT_SETUP; ra_list->amsdu_in_ampdu = MFALSE; if (queuing_ra_based(priv)) { - ra_list->is_11n_enabled = wlan_is_11n_enabled(priv, ra); - if (ra_list->is_11n_enabled) + ra_list->is_wmm_enabled = wlan_is_11n_enabled(priv, ra); + if (ra_list->is_wmm_enabled) ra_list->max_amsdu = get_station_max_amsdu_size(priv, ra); ra_list->tx_pause = wlan_is_tx_pause(priv, ra); @@ -1678,25 +1678,25 @@ void wlan_ralist_add(mlan_private *priv, t_u8 *ra) ra_list->tx_pause = MFALSE; status = wlan_get_tdls_link_status(priv, ra); if (MTRUE == wlan_is_tdls_link_setup(status)) { - ra_list->is_11n_enabled = + ra_list->is_wmm_enabled = is_station_11n_enabled(priv, ra); - if (ra_list->is_11n_enabled) + if (ra_list->is_wmm_enabled) ra_list->max_amsdu = get_station_max_amsdu_size(priv, ra); ra_list->is_tdls_link = MTRUE; } else { - ra_list->is_11n_enabled = IS_11N_ENABLED(priv); - if (ra_list->is_11n_enabled) + ra_list->is_wmm_enabled = IS_11N_ENABLED(priv); + if (ra_list->is_wmm_enabled) ra_list->max_amsdu = priv->max_amsdu; } } PRINTM_NETINTF(MDATA, priv); - PRINTM(MDATA, "ralist %p: is_11n_enabled=%d max_amsdu=%d\n", - ra_list, ra_list->is_11n_enabled, ra_list->max_amsdu); + PRINTM(MDATA, "ralist %p: is_wmm_enabled=%d max_amsdu=%d\n", + ra_list, ra_list->is_wmm_enabled, ra_list->max_amsdu); - if (ra_list->is_11n_enabled) { + if (ra_list->is_wmm_enabled) { ra_list->packet_count = 0; ra_list->ba_packet_threshold = wlan_get_random_ba_threshold(pmadapter); @@ -2008,15 +2008,15 @@ int wlan_ralist_update(mlan_private *priv, t_u8 *old_ra, t_u8 *new_ra) update_count++; if (queuing_ra_based(priv)) { - ra_list->is_11n_enabled = + ra_list->is_wmm_enabled = wlan_is_11n_enabled(priv, new_ra); - if (ra_list->is_11n_enabled) + if (ra_list->is_wmm_enabled) ra_list->max_amsdu = get_station_max_amsdu_size( priv, new_ra); } else { - ra_list->is_11n_enabled = IS_11N_ENABLED(priv); - if (ra_list->is_11n_enabled) + ra_list->is_wmm_enabled = IS_11N_ENABLED(priv); + if (ra_list->is_wmm_enabled) ra_list->max_amsdu = priv->max_amsdu; } @@ -2029,7 +2029,7 @@ int wlan_ralist_update(mlan_private *priv, t_u8 *old_ra, t_u8 *new_ra) PRINTM(MINFO, "ralist_update: %p, %d, " MACSTR "-->" MACSTR "\n", - ra_list, ra_list->is_11n_enabled, + ra_list, ra_list->is_wmm_enabled, MAC2STR(ra_list->ra), MAC2STR(new_ra)); memcpy_ext(priv->adapter, ra_list->ra, new_ra, diff --git a/mxm_wifiex/wlan_src/mlinux/mlan.h b/mxm_wifiex/wlan_src/mlinux/mlan.h index 566ad50..4d48ce8 100644 --- a/mxm_wifiex/wlan_src/mlinux/mlan.h +++ b/mxm_wifiex/wlan_src/mlinux/mlan.h @@ -4,7 +4,7 @@ * It also defines the data structures used for APIs between MLAN and MOAL. * * - * Copyright 2008-2020 NXP + * Copyright 2008-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mxm_wifiex/wlan_src/mlinux/mlan_decl.h b/mxm_wifiex/wlan_src/mlinux/mlan_decl.h index f24b04b..7d1be10 100644 --- a/mxm_wifiex/wlan_src/mlinux/mlan_decl.h +++ b/mxm_wifiex/wlan_src/mlinux/mlan_decl.h @@ -3,7 +3,7 @@ * @brief This file declares the generic data structures and APIs. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -24,7 +24,7 @@ #define _MLAN_DECL_H_ /** MLAN release version */ -#define MLAN_RELEASE_VERSION "299.p1" +#define MLAN_RELEASE_VERSION "322" /** Re-define generic data types for MLAN/MOAL */ /** Signed char (1-byte) */ @@ -98,6 +98,8 @@ typedef t_s32 t_sval; /** MLAN FALSE */ #define MFALSE (0) +#define CHANNEL_SPEC_SNIFFER_MODE 1 + #ifndef MACSTR /** MAC address security format */ #define MACSTR "%02x:XX:XX:XX:%02x:%02x" @@ -375,6 +377,8 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; #define CARD_TYPE_9177 0x09 /** 8801 card type */ #define CARD_TYPE_8801 0x0a +/** OWL card type */ +#define CARD_TYPE_NW62X 0x0b /** 9098 A0 reverion num */ #define CHIP_9098_REV_A0 1 @@ -406,6 +410,8 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; #define CARD_TYPE_SD9177 (CARD_TYPE_9177 | (INTF_SD << 8)) /** SD8801 card type */ #define CARD_TYPE_SD8801 (CARD_TYPE_8801 | (INTF_SD << 8)) +/** SD_NW62X card type */ +#define CARD_TYPE_SDNW62X (CARD_TYPE_NW62X | (INTF_SD << 8)) #define IS_SD8887(ct) (CARD_TYPE_SD8887 == (ct)) #define IS_SD8897(ct) (CARD_TYPE_SD8897 == (ct)) @@ -417,6 +423,7 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; #define IS_SD9098(ct) (CARD_TYPE_SD9098 == (ct)) #define IS_SD9177(ct) (CARD_TYPE_SD9177 == (ct)) #define IS_SD8801(ct) (CARD_TYPE_SD8801 == (ct)) +#define IS_SDNW62X(ct) (CARD_TYPE_SDNW62X == (ct)) /** SD8887 Card */ #define CARD_SD8887 "SD8887" @@ -431,15 +438,15 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; /** SD8987 Card */ #define CARD_SD8987 "SD8987" /** SD9097 Card */ -#define CARD_SD9097 "SD9097" -/** SDIW620 Card */ -#define CARD_SDIW620 "SDIW620" +#define CARD_SD9097 "SDIW620" /** SD9098 Card */ #define CARD_SD9098 "SD9098" /** SD9177 Card */ #define CARD_SD9177 "SD9177" /** SD8801 Card */ #define CARD_SD8801 "SD8801" +/** SDNW62X Card */ +#define CARD_SDNW62X "SDNW62X" #endif #ifdef PCIE @@ -451,26 +458,29 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; #define CARD_TYPE_PCIE9097 (CARD_TYPE_9097 | (INTF_PCIE << 8)) /** PCIE9098 card type */ #define CARD_TYPE_PCIE9098 (CARD_TYPE_9098 | (INTF_PCIE << 8)) +/** PCIENW62X card type */ +#define CARD_TYPE_PCIENW62X (CARD_TYPE_NW62X | (INTF_PCIE << 8)) #define IS_PCIE8897(ct) (CARD_TYPE_PCIE8897 == (ct)) #define IS_PCIE8997(ct) (CARD_TYPE_PCIE8997 == (ct)) #define IS_PCIE9097(ct) (CARD_TYPE_PCIE9097 == (ct)) #define IS_PCIE9098(ct) (CARD_TYPE_PCIE9098 == (ct)) +#define IS_PCIENW62X(ct) (CARD_TYPE_PCIENW62X == (ct)) /** PCIE8897 Card */ #define CARD_PCIE8897 "PCIE8897" /** PCIE8997 Card */ #define CARD_PCIE8997 "PCIE8997" /** PCIE9097 Card */ -#define CARD_PCIE9097 "PCIE9097" -/** PCIEIW620 Card */ -#define CARD_PCIEIW620 "PCIEIW620" +#define CARD_PCIE9097 "PCIEIW620" /** PCIE9000S Card */ #define CARD_PCIE9000S "PCIE9000S" /** PCIE9098 Card */ #define CARD_PCIE9098 "PCIE9098" /** PCIEAW690 Card */ #define CARD_PCIEAW690 "PCIEAW690" +/** PCIENW62X Card */ +#define CARD_PCIENW62X "PCIENW62X" #endif #ifdef USB @@ -486,6 +496,8 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; #define CARD_TYPE_USB9098 (CARD_TYPE_9098 | (INTF_USB << 8)) /** USB9097 card type */ #define CARD_TYPE_USB9097 (CARD_TYPE_9097 | (INTF_USB << 8)) +/** USBNW62X card type */ +#define CARD_TYPE_USBNW62X (CARD_TYPE_NW62X | (INTF_USB << 8)) #define IS_USB8801(ct) (CARD_TYPE_USB8801 == (ct)) #define IS_USB8897(ct) (CARD_TYPE_USB8897 == (ct)) @@ -493,6 +505,7 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; #define IS_USB8978(ct) (CARD_TYPE_USB8978 == (ct)) #define IS_USB9098(ct) (CARD_TYPE_USB9098 == (ct)) #define IS_USB9097(ct) (CARD_TYPE_USB9097 == (ct)) +#define IS_USBNW62X(ct) (CARD_TYPE_USBNW62X == (ct)) /** USB8801 Card */ #define CARD_USB8801 "USB8801" @@ -505,9 +518,9 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; /** USB9098 Card */ #define CARD_USB9098 "USB9098" /** USB9097 Card */ -#define CARD_USB9097 "USB9097" -/** USBIW620 Card */ -#define CARD_USBIW620 "USBIW620" +#define CARD_USB9097 "USBIW620" +/** USBNW62X Card */ +#define CARD_USBNW62X "USBNW62X" #endif #define IS_CARD8801(ct) (CARD_TYPE_8801 == ((ct)&0xf)) @@ -519,6 +532,7 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; #define IS_CARD9098(ct) (CARD_TYPE_9098 == ((ct)&0xf)) #define IS_CARD9097(ct) (CARD_TYPE_9097 == ((ct)&0xf)) #define IS_CARD9177(ct) (CARD_TYPE_9177 == ((ct)&0xf)) +#define IS_CARDNW62X(ct) (CARD_TYPE_NW62X == ((ct)&0xf)) typedef struct _card_type_entry { t_u16 card_type; @@ -578,6 +592,9 @@ typedef enum { /** Buffer flag for TX_STATUS */ #define MLAN_BUF_FLAG_TX_STATUS MBIT(10) +/** Buffer flag for NET_MONITOR */ +#define MLAN_BUF_FLAG_NET_MONITOR MBIT(11) + /** Buffer flag for NULL data packet */ #define MLAN_BUF_FLAG_NULL_PKT MBIT(12) /** Buffer flag for Diag pkt */ @@ -585,6 +602,8 @@ typedef enum { #define MLAN_BUF_FLAG_TX_CTRL MBIT(14) +#define MLAN_BUF_FLAG_MC_AGGR_PKT MBIT(17) + #ifdef DEBUG_LEVEL1 /** Debug level bit definition */ #define MMSG MBIT(0) @@ -694,6 +713,7 @@ typedef enum _mlan_bss_type { #ifdef WIFI_DIRECT_SUPPORT MLAN_BSS_TYPE_WIFIDIRECT = 2, #endif + MLAN_BSS_TYPE_DFS = 8, MLAN_BSS_TYPE_ANY = 0xff, } mlan_bss_type; @@ -767,6 +787,7 @@ typedef enum _mlan_event_id { #if defined(PCIE) MLAN_EVENT_ID_SSU_DUMP_FILE = 0x00000039, #endif /* SSU_SUPPORT */ + MLAN_EVENT_ID_CSI = 0x00000040, /* Event generated by MLAN driver (MSB=1) */ MLAN_EVENT_ID_DRV_CONNECTED = 0x80000001, MLAN_EVENT_ID_DRV_DEFER_HANDLING = 0x80000002, @@ -789,6 +810,7 @@ typedef enum _mlan_event_id { #ifdef UAP_SUPPORT MLAN_EVENT_ID_DRV_UAP_CHAN_INFO = 0x80000020, #endif + MLAN_EVENT_ID_FW_ROAM_OFFLOAD_RESULT = 0x80000023, MLAN_EVENT_ID_DRV_ASSOC_FAILURE_LOGGER = 0x80000026, MLAN_EVENT_ID_DRV_ASSOC_SUCC_LOGGER = 0x80000027, MLAN_EVENT_ID_DRV_DISCONNECT_LOGGER = 0x80000028, @@ -875,6 +897,7 @@ enum mlan_channel_type { enum { BAND_2GHZ = 0, BAND_5GHZ = 1, BAND_4GHZ = 2, + BAND_6GHZ = 3, }; /** channel offset */ @@ -925,16 +948,6 @@ typedef enum _dfs_w53_cfg_t { /** Band_Config_t */ typedef MLAN_PACK_START struct _Band_Config_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Channel Selection Mode - (00)=manual, (01)=ACS, (02)=user*/ - t_u8 scanMode : 2; - /** Secondary Channel Offset - (00)=None, (01)=Above, (11)=Below */ - t_u8 chan2Offset : 2; - /** Channel Width - (00)=20MHz, (10)=40MHz, (11)=80MHz */ - t_u8 chanWidth : 2; - /** Band Info - (00)=2.4GHz, (01)=5GHz */ - t_u8 chanBand : 2; -#else /** Band Info - (00)=2.4GHz, (01)=5GHz */ t_u8 chanBand : 2; /** Channel Width - (00)=20MHz, (10)=40MHz, (11)=80MHz */ @@ -943,7 +956,6 @@ typedef MLAN_PACK_START struct _Band_Config_t { t_u8 chan2Offset : 2; /** Channel Selection Mode - (00)=manual, (01)=ACS, (02)=Adoption mode*/ t_u8 scanMode : 2; -#endif } MLAN_PACK_END Band_Config_t; /** channel_band_t */ @@ -1033,6 +1045,45 @@ typedef struct _mlan_cmdresp_event { } mlan_cmdresp_event, *pmlan_cmdresp_event; /** csi event data structure */ +typedef MLAN_PACK_START struct _csi_record_ds { + /** Length in DWORDS, including header */ + t_u16 Len; + /** CSI signature. 0xABCD fixed */ + t_u16 CSI_Sign; + /** User defined HeaderID */ + t_u32 CSI_HeaderID; + /** Packet info field */ + t_u16 PKT_info; + /** Frame control field for the received packet*/ + t_u16 FCF; + /** Timestamp when packet received */ + t_u64 TSF; + /** Received Packet Destination MAC Address */ + t_u8 Dst_MAC[6]; + /** Received Packet Source MAC Address */ + t_u8 Src_MAC[6]; + /** RSSI for antenna A */ + t_u8 Rx_RSSI_A; + /** RSSI for antenna B */ + t_u8 Rx_RSSI_B; + /** Noise floor for antenna A */ + t_u8 Rx_NF_A; + /** Noise floor for antenna A */ + t_u8 Rx_NF_B; + /** Rx signal strength above noise floor */ + t_u8 Rx_SINR; + /** Channel */ + t_u8 channel; + /** user defined Chip ID */ + t_u16 chip_id; + /** Reserved */ + t_u32 rsvd; + /** CSI data length in DWORDs */ + t_u32 CSI_Data_Length; + /** Start of CSI data */ + t_u8 CSI_Data[0]; + /** At the end of CSI raw data, user defined TailID of 4 bytes*/ +} MLAN_PACK_END csi_record_ds, *pcsi_record_ds; /** mlan_ioctl_req data structure */ typedef struct _mlan_ioctl_req { @@ -1060,18 +1111,52 @@ typedef struct _mlan_ioctl_req { t_ptr reserved_1; } mlan_ioctl_req, *pmlan_ioctl_req; +typedef MLAN_PACK_START struct _mix_rate_info { + /** bit0: LGI: gi=0, SGI: gi= 1 */ + /** bit1-2: 20M: bw=0, 40M: bw=1, 80M: bw=2, 160M: bw=3 */ + /** bit3-4: LG: format=0, HT: format=1, VHT: format=2 */ + /** bit5: LDPC: 0-not support, 1-support */ + /** bit6-7:reserved */ + t_u8 rate_info; + /** MCS index */ + t_u8 mcs_index; + /** bitrate, in 500Kbps */ + t_u16 bitrate; +} MLAN_PACK_END mix_rate_info, *pmix_rate_info; + +typedef MLAN_PACK_START struct _rxpd_extra_info { + /** flags */ + t_u8 flags; + /** channel.flags */ + t_u16 channel_flags; + /** mcs.known */ + t_u8 mcs_known; + /** mcs.flags */ + t_u8 mcs_flags; + /** vht sig1 */ + t_u32 vht_sig1; + /** vht sig2 */ + t_u32 vht_sig2; +} MLAN_PACK_END rxpd_extra_info, *prxpd_extra_info; + +typedef MLAN_PACK_START struct _radiotap_info { + /** Rate Info */ + mix_rate_info rate_info; + /** SNR */ + t_s8 snr; + /** Noise Floor */ + t_s8 nf; + /** band config */ + t_u8 band_config; + /** chan number */ + t_u8 chan_num; + t_u8 antenna; + /** extra rxpd info from FW */ + rxpd_extra_info extra_info; +} MLAN_PACK_END radiotap_info, *pradiotap_info; + /** txpower structure */ typedef MLAN_PACK_START struct { -#ifdef BIG_ENDIAN_SUPPORT - /** Host tx power ctrl: - 0x0: use fw setting for TX power - 0x1: value specified in bit[6] and bit[5:0] are valid */ - t_u8 hostctl : 1; - /** Sign of the power specified in bit[5:0] */ - t_u8 sign : 1; - /** Power to be used for transmission(in dBm) */ - t_u8 abs_val : 6; -#else /** Power to be used for transmission(in dBm) */ t_u8 abs_val : 6; /** Sign of the power specified in bit[5:0] */ @@ -1080,7 +1165,6 @@ typedef MLAN_PACK_START struct { 0x0: use fw setting for TX power 0x1: value specified in bit[6] and bit[5:0] are valid */ t_u8 hostctl : 1; -#endif } MLAN_PACK_END tx_power_t; /* pkt_txctrl */ typedef MLAN_PACK_START struct _pkt_txctrl { @@ -1111,6 +1195,25 @@ typedef MLAN_PACK_START struct _pkt_rxinfo { t_u8 rssi; } MLAN_PACK_END pkt_rxinfo, *ppkt_rxinfo; +#define MC_FLAG_RETRY MBIT(0) +#define MC_FLAG_START_CYCLE MBIT(1) +#define MC_FLAG_END_CYCLE MBIT(2) +#define MC_FLAG_START_AMPDU MBIT(3) +#define MC_FLAG_END_AMPDU MBIT(4) +/* mc pkt txcontrol */ +typedef MLAN_PACK_START struct _mc_txcontrol { + /** Data rate in mcs index, 0-7 */ + t_u8 mcs_index; + /** band width 0-20Mhz, 1-40Mhz */ + t_u8 bandwidth; + /** seq_num */ + t_u16 seq_num; + /** packet expiry time */ + t_u32 pkt_expiry; + /** mc_pkt_flags */ + t_u8 mc_pkt_flags; +} MLAN_PACK_END mc_txcontrol, *pmc_txcontrol; + /** mlan_buffer data structure */ typedef struct _mlan_buffer { /** Pointer to previous mlan_buffer */ @@ -1162,6 +1265,7 @@ typedef struct _mlan_buffer { /** Use count for this buffer */ t_u32 use_count; union { + mc_txcontrol mc_tx_info; pkt_txctrl tx_info; pkt_rxinfo rx_info; } u; @@ -2270,4 +2374,6 @@ MLAN_API mlan_status mlan_disable_host_int(t_void *padapter); /** mlan unmask host interrupt */ MLAN_API mlan_status mlan_enable_host_int(t_void *padapter); +#define CSI_SIGNATURE 0xABCD + #endif /* !_MLAN_DECL_H_ */ diff --git a/mxm_wifiex/wlan_src/mlinux/mlan_ieee.h b/mxm_wifiex/wlan_src/mlinux/mlan_ieee.h index 500ee3e..743d789 100644 --- a/mxm_wifiex/wlan_src/mlinux/mlan_ieee.h +++ b/mxm_wifiex/wlan_src/mlinux/mlan_ieee.h @@ -4,7 +4,7 @@ * definitions used in MLAN and MOAL module. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -46,17 +46,10 @@ typedef enum _WLAN_802_11_NETWORK_TYPE { Wlan802_11NetworkTypeMax } WLAN_802_11_NETWORK_TYPE; -#ifdef BIG_ENDIAN_SUPPORT -/** Frame control: Type Mgmt frame */ -#define IEEE80211_FC_MGMT_FRAME_TYPE_MASK 0x3000 -/** Frame control: SubType Mgmt frame */ -#define IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE(fc) (((fc)&0xF000) >> 12) -#else /** Frame control: Type Mgmt frame */ #define IEEE80211_FC_MGMT_FRAME_TYPE_MASK 0x000C /** Frame control: SubType Mgmt frame */ #define IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE(fc) (((fc)&0x00F0) >> 4) -#endif #ifdef PRAGMA_PACK #pragma pack(push, 1) @@ -67,7 +60,8 @@ typedef enum _WLAN_802_11_NETWORK_TYPE { typedef enum _IEEEtypes_Ext_ElementId_e { HE_CAPABILITY = 35, - HE_OPERATION = 36 + HE_OPERATION = 36, + HE_6G_CAPABILITY = 59 } IEEEtypes_Ext_ElementId_e; /** IEEE Type definitions */ @@ -178,21 +172,12 @@ typedef MLAN_PACK_START struct _IEEEtypes_Generic_t { /**ft capability policy*/ typedef MLAN_PACK_START struct _IEEEtypes_FtCapPolicy_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Reserved */ - t_u8 reserved : 6; - /** RIC support */ - t_u8 ric : 1; - /** FT over the DS capable */ - t_u8 ft_over_ds : 1; -#else /** FT over the DS capable */ t_u8 ft_over_ds : 1; /** RIC support */ t_u8 ric : 1; /** Reserved */ t_u8 reserved : 6; -#endif } MLAN_PACK_END IEEEtypes_FtCapPolicy_t; /** Mobility domain IE */ @@ -325,25 +310,6 @@ typedef MLAN_PACK_START struct _TLV_Generic_t { #define CAPINFO_MASK (~(MBIT(15) | MBIT(14) | MBIT(11) | MBIT(9))) /** Capability Bit Map*/ -#ifdef BIG_ENDIAN_SUPPORT -typedef MLAN_PACK_START struct _IEEEtypes_CapInfo_t { - t_u8 rsrvd1 : 2; - t_u8 dsss_ofdm : 1; - t_u8 radio_measurement : 1; - t_u8 rsvrd2 : 1; - t_u8 short_slot_time : 1; - t_u8 rsrvd3 : 1; - t_u8 spectrum_mgmt : 1; - t_u8 chan_agility : 1; - t_u8 pbcc : 1; - t_u8 short_preamble : 1; - t_u8 privacy : 1; - t_u8 cf_poll_rqst : 1; - t_u8 cf_pollable : 1; - t_u8 ibss : 1; - t_u8 ess : 1; -} MLAN_PACK_END IEEEtypes_CapInfo_t, *pIEEEtypes_CapInfo_t; -#else typedef MLAN_PACK_START struct _IEEEtypes_CapInfo_t { /** Capability Bit Map : ESS */ t_u8 ess : 1; @@ -376,7 +342,6 @@ typedef MLAN_PACK_START struct _IEEEtypes_CapInfo_t { /** Capability Bit Map : Reserved */ t_u8 rsrvd1 : 2; } MLAN_PACK_END IEEEtypes_CapInfo_t, *pIEEEtypes_CapInfo_t; -#endif /* BIG_ENDIAN_SUPPORT */ /** IEEEtypes_Ssid_t */ typedef MLAN_PACK_START struct _IEEEtypes_Ssid_t { @@ -591,35 +556,16 @@ typedef MLAN_PACK_START struct _IEEEtypes_Wpa_t { /** Data structure of WMM QoS information */ typedef MLAN_PACK_START struct _IEEEtypes_WmmQosInfo_t { -#ifdef BIG_ENDIAN_SUPPORT - /** QoS UAPSD */ - t_u8 qos_uapsd : 1; - /** Reserved */ - t_u8 reserved : 3; - /** Parameter set count */ - t_u8 para_set_count : 4; -#else /** Parameter set count */ t_u8 para_set_count : 4; /** Reserved */ t_u8 reserved : 3; /** QoS UAPSD */ t_u8 qos_uapsd : 1; -#endif /* BIG_ENDIAN_SUPPORT */ } MLAN_PACK_END IEEEtypes_WmmQosInfo_t, *pIEEEtypes_WmmQosInfo_t; /** Data structure of WMM Aci/Aifsn */ typedef MLAN_PACK_START struct _IEEEtypes_WmmAciAifsn_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Reserved */ - t_u8 reserved : 1; - /** Aci */ - t_u8 aci : 2; - /** Acm */ - t_u8 acm : 1; - /** Aifsn */ - t_u8 aifsn : 4; -#else /** Aifsn */ t_u8 aifsn : 4; /** Acm */ @@ -628,22 +574,14 @@ typedef MLAN_PACK_START struct _IEEEtypes_WmmAciAifsn_t { t_u8 aci : 2; /** Reserved */ t_u8 reserved : 1; -#endif /* BIG_ENDIAN_SUPPORT */ } MLAN_PACK_END IEEEtypes_WmmAciAifsn_t, *pIEEEtypes_WmmAciAifsn_t; /** Data structure of WMM ECW */ typedef MLAN_PACK_START struct _IEEEtypes_WmmEcw_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Maximum Ecw */ - t_u8 ecw_max : 4; - /** Minimum Ecw */ - t_u8 ecw_min : 4; -#else /** Minimum Ecw */ t_u8 ecw_min : 4; /** Maximum Ecw */ t_u8 ecw_max : 4; -#endif /* BIG_ENDIAN_SUPPORT */ } MLAN_PACK_END IEEEtypes_WmmEcw_t, *pIEEEtypes_WmmEcw_t; /** Data structure of WMM AC parameters */ @@ -731,22 +669,6 @@ typedef MLAN_PACK_START enum _IEEEtypes_WMM_TSPEC_TS_TRAFFIC_TYPE_e { /** Data structure of WMM TSPEC information */ typedef MLAN_PACK_START struct { -#ifdef BIG_ENDIAN_SUPPORT - t_u8 Reserved17_23 : 7; /* ! Reserved */ - t_u8 Schedule : 1; - IEEEtypes_WMM_TSPEC_TS_Info_AckPolicy_e AckPolicy : 2; - t_u8 UserPri : 3; /* ! 802.1d User Priority */ - // IEEEtypes_WMM_TSPEC_TS_Info_PSB_e PowerSaveBehavior : 1; /* - // !Legacy/Trigg*/ - t_u8 PowerSaveBehavior : 1; - t_u8 Aggregation : 1; /* ! Reserved */ - t_u8 AccessPolicy2 : 1; /* ! */ - t_u8 AccessPolicy1 : 1; /* ! */ - IEEEtypes_WMM_TSPEC_TS_Info_Direction_e Direction : 2; - t_u8 TID : 4; /* ! Unique identifier */ - // IEEEtypes_WMM_TSPEC_TS_TRAFFIC_TYPE_e TrafficType : 1; - t_u8 TrafficType : 1; -#else // IEEEtypes_WMM_TSPEC_TS_TRAFFIC_TYPE_e TrafficType : 1; t_u8 TrafficType : 1; t_u8 TID : 4; /* ! Unique identifier */ @@ -761,31 +683,19 @@ typedef MLAN_PACK_START struct { IEEEtypes_WMM_TSPEC_TS_Info_AckPolicy_e AckPolicy : 2; t_u8 Schedule : 1; t_u8 Reserved17_23 : 7; /* ! Reserved */ -#endif } MLAN_PACK_END IEEEtypes_WMM_TSPEC_TS_Info_t; /** Data structure of WMM TSPEC Nominal Size */ typedef MLAN_PACK_START struct { -#ifdef BIG_ENDIAN_SUPPORT - t_u16 Fixed : 1; /* ! 1: Fixed size given in Size, 0: Var, size is - nominal */ - t_u16 Size : 15; /* ! Nominal size in octets */ -#else t_u16 Size : 15; /* ! Nominal size in octets */ t_u16 Fixed : 1; /* ! 1: Fixed size given in Size, 0: Var, size is nominal */ -#endif } MLAN_PACK_END IEEEtypes_WMM_TSPEC_NomMSDUSize_t; /** Data structure of WMM TSPEC SBWA */ typedef MLAN_PACK_START struct { -#ifdef BIG_ENDIAN_SUPPORT - t_u16 Whole : 3; /* ! Whole portion */ - t_u16 Fractional : 13; /* ! Fractional portion */ -#else t_u16 Fractional : 13; /* ! Fractional portion */ t_u16 Whole : 3; /* ! Whole portion */ -#endif } MLAN_PACK_END IEEEtypes_WMM_TSPEC_SBWA; /** Data structure of WMM TSPEC Body */ @@ -1126,26 +1036,6 @@ typedef MLAN_PACK_START struct _VHT_MCS_set { /** VHT Capabilities info field, reference 802.11ac D1.4 p89 */ typedef MLAN_PACK_START struct _VHT_capa { #if 0 -#ifdef BIG_ENDIAN_SUPPORT - t_u8 mpdu_max_len:2; - t_u8 chan_width:2; - t_u8 rx_LDPC:1; - t_u8 sgi_80:1; - t_u8 sgi_160:1; - t_u8 tx_STBC:1; - t_u8 rx_STBC:3; - t_u8 SU_beamformer_capa:1; - t_u8 SU_beamformee_capa:1; - t_u8 beamformer_ante_num:3; - t_u8 sounding_dim_num:3; - t_u8 MU_beamformer_capa:1; - t_u8 MU_beamformee_capa:1; - t_u8 VHT_TXOP_ps:1; - t_u8 HTC_VHT_capa:1; - t_u8 max_ampdu_len:3; - t_u8 link_apapt_capa:2; - t_u8 reserved_1:4; -#else t_u8 reserved_1:4; t_u8 link_apapt_capa:2; t_u8 max_ampdu_len:3; @@ -1164,7 +1054,6 @@ typedef MLAN_PACK_START struct _VHT_capa { t_u8 rx_LDPC:1; t_u8 chan_width:2; t_u8 mpdu_max_len:2; -#endif /* BIG_ENDIAN_SUPPORT */ #endif t_u32 vht_cap_info; VHT_MCS_set_t mcs_sets; @@ -1272,6 +1161,32 @@ typedef MLAN_PACK_START struct _IEEEtypes_Extension_t { t_u8 data[]; } MLAN_PACK_END IEEEtypes_Extension_t, *pIEEEtypes_Extension_t; +typedef MLAN_PACK_START struct _IEEEtypes_HeMcsMap_t { + /** Max HE-MAC for 1 SS */ + t_u8 max_mcs_1ss : 2; + /** Max HE-MAC for 2 SS */ + t_u8 max_mcs_2ss : 2; + /** Max HE-MAC for 3 SS */ + t_u8 max_mcs_3ss : 2; + /** Max HE-MAC for 4 SS */ + t_u8 max_mcs_4ss : 2; + /** Max HE-MAC for 5 SS */ + t_u8 max_mcs_5ss : 2; + /** Max HE-MAC for 6 SS */ + t_u8 max_mcs_6ss : 2; + /** Max HE-MAC for 7 SS */ + t_u8 max_mcs_7ss : 2; + /** Max HE-MAC for 8 SS */ + t_u8 max_mcs_8ss : 2; +} MLAN_PACK_END IEEEtypes_HeMcsMap_t, *pIEEEtypes_HeMcsMap_t; + +typedef MLAN_PACK_START struct _IEEEtypes_HeMcsNss_t { + /** HE Rx MCS and NSS Set */ + t_u16 rx_mcs; + /** HE Tx MCS and NSS Set*/ + t_u16 tx_mcs; +} MLAN_PACK_END IEEEtypes_HeMcsNss_t, *pIEEEtypes_HeMcsNss_t; + typedef MLAN_PACK_START struct _IEEEtypes_HECap_t { /** Generic IE header */ IEEEtypes_Header_t ieee_hdr; @@ -1281,11 +1196,55 @@ typedef MLAN_PACK_START struct _IEEEtypes_HECap_t { t_u8 he_mac_cap[6]; /** he phy capability info */ t_u8 he_phy_cap[11]; - /** he txrx mcs support , size would be 4 or 8 or 12 */ + /** he txrx mcs support (for 80 MHz) */ t_u8 he_txrx_mcs_support[4]; - /** PPE Thresholds (optional) */ + /** Optional Field, including he_txrx_mcs_support for 160 and 80+80 MHz, + * and PPE Thresholds */ + t_u8 option[28]; } MLAN_PACK_END IEEEtypes_HECap_t, *pIEEEtypes_HECap_t; +typedef MLAN_PACK_START struct _IEEEtypes_HeOpParam_t { + /** Default PE Duration */ + t_u16 default_pe_dur : 3; /* bit 0-2 */ + /** TWT Required */ + t_u16 twt_req : 1; /* bit 3 */ + /** TXOP Duration RTS Threshold */ + t_u16 txop_dur_rts_threshold : 10; /* bit 4-13 */ + /** VHT Operation Info Present */ + t_u16 vht_op_info_present : 1; /* bit 14 */ + /** Co-Hosted BSS */ + t_u16 co_located_bss : 1; /* bit 15 */ + /** ER SU Disable */ + t_u8 er_su_disable : 1; /* bit 16 */ + /** Reserved, including 6G Operation Info Pressent (bit17) */ + t_u8 reserved : 7; /* bit 17-23 */ +} MLAN_PACK_END IEEEtypes_HeOpParam_t; + +typedef MLAN_PACK_START struct _IEEEtypes_HeBssColorInfo_t { + /** BSS Color */ + t_u8 bss_color : 6; /* bit 0-5 */ + /** Partial BSS Color */ + t_u8 partial_bss_color : 1; /* bit 6 */ + /** BSS Color Disabled */ + t_u8 bss_color_disabled : 1; /* bit 7 */ +} MLAN_PACK_END IEEEtypes_HeBssColorInfo_t; + +typedef MLAN_PACK_START struct _IEEEtypes_HeOp_t { + /** Generic IE header */ + IEEEtypes_Header_t ieee_hdr; + /** Element id extension */ + t_u8 ext_id; + /** HE Operation Parameters */ + IEEEtypes_HeOpParam_t he_op_param; + /** BSS Color Info */ + IEEEtypes_HeBssColorInfo_t bss_color_info; + /** Basic HE-MCS and NSS Set */ + IEEEtypes_HeMcsMap_t basic_he_mcs_nss; + /** Optional Field, including VHT Operation Info Max Co-Hosted BSSID + * Indicator, and 6Ghz Operation Info */ + t_u8 option[9]; +} MLAN_PACK_END IEEEtypes_HeOp_t; + /** default channel switch count */ #define DEF_CHAN_SWITCH_COUNT 5 @@ -1321,7 +1280,7 @@ typedef MLAN_PACK_START struct { } MLAN_PACK_END IEEEtypes_ExtChanSwitchAnn_t; /** Maximum number of subbands in the IEEEtypes_SupportedChannels_t structure */ -#define WLAN_11H_MAX_SUBBANDS 5 +#define WLAN_11H_MAX_SUBBANDS 6 /** Maximum number of DFS channels configured in IEEEtypes_IBSS_DFS_t */ #define WLAN_11H_MAX_IBSS_DFS_CHANNELS 25 @@ -1429,20 +1388,6 @@ typedef MLAN_PACK_START struct { *** @brief Map octet of the basic measurement report (7.3.2.22.1) **/ typedef MLAN_PACK_START struct { -#ifdef BIG_ENDIAN_SUPPORT - /**< Reserved */ - t_u8 rsvd5_7 : 3; - /**< Channel is unmeasured */ - t_u8 unmeasured : 1; - /**< Radar detected on channel */ - t_u8 radar : 1; - /**< Unidentified signal found on channel */ - t_u8 unidentified_sig : 1; - /**< OFDM preamble detected on channel */ - t_u8 ofdm_preamble : 1; - /**< At least one valid MPDU received on channel */ - t_u8 bss : 1; -#else /**< At least one valid MPDU received on channel */ t_u8 bss : 1; /**< OFDM preamble detected on channel */ @@ -1455,7 +1400,6 @@ typedef MLAN_PACK_START struct { t_u8 unmeasured : 1; /**< Reserved */ t_u8 rsvd5_7 : 3; -#endif /* BIG_ENDIAN_SUPPORT */ } MLAN_PACK_END MeasRptBasicMap_t; diff --git a/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h b/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h index 21139c3..7fbf073 100644 --- a/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h +++ b/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h @@ -3,7 +3,7 @@ * @brief This file declares the IOCTL data structures and APIs. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -110,6 +110,8 @@ enum _mlan_ioctl_req_id { MLAN_OID_SNMP_MIB_DTIM_PERIOD = 0x00040006, MLAN_OID_SNMP_MIB_SIGNALEXT_ENABLE = 0x00040007, MLAN_OID_SNMP_MIB_CTRL_DEAUTH = 0x00040008, + MLAN_OID_SNMP_MIB_DOT11H_FAKERADAR = 0x00040009, + MLAN_OID_SNMP_MIB_CHAN_TRACK = 0x0004000A, /* Status Information Group */ MLAN_IOCTL_GET_INFO = 0x00050000, @@ -232,6 +234,7 @@ enum _mlan_ioctl_req_id { MLAN_OID_11H_CHAN_REPORT_REQUEST = 0x00110004, MLAN_OID_11H_CHAN_SWITCH_COUNT = 0x00110005, MLAN_OID_11H_CHAN_NOP_INFO = 0x00110006, + MLAN_OID_11H_CHAN_DFS_STATE = 0x00110007, MLAN_OID_11H_DFS_W53_CFG = 0x00110008, /* 802.11n Configuration Group RANDYTODO for value assign */ @@ -262,6 +265,7 @@ enum _mlan_ioctl_req_id { MLAN_OID_MISC_INIT_SHUTDOWN = 0x0020000D, MLAN_OID_MISC_CUSTOM_IE = 0x0020000F, MLAN_OID_MISC_TDLS_CONFIG = 0x00200010, + MLAN_OID_MISC_NET_MONITOR = 0x00200011, MLAN_OID_MISC_TX_DATAPAUSE = 0x00200012, MLAN_OID_MISC_IP_ADDR = 0x00200013, MLAN_OID_MISC_MAC_CONTROL = 0x00200014, @@ -306,6 +310,8 @@ enum _mlan_ioctl_req_id { MLAN_OID_MISC_OPER_CLASS = 0x00200038, MLAN_OID_MISC_PMIC_CFG = 0x00200039, MLAN_OID_MISC_IND_RST_CFG = 0x00200040, + MLAN_OID_MISC_ROAM_OFFLOAD = 0x00200042, + MLAN_OID_MISC_ROAM_OFFLOAD_APLIST = 0x00200043, MLAN_OID_MISC_GET_TSF = 0x00200045, MLAN_OID_MISC_GET_CHAN_REGION_CFG = 0x00200046, MLAN_OID_MISC_CLOUD_KEEP_ALIVE = 0x00200048, @@ -324,6 +330,7 @@ enum _mlan_ioctl_req_id { #if defined(PCIE) MLAN_OID_MISC_SSU = 0x00200062, #endif + MLAN_OID_MISC_CSI = 0x00200064, MLAN_OID_MISC_DMCS_CONFIG = 0x00200065, MLAN_OID_MISC_RX_ABORT_CFG = 0x00200066, MLAN_OID_MISC_RX_ABORT_CFG_EXT = 0x00200067, @@ -351,6 +358,8 @@ enum _mlan_ioctl_req_id { MLAN_OID_MISC_GET_TSF_INFO = 0x00200083, MLAN_OID_MISC_ASSOC_REQ = 0x00200084, MLAN_OID_MISC_IPS_CFG = 0x00200085, + MLAN_OID_MISC_MC_AGGR_CFG = 0x00200086, + MLAN_OID_MISC_CH_LOAD = 0x00200087, }; /** Sub command size */ @@ -600,6 +609,8 @@ enum _mlan_bss_mode { /** Maximum key length */ #define MLAN_MAX_KEY_LENGTH 32 +/** Maximum PMK R0 NAME key length */ +#define MLAN_MAX_PMKR0_NAME_LENGTH 16 /** Maximum atim window in milliseconds */ #define MLAN_MAX_ATIM_WINDOW 50 @@ -632,7 +643,7 @@ typedef struct _mlan_multicast_list { } mlan_multicast_list, *pmlan_multicast_list; /** Max channel */ -#define MLAN_MAX_CHANNEL 165 +#define MLAN_MAX_CHANNEL 177 /** Maximum number of channels in table */ #define MLAN_MAX_CHANNEL_NUM 128 @@ -746,31 +757,14 @@ typedef struct _mlan_ssid_bssid { /** Data structure of WMM ECW */ typedef struct _wmm_ecw_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Maximum Ecw */ - t_u8 ecw_max : 4; - /** Minimum Ecw */ - t_u8 ecw_min : 4; -#else /** Minimum Ecw */ t_u8 ecw_min : 4; /** Maximum Ecw */ t_u8 ecw_max : 4; -#endif /* BIG_ENDIAN_SUPPORT */ } wmm_ecw_t, *pwmm_ecw_t; /** Data structure of WMM Aci/Aifsn */ typedef struct _wmm_aci_aifsn_t { -#ifdef BIG_ENDIAN_SUPPORT - /** Reserved */ - t_u8 reserved : 1; - /** Aci */ - t_u8 aci : 2; - /** Acm */ - t_u8 acm : 1; - /** Aifsn */ - t_u8 aifsn : 4; -#else /** Aifsn */ t_u8 aifsn : 4; /** Acm */ @@ -779,7 +773,6 @@ typedef struct _wmm_aci_aifsn_t { t_u8 aci : 2; /** Reserved */ t_u8 reserved : 1; -#endif /* BIG_ENDIAN_SUPPORT */ } wmm_aci_aifsn_t, *pwmm_aci_aifsn_t; /** Data structure of WMM AC parameters */ @@ -986,21 +979,12 @@ typedef struct _wep_param { /** Data structure of WMM QoS information */ typedef struct _wmm_qos_info_t { -#ifdef BIG_ENDIAN_SUPPORT - /** QoS UAPSD */ - t_u8 qos_uapsd : 1; - /** Reserved */ - t_u8 reserved : 3; - /** Parameter set count */ - t_u8 para_set_count : 4; -#else /** Parameter set count */ t_u8 para_set_count : 4; /** Reserved */ t_u8 reserved : 3; /** QoS UAPSD */ t_u8 qos_uapsd : 1; -#endif /* BIG_ENDIAN_SUPPORT */ } wmm_qos_info_t, *pwmm_qos_info_t; /** Data structure of WMM parameter IE */ @@ -1086,6 +1070,10 @@ typedef struct _mlan_uap_bss_param { t_u8 channel; /** auth mode */ t_u16 auth_mode; + /** PWE derivation */ + t_u8 pwe_derivation; + /** transition disable */ + t_u8 transition_disable; /** encryption protocol */ t_u16 protocol; /** key managment type */ @@ -1144,6 +1132,8 @@ typedef struct _mlan_uap_scan_channels { scan_chan_list chan_list[MLAN_MAX_CHANNEL]; } mlan_uap_scan_channels; +#define MAX_NUM_PKTS 9 +#define DEF_NUM_PKTS 3 /** mlan_chan_switch_param */ typedef struct _mlan_action_chan_switch { /** mode*/ @@ -1335,7 +1325,6 @@ enum _mlan_band_def { BAND_AAC = 64, BAND_GAX = 256, BAND_AAX = 512, - }; /** Channel bandwidth */ @@ -1482,6 +1471,7 @@ typedef struct _mlan_ds_snmp_mib { t_u8 signalext_enable; /** Control deauth when uap switch channel */ t_u8 deauthctrl; + t_u8 chan_track; } param; } mlan_ds_snmp_mib, *pmlan_ds_snmp_mib; @@ -1882,6 +1872,8 @@ typedef struct _mlan_fw_info { t_u8 antinfo; /** max AP associated sta count supported by fw */ t_u8 max_ap_assoc_sta; + /** FW support roaming offload */ + t_u8 fw_roaming_support; /** Bandwidth not support 80Mhz */ t_u8 prohibit_80mhz; /** FW support beacon protection */ @@ -1899,100 +1891,6 @@ typedef struct _mlan_ver_ext { char version_str[MLAN_MAX_VER_STR_LEN]; } mlan_ver_ext, *pmlan_ver_ext; -#ifdef BIG_ENDIAN_SUPPORT -/** Extended Capabilities Data */ -typedef struct MLAN_PACK_START _ExtCap_t { - /** Extended Capabilities value */ - t_u8 rsvdBit87 : 1; /* bit 87 */ - t_u8 rsvdBit86 : 1; /* bit 86 */ - t_u8 rsvdBit85 : 1; /* bit 85 */ - t_u8 beacon_prot : 1; /* bit 84 */ - t_u8 rsvdBit83 : 1; /* bit 83 */ - t_u8 rsvdBit82 : 1; /* bit 82 */ - t_u8 rsvdBit81 : 1; /* bit 81 */ - t_u8 rsvdBit80 : 1; /* bit 80 */ - t_u8 rsvdBit79 : 1; /* bit 79 */ - t_u8 TWTResp : 1; /* bit 78 */ - t_u8 TWTReq : 1; /* bit 77 */ - t_u8 rsvdBit76 : 1; /* bit 76 */ - t_u8 rsvdBit75 : 1; /* bit 75 */ - t_u8 rsvdBit74 : 1; /* bit 74 */ - t_u8 rsvdBit73 : 1; /* bit 73 */ - t_u8 FILS : 1; /* bit 72 */ - t_u8 FTMI : 1; /* bit 71 */ - t_u8 FTMR : 1; /* bit 70 */ - t_u8 CAQ : 1; /* bit 69 */ - t_u8 rsvdBit68 : 1; /* bit 68 */ - t_u8 NCC : 1; /* bit 67 */ - t_u8 rsvdBit66 : 1; /* bit 66 */ - t_u8 chanSchedMgnt : 1; /* bit 65 */ - t_u8 MaxAMSDU1 : 1; /* bit 64 */ - t_u8 MaxAMSDU0 : 1; /* bit 63 */ - t_u8 OperModeNtf : 1; /* bit 62 */ - t_u8 TDLSWildBandwidth : 1; /* bit 61 */ - t_u8 rsvdBit60 : 1; /* bit 60 */ - t_u8 rsvdBit59 : 1; /* bit 59 */ - t_u8 rsvdBit58 : 1; /* bit 58 */ - t_u8 rsvdBit57 : 1; /* bit 57 */ - t_u8 rsvdBit56 : 1; /* bit 56 */ - t_u8 rsvdBit55 : 1; /* bit 55 */ - t_u8 rsvdBit54 : 1; /* bit 54 */ - t_u8 rsvdBit53 : 1; /* bit 53 */ - t_u8 rsvdBit52 : 1; /* bit 52 */ - t_u8 rsvdBit51 : 1; /* bit 51 */ - t_u8 rsvdBit50 : 1; /* bit 50 */ - t_u8 rsvdBit49 : 1; /* bit 49 */ - t_u8 rsvdBit48 : 1; /* bit 48 */ - t_u8 rsvdBit47 : 1; /* bit 47 */ - t_u8 rsvdBit46 : 1; /* bit 46 */ - t_u8 rsvdBit45 : 1; /* bit 45 */ - t_u8 rsvdBit44 : 1; /* bit 44 */ - t_u8 rsvdBit43 : 1; /* bit 43 */ - t_u8 rsvdBit42 : 1; /* bit 42 */ - t_u8 rsvdBit41 : 1; /* bit 41 */ - t_u8 rsvdBit40 : 1; /* bit 40 */ - t_u8 TDLSChlSwitchProhib : 1; /* bit 39 */ - t_u8 TDLSProhibited : 1; /* bit 38 */ - t_u8 TDLSSupport : 1; /* bit 37 */ - t_u8 MSGCF_Capa : 1; /* bit 36 */ - t_u8 Reserved35 : 1; /* bit 35 */ - t_u8 SSPN_Interface : 1; /* bit 34 */ - t_u8 EBR : 1; /* bit 33 */ - t_u8 Qos_Map : 1; /* bit 32 */ - t_u8 Interworking : 1; /* bit 31 */ - t_u8 TDLSChannelSwitching : 1; /* bit 30 */ - t_u8 TDLSPeerPSMSupport : 1; /* bit 29 */ - t_u8 TDLSPeerUAPSDSupport : 1; /* bit 28 */ - t_u8 UTC : 1; /* bit 27 */ - t_u8 DMS : 1; /* bit 26 */ - t_u8 SSID_List : 1; /* bit 25 */ - t_u8 ChannelUsage : 1; /* bit 24 */ - t_u8 TimingMeasurement : 1; /* bit 23 */ - t_u8 MultipleBSSID : 1; /* bit 22 */ - t_u8 AC_StationCount : 1; /* bit 21 */ - t_u8 QoSTrafficCap : 1; /* bit 20 */ - t_u8 BSS_Transition : 1; /* bit 19 */ - t_u8 TIM_Broadcast : 1; /* bit 18 */ - t_u8 WNM_Sleep : 1; /* bit 17 */ - t_u8 TFS : 1; /* bit 16 */ - t_u8 GeospatialLocation : 1; /* bit 15 */ - t_u8 CivicLocation : 1; /* bit 14 */ - t_u8 CollocatedIntf : 1; /* bit 13 */ - t_u8 ProxyARPService : 1; /* bit 12 */ - t_u8 FMS : 1; /* bit 11 */ - t_u8 LocationTracking : 1; /* bit 10 */ - t_u8 MulticastDiagnostics : 1; /* bit 9 */ - t_u8 Diagnostics : 1; /* bit 8 */ - t_u8 Event : 1; /* bit 7 */ - t_u8 SPSMP_Support : 1; /* bit 6 */ - t_u8 Reserved5 : 1; /* bit 5 */ - t_u8 PSMP_Capable : 1; /* bit 4 */ - t_u8 RejectUnadmFrame : 1; /* bit 3 */ - t_u8 ExtChanSwitching : 1; /* bit 2 */ - t_u8 Reserved1 : 1; /* bit 1 */ - t_u8 BSS_CoexistSupport : 1; /* bit 0 */ -} MLAN_PACK_END ExtCap_t, *pExtCap_t; -#else /** Extended Capabilities Data */ typedef struct MLAN_PACK_START _ExtCap_t { /** Extended Capabilities value */ @@ -2085,7 +1983,6 @@ typedef struct MLAN_PACK_START _ExtCap_t { t_u8 rsvdBit86 : 1; /* bit 86 */ t_u8 rsvdBit87 : 1; /* bit 87 */ } MLAN_PACK_END ExtCap_t, *pExtCap_t; -#endif /** ExtCap : TDLS prohibited */ #define IS_EXTCAP_TDLS_PROHIBITED(ext_cap) (ext_cap.TDLSProhibited) @@ -2211,6 +2108,8 @@ typedef struct _tdls_peer_info { t_u8 ht_cap[IEEE_MAX_IE_SIZE]; /** VHT Capabilities IE */ t_u8 vht_cap[IEEE_MAX_IE_SIZE]; + /** HE Capabilities IE */ + t_u8 he_cap[IEEE_MAX_IE_SIZE]; } tdls_peer_info; /** max ralist num */ @@ -2682,6 +2581,8 @@ typedef struct _mlan_sae_password_t { typedef struct _mlan_pmk_t { /** PMK */ t_u8 pmk[MLAN_MAX_KEY_LENGTH]; + t_u8 pmk_r0[MLAN_MAX_KEY_LENGTH]; + t_u8 pmk_r0_name[MLAN_MAX_PMKR0_NAME_LENGTH]; } mlan_pmk_t; /** Embedded supplicant RSN type: No RSN */ @@ -2732,10 +2633,20 @@ typedef struct _mlan_ds_ewpa_mode { t_u32 act_groupcipher; } mlan_ds_esupp_mode, *pmlan_ds_esupp_mode; +/* Security SSID MAX number support by firmware*/ +#define MAX_SEC_SSID_NUM 6 + /** Type definition of mlan_ds_sec_cfg for MLAN_IOCTL_SEC_CFG */ typedef struct _mlan_ds_sec_cfg { /** Sub-command */ t_u32 sub_command; + /** Flag to extend some structures to support multiple values. + ** For example, mlan_ds_passphrase can only contain one value, + ** if need use mlan_ds_passphrase[N], just set this flag and + ** use mlan_ds_passphrase[] instead to avoid modify + ** more already exist code. + */ + t_u8 multi_passphrase; /** Security configuration parameter */ union { /** Authentication mode for MLAN_OID_SEC_CFG_AUTH_MODE */ @@ -2761,6 +2672,7 @@ typedef struct _mlan_ds_sec_cfg { #ifdef UAP_SUPPORT t_u8 sta_mac[MLAN_MAC_ADDR_LENGTH]; #endif + mlan_ds_passphrase roam_passphrase[MAX_SEC_SSID_NUM]; } param; } mlan_ds_sec_cfg, *pmlan_ds_sec_cfg; @@ -3075,6 +2987,8 @@ typedef struct _mlan_ds_hs_cfg { t_u8 ext_gap; /** GPIO wave level for extend hscfg*/ t_u8 gpio_wave; + /** Minimum delay between HsActive and HostWake (in msec) */ + t_u16 min_wake_holdoff; } mlan_ds_hs_cfg, *pmlan_ds_hs_cfg; #define MAX_MGMT_FRAME_FILTER 2 @@ -3922,7 +3836,7 @@ typedef MLAN_PACK_START struct _mlan_ds_11ax_he_capa { /** Type definition of mlan_ds_11ax_he_cfg for MLAN_OID_11AX_HE_CFG */ typedef struct _mlan_ds_11ax_he_cfg { - /** band, BIT0:2.4G, BIT1:5G*/ + /** band, BIT0:2.4G, BIT1:5G BIT2:6G*/ t_u8 band; /** mlan_ds_11ax_he_capa */ mlan_ds_11ax_he_capa he_cap; @@ -4117,12 +4031,19 @@ typedef struct _mlan_ds_subband_set_t { t_u8 max_tx_pwr; } mlan_ds_subband_set_t; +#define NXP_DFS_UNSET 0 +#define NXP_DFS_FCC 1 +#define NXP_DFS_ETSI 2 +#define NXP_DFS_JP 3 +#define NXP_DFS_UNKNOWN 0xFF /** Domain regulatory information */ typedef struct _mlan_ds_11d_domain_info { + /** DFS region code */ + t_u8 dfs_region; /** Country Code */ t_u8 country_code[COUNTRY_CODE_LEN]; /** Band that channels in sub_band belong to */ - t_u8 band; + t_u16 band; /** No. of subband in below */ t_u8 no_of_sub_band; /** Subband data to send/last sent */ @@ -4166,7 +4087,14 @@ enum _mlan_reg_type { MLAN_REG_PSU = 6, MLAN_REG_BCA = 7, #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ - defined(PCIE9097) || defined(USB9097) || defined(SD9097) + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) || \ + defined(SD9177) + MLAN_REG_CIU = 8, +#endif +#if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \ + defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \ + defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) MLAN_REG_MAC2 = 0x81, MLAN_REG_BBP2 = 0x82, MLAN_REG_RF2 = 0x83, @@ -4261,6 +4189,16 @@ typedef struct _mlan_ds_11h_chan_rep_req { t_u8 host_based; } mlan_ds_11h_chan_rep_req; +/** channel dfs state for MLAN_OID_11H_CHAN_DFS_STATE */ +typedef struct _mlan_ds_11h_chan_dfs_state { + /** channel */ + t_u8 channel; + /** is dfs channel */ + t_u8 dfs_required; + /** dfs state */ + dfs_state_t dfs_state; +} mlan_ds_11h_chan_dfs_state; + typedef struct _mlan_ds_11h_dfs_w53_cfg { /** dfs w53 cfg */ t_u8 dfs53cfg; @@ -4282,6 +4220,8 @@ typedef struct _mlan_ds_11h_cfg { mlan_ds_11h_chan_rep_req chan_rpt_req; /** channel switch count for MLAN_OID_11H_CHAN_SWITCH_COUNT*/ t_s8 cs_count; + /** channel dfs state for MLAN_OID_11H_CHAN_DFS_STATE */ + mlan_ds_11h_chan_dfs_state ch_dfs_state; mlan_ds_11h_dfs_w53_cfg dfs_w53_cfg; } param; } mlan_ds_11h_cfg, *pmlan_ds_11h_cfg; @@ -4370,6 +4310,26 @@ enum _mlan_func_cmd { MLAN_FUNC_SHUTDOWN, }; +/** Net monitor filter: management frame */ +#define MLAN_NETMON_MANAGEMENT_FRAME MBIT(0) +/** Net monitor filter: control frame */ +#define MLAN_NETMON_CONTROL_FRAME MBIT(1) +/** Net monitor filter: data frame */ +#define MLAN_NETMON_DATA_FRAME MBIT(2) + +typedef struct _mlan_ds_misc_net_monitor { + /** Enable/disable network monitor */ + t_u32 enable_net_mon; + /** Set net monitor filer flag */ + t_u32 filter_flag; + /** Radio type */ + t_u32 band; + /** Channel */ + t_u32 channel; + /** Secondary channel bandwidth */ + t_u32 chan_bandwidth; +} mlan_ds_misc_net_monitor; + /** Type definition of mlan_ds_misc_tx_datapause * for MLAN_OID_MISC_TX_DATAPAUSE */ @@ -4780,6 +4740,166 @@ typedef struct _mlan_ds_misc_pmfcfg { #define MAX_SSID_NUM 16 #define MAX_AP_LIST 8 +#define RETRY_UNLIMITED_TIME 0xFF + +#define FW_ROAM_ENABLE MBIT(0) +#define FW_ROAM_TRIGGER_COND MBIT(1) +#define FW_ROAM_BSSID MBIT(2) +#define FW_ROAM_SSID MBIT(3) +#define FW_ROAM_RETRY_COUNT MBIT(4) +#define FW_ROAM_RSSI_PARA MBIT(5) +#define FW_ROAM_BAND_RSSI MBIT(6) +#define FW_ROAM_BGSCAN_PARAM MBIT(7) +#define FW_ROAM_EES_PARAM MBIT(8) +#define FW_ROAM_BCN_MISS_THRESHOLD MBIT(9) +#define FW_ROAM_PRE_BCN_MISS_THRESHOLD MBIT(10) +#define FW_ROAM_BLACKLIST MBIT(11) +#define FW_ROAM_REPEAT_CNT MBIT(12) + +/*Roam offload configuration for auto reconnection when suspend and resume*/ +typedef enum _roam_offload_config_mode { + ROAM_OFFLOAD_ENABLE = 1, + ROAM_OFFLOAD_SUSPEND_CFG, + ROAM_OFFLOAD_RESUME_CFG, + ROAM_OFFLOAD_PARAM_CFG, +} roam_offload_config_mode; + +typedef enum _roam_offload_set_mode { + ROAM_OFFLOAD_DISABLE = 0, + ROAM_OFFLOAD_WITH_APLIST, + ROAM_OFFLOAD_WITHOUT_APLIST, + ROAM_OFFLOAD_WITH_BSSID, + ROAM_OFFLOAD_WITH_SSID, + AUTO_RECONNECT, +} roam_offload_set_mode; + +typedef enum _roam_offload_trigger_mode { + NO_TRIGGER = 0x00, + RSSI_LOW_TRIGGER = 0x01, + PRE_BEACON_LOST_TRIGGER = 0x02, + LINK_LOST_TRIGGER = 0x04, + DEAUTH_WITH_EXT_AP_TRIGGER = 0x08, +} roam_offload_trigger_mode; + +/** mlan_ds_misc_ees_cfg structure */ +typedef MLAN_PACK_START struct _mlan_ds_misc_ees_cfg { + /* EES mode*/ + t_u16 ees_mode; + /* EES report condition*/ + t_u16 ees_rpt_condition; + /* High scan period(milliseconds)*/ + t_u16 high_scan_period; + /* High scan count*/ + t_u16 high_scan_count; + /* Middle scan period(milliseconds)*/ + t_u16 mid_scan_period; + /* Middle scan count*/ + t_u16 mid_scan_count; + /* Low scan period(milliseconds)*/ + t_u16 low_scan_period; + /* Low scan count*/ + t_u16 low_scan_count; +} MLAN_PACK_END mlan_ds_misc_ees_cfg; + +/** mlan_ds_misc_bgscan_cfg structure */ +typedef MLAN_PACK_START struct _mlan_ds_misc_bgscan_cfg { + /* BSS Type 0x1-bss independent, 0x2-bss infrastructure, 0x3-bss any*/ + t_u8 bss_type; + /* Number of channels scanned for each scan*/ + t_u8 channels_per_scan; + /* Interval between consective scans*/ + t_u32 scan_interval; + /* Conditons to trigger report to host*/ + t_u32 bg_rpt_condition; +} MLAN_PACK_END mlan_ds_misc_bgscan_cfg; + +/** mlan_ds_misc_band_rssi structure */ +typedef MLAN_PACK_START struct _mlan_ds_misc_band_rssi { + /* RSSI hysteresis*/ + t_u8 rssi_hysteresis; + /* Preferred channel band for fw roaming + * 0:2.4G band; 1: 5G band; 2:4G band; 0xFF:band not set(invalid) + */ + t_u8 band_preferred; +} MLAN_PACK_END mlan_ds_misc_band_rssi; + +/** mlan_ds_misc_ssid_list structure */ +typedef MLAN_PACK_START struct _mlan_ds_misc_ssid_list { + /* SSID number*/ + t_u8 ssid_num; + /* SSID for fw roaming/auto_reconnect*/ + mlan_802_11_ssid ssids[MAX_SSID_NUM]; +} MLAN_PACK_END mlan_ds_misc_ssid_list; + +typedef MLAN_PACK_START struct _mlan_ds_misc_roam_offload_aplist { + /** Number of AP**/ + t_u8 ap_num; + /** AP mac addrs**/ + t_u8 ap_mac[MAX_AP_LIST][MLAN_MAC_ADDR_LENGTH]; +} MLAN_PACK_END mlan_ds_misc_roam_offload_aplist; + +typedef MLAN_PACK_START struct _mlan_ds_misc_roam_offload_para_rssi { + /** Setting flag**/ + t_u8 set_flag; + /** Max value of RSSI threshold**/ + t_u8 max_rssi; + /** Min value of RSSI threshold**/ + t_u8 min_rssi; + /** Adjusting step value of RSSI threshold**/ + t_u8 step_rssi; +} MLAN_PACK_END mlan_ds_misc_roam_offload_para_rssi; + +typedef MLAN_PACK_START struct _mlan_ds_misc_roam_offload { + /** Enable roam offload**/ + t_u8 enable; + /** User set passphrase**/ + t_u8 userset_passphrase; + /* Condition to trigger roaming + * Bit0 : RSSI low trigger + * Bit1 : Pre-beacon lost trigger + * Bit2 : Link Lost trigger + * Bit3 : Deauth by ext-AP trigger + * Bit4 ~ Bit15 : Reserved + * value 0 : no trigger + * value 0xff : invalid + */ + t_u16 trigger_condition; + /** AP list**/ + mlan_ds_misc_roam_offload_aplist aplist; + /*Roam offload configuration mode for auto connection when suspend and + * resume*/ + roam_offload_config_mode config_mode; + /** Retry count**/ + t_u8 retry_count; + /** RSSI para**/ + mlan_ds_misc_roam_offload_para_rssi para_rssi; + /** BSSID of reconnection**/ + mlan_802_11_mac_addr bssid_reconnect; + /* SSID List(White list)*/ + mlan_ds_misc_ssid_list ssid_list; + /* Black list(BSSID list)*/ + mlan_ds_misc_roam_offload_aplist black_list; + /* BAND and RSSI_HYSTERESIS set flag*/ + t_u8 band_rssi_flag; + mlan_ds_misc_band_rssi band_rssi; + + /* BGSCAN params set flag*/ + t_u8 bgscan_set_flag; + mlan_ds_misc_bgscan_cfg bgscan_cfg; + + /* EES mode params set flag*/ + t_u8 ees_param_set_flag; + mlan_ds_misc_ees_cfg ees_cfg; + + /* Beacon miss threshold*/ + t_u8 bcn_miss_threshold; + + /* Beacon miss threshold*/ + t_u8 pre_bcn_miss_threshold; + + /* Scan repeat count*/ + t_u16 repeat_count; +} MLAN_PACK_END mlan_ds_misc_roam_offload; /**Action ID for TDLS disable link*/ #define WLAN_TDLS_DISABLE_LINK 0x00 @@ -4833,6 +4953,8 @@ typedef struct _mlan_ds_misc_tdls_oper { #define TDLS_IE_FLAGS_QOS_INFO 0x0080 /** flag for TDLS SETUP */ #define TDLS_IE_FLAGS_SETUP 0x0100 +#define TDLS_IE_FLAGS_HECAP 0x0200 +#define TDLS_IE_FLAGS_HEOP 0x0400 /** TDLS ie buffer */ typedef struct _mlan_ds_misc_tdls_ies { @@ -4854,6 +4976,10 @@ typedef struct _mlan_ds_misc_tdls_ies { t_u8 vht_oprat[IEEE_MAX_IE_SIZE]; /** aid Info */ t_u8 aid_info[IEEE_MAX_IE_SIZE]; + /** HE Capabilities IE */ + t_u8 he_cap[IEEE_MAX_IE_SIZE]; + /** HE Operation IE */ + t_u8 he_op[IEEE_MAX_IE_SIZE]; /** supported channels */ t_u8 supp_chan[IEEE_MAX_IE_SIZE]; /** supported regulatory class */ @@ -5112,6 +5238,34 @@ typedef struct _mlan_ds_ssu_params { } mlan_ds_ssu_params; #endif +#define CSI_FILTER_MAX 16 +/** Structure of CSI filters */ +typedef MLAN_PACK_START struct _mlan_csi_filter_t { + /** Source address of the packet to receive */ + t_u8 mac_addr[MLAN_MAC_ADDR_LENGTH]; + /** Pakcet type of the interested CSI */ + t_u8 pkt_type; + /* Packet subtype of the interested CSI */ + t_u8 subtype; + /* Other filter flags */ + t_u8 flags; +} MLAN_PACK_END mlan_csi_filter_t; +/** Structure of CSI parameters */ +typedef MLAN_PACK_START struct _mlan_ds_csi_params { + /** CSI enable flag. 1: enable, 0: disable */ + t_u16 csi_enable; + /** Header ID*/ + t_u32 head_id; + /** Tail ID */ + t_u32 tail_id; + /** Number of CSI filters */ + t_u8 csi_filter_cnt; + /** Chip ID */ + t_u8 chip_id; + /** CSI filters */ + mlan_csi_filter_t csi_filter[CSI_FILTER_MAX]; +} MLAN_PACK_END mlan_ds_csi_params; + typedef MLAN_PACK_START struct _mlan_ds_hal_phy_cfg_params { /** 11b pwr spectral density mask enable/disable */ t_u8 dot11b_psd_mask_cfg; @@ -5319,6 +5473,31 @@ typedef struct _mlan_ds_misc_cfp_tbl { chan_freq_power_t cfp_tbl[]; } mlan_ds_misc_cfp_tbl; +/** mlan_ds_mc_aggr_cfg for MLAN_OID_MISC_MC_AGGR_CFG */ +typedef struct _mlan_ds_mc_aggr_cfg { + /** action */ + t_u8 action; + /* 1 enable, 0 disable + * bit 0 MC aggregation + * bit 1 packet expiry + * bit 2 CTS2Self + * bit 3 CTS2Self duration offset*/ + t_u8 enable_bitmap; + /* 1 valid, 0 invalid + * bit 0 MC aggregation + * bit 1 packet expiry + * bit 2 CTS2Self + * bit 3 CTS2Self duration offset*/ + t_u8 mask_bitmap; + /** CTS2Self duration offset */ + t_u16 cts2self_offset; +} mlan_ds_mc_aggr_cfg; +typedef struct _mlan_ds_ch_load { + /** action */ + t_u8 action; + t_u16 ch_load_param; +} mlan_ds_ch_load; + /** Type definition of mlan_ds_misc_cfg for MLAN_IOCTL_MISC_CFG */ typedef struct _mlan_ds_misc_cfg { /** Sub-command */ @@ -5358,6 +5537,8 @@ typedef struct _mlan_ds_misc_cfg { mlan_ds_misc_tdls_ies tdls_ies; /**tdls cs off channel*/ t_u8 tdls_cs_channel; + /** Net monitor for MLAN_OID_MISC_NET_MONITOR */ + mlan_ds_misc_net_monitor net_mon; /** Tx data pause for MLAN_OID_MISC_TX_DATAPAUSE */ mlan_ds_misc_tx_datapause tx_datapause; /** IP address configuration */ @@ -5419,6 +5600,8 @@ typedef struct _mlan_ds_misc_cfg { mlan_ds_misc_gtk_rekey_data gtk_rekey; mlan_ds_bw_chan_oper bw_chan_oper; mlan_ds_ind_rst_cfg ind_rst_cfg; + /** Roam offload */ + mlan_ds_misc_roam_offload roam_offload; t_u64 misc_tsf; mlan_ds_custom_reg_domain custom_reg_domain; mlan_ds_misc_keep_alive keep_alive; @@ -5430,6 +5613,7 @@ typedef struct _mlan_ds_misc_cfg { #if defined(PCIE) mlan_ds_ssu_params ssu_params; #endif + mlan_ds_csi_params csi_params; /** boot sleep enable or disable */ t_u16 boot_sleep; /** Mapping Policy */ @@ -5455,10 +5639,12 @@ typedef struct _mlan_ds_misc_cfg { mlan_ds_misc_dot11mc_unassoc_ftm_cfg dot11mc_unassoc_ftm_cfg; mlan_ds_misc_tp_state tp_state; mlan_ds_hal_phy_cfg_params hal_phy_cfg_params; + mlan_ds_mc_aggr_cfg mc_aggr_cfg; #ifdef UAP_SUPPORT t_u8 wacp_mode; #endif t_u32 ips_ctrl; + mlan_ds_ch_load ch_load; } param; } mlan_ds_misc_cfg, *pmlan_ds_misc_cfg; diff --git a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c index 9a4c614..ac4e38c 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c @@ -3,7 +3,7 @@ * @brief This file contains the functions for CFG80211. * * - * Copyright 2011-2021 NXP + * Copyright 2011-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -127,6 +127,9 @@ static struct ieee80211_channel cfg80211_channels_5ghz[] = { {.center_freq = 5785, .hw_value = 157, .max_power = 20}, {.center_freq = 5805, .hw_value = 161, .max_power = 20}, {.center_freq = 5825, .hw_value = 165, .max_power = 20}, + {.center_freq = 5845, .hw_value = 169, .max_power = 20}, + {.center_freq = 5865, .hw_value = 173, .max_power = 20}, + {.center_freq = 5885, .hw_value = 177, .max_power = 20}, }; struct ieee80211_supported_band cfg80211_band_2ghz = { @@ -145,68 +148,7 @@ struct ieee80211_supported_band cfg80211_band_5ghz = { .n_bitrates = ARRAY_SIZE(cfg80211_rates) - 4, }; -/** Channel definitions for 2 GHz to be advertised to cfg80211 */ -static struct ieee80211_channel macl_cfg80211_channels_2ghz[] = { - {.center_freq = 2412, .hw_value = 1, .max_power = 20}, - {.center_freq = 2417, .hw_value = 2, .max_power = 20}, - {.center_freq = 2422, .hw_value = 3, .max_power = 20}, - {.center_freq = 2427, .hw_value = 4, .max_power = 20}, - {.center_freq = 2432, .hw_value = 5, .max_power = 20}, - {.center_freq = 2437, .hw_value = 6, .max_power = 20}, - {.center_freq = 2442, .hw_value = 7, .max_power = 20}, - {.center_freq = 2447, .hw_value = 8, .max_power = 20}, - {.center_freq = 2452, .hw_value = 9, .max_power = 20}, - {.center_freq = 2457, .hw_value = 10, .max_power = 20}, - {.center_freq = 2462, .hw_value = 11, .max_power = 20}, - {.center_freq = 2467, .hw_value = 12, .max_power = 20}, - {.center_freq = 2472, .hw_value = 13, .max_power = 20}, - {.center_freq = 2484, .hw_value = 14, .max_power = 20}, -}; - -/** Channel definitions for 5 GHz to be advertised to cfg80211 */ -static struct ieee80211_channel mac1_cfg80211_channels_5ghz[] = { - {.center_freq = 5180, .hw_value = 36, .max_power = 20}, - {.center_freq = 5200, .hw_value = 40, .max_power = 20}, - {.center_freq = 5220, .hw_value = 44, .max_power = 20}, - {.center_freq = 5240, .hw_value = 48, .max_power = 20}, - {.center_freq = 5260, .hw_value = 52, .max_power = 20}, - {.center_freq = 5280, .hw_value = 56, .max_power = 20}, - {.center_freq = 5300, .hw_value = 60, .max_power = 20}, - {.center_freq = 5320, .hw_value = 64, .max_power = 20}, - {.center_freq = 5500, .hw_value = 100, .max_power = 20}, - {.center_freq = 5520, .hw_value = 104, .max_power = 20}, - {.center_freq = 5540, .hw_value = 108, .max_power = 20}, - {.center_freq = 5560, .hw_value = 112, .max_power = 20}, - {.center_freq = 5580, .hw_value = 116, .max_power = 20}, - {.center_freq = 5600, .hw_value = 120, .max_power = 20}, - {.center_freq = 5620, .hw_value = 124, .max_power = 20}, - {.center_freq = 5640, .hw_value = 128, .max_power = 20}, - {.center_freq = 5660, .hw_value = 132, .max_power = 20}, - {.center_freq = 5680, .hw_value = 136, .max_power = 20}, - {.center_freq = 5700, .hw_value = 140, .max_power = 20}, - {.center_freq = 5720, .hw_value = 144, .max_power = 20}, - {.center_freq = 5745, .hw_value = 149, .max_power = 20}, - {.center_freq = 5765, .hw_value = 153, .max_power = 20}, - {.center_freq = 5785, .hw_value = 157, .max_power = 20}, - {.center_freq = 5805, .hw_value = 161, .max_power = 20}, - {.center_freq = 5825, .hw_value = 165, .max_power = 20}, -}; - -struct ieee80211_supported_band mac1_cfg80211_band_2ghz = { - .channels = macl_cfg80211_channels_2ghz, - .band = IEEE80211_BAND_2GHZ, - .n_channels = ARRAY_SIZE(macl_cfg80211_channels_2ghz), - .bitrates = cfg80211_rates, - .n_bitrates = ARRAY_SIZE(cfg80211_rates), -}; - -struct ieee80211_supported_band mac1_cfg80211_band_5ghz = { - .channels = mac1_cfg80211_channels_5ghz, - .band = IEEE80211_BAND_5GHZ, - .n_channels = ARRAY_SIZE(mac1_cfg80211_channels_5ghz), - .bitrates = cfg80211_rates + 4, - .n_bitrates = ARRAY_SIZE(cfg80211_rates) - 4, -}; +extern pmoal_handle m_handle[]; #if KERNEL_VERSION(2, 6, 29) < LINUX_VERSION_CODE #ifdef UAP_SUPPORT @@ -1064,6 +1006,11 @@ int woal_cfg80211_change_virtual_intf(struct wiphy *wiphy, ENTER(); + if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_MONITOR) { + ret = -EFAULT; + goto done; + } + if (priv->wdev->iftype == type) { PRINTM(MINFO, "Already set to required type\n"); goto done; @@ -2476,7 +2423,11 @@ static void woal_cancel_chanrpt_event(moal_private *priv) return; } evt->priv = priv; +#ifdef UAP_CFG80211 +#if KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE evt->type = WOAL_EVENT_CANCEL_CHANRPT; +#endif +#endif INIT_LIST_HEAD(&evt->link); spin_lock_irqsave(&handle->evt_lock, flags); list_add_tail(&evt->link, &handle->evt_queue); @@ -2681,9 +2632,12 @@ int woal_cfg80211_mgmt_tx(struct wiphy *wiphy, case IEEE80211_STYPE_DISASSOC: /* Need cancel the CAC when stop hostapd during * CAC*/ +#ifdef UAP_CFG80211 +#if KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE if (priv->phandle->is_cac_timer_set) woal_cancel_chanrpt_event(priv); - +#endif +#endif if (!priv->bss_started) { PRINTM(MCMND, "Drop deauth packet before AP started\n"); @@ -4192,6 +4146,62 @@ done: return ret; } +/** + * @brief Sets up the ieee80211_supported band + * * + * @param ht_info A pointer to ieee80211_sta_ht_cap structure + * @param dev_cap Device capability information + * @param mcs_set Device MCS sets + * + * @return N/A + */ +struct ieee80211_supported_band *woal_setup_wiphy_bands(t_u8 ieee_band) +{ + struct ieee80211_supported_band *band = NULL; + switch (ieee_band) { + case IEEE80211_BAND_5GHZ: + band = kmemdup(&cfg80211_band_5ghz, + sizeof(struct ieee80211_supported_band), + GFP_KERNEL); + if (!band) { + PRINTM(MERROR, "No memory for band\n"); + break; + } + band->channels = + kmemdup(&cfg80211_channels_5ghz, + sizeof(cfg80211_channels_5ghz), GFP_KERNEL); + if (!band->channels) { + PRINTM(MERROR, "No memory for band->channel\n"); + kfree(band); + band = NULL; + break; + } + band->n_channels = ARRAY_SIZE(cfg80211_channels_5ghz); + break; + case IEEE80211_BAND_2GHZ: + default: + band = kmemdup(&cfg80211_band_2ghz, + sizeof(struct ieee80211_supported_band), + GFP_KERNEL); + if (!band) { + PRINTM(MERROR, "No memory for band\n"); + break; + } + band->channels = + kmemdup(&cfg80211_channels_2ghz, + sizeof(cfg80211_channels_2ghz), GFP_KERNEL); + if (!band->channels) { + PRINTM(MERROR, "No memory for band->channel\n"); + kfree(band); + band = NULL; + break; + } + band->n_channels = ARRAY_SIZE(cfg80211_channels_2ghz); + break; + } + return band; +} + /** * @brief Sets up the CFG802.11 specific HT capability fields * with default values @@ -4411,12 +4421,12 @@ Bit75: 0x1 (Rx 1024-QAM Support < 242-tone RU) /** * @brief update 11ax ie for AP mode * - * @param band band config - * @hecap_ie a pointer to mlan_ds_11ax_he_capa + * @param band channel band + * @hecap_ie a pointer to mlan_ds_11ax_he_capa * * @return 0--success, otherwise failure */ -void woal_uap_update_11ax_ie(t_u8 band, mlan_ds_11ax_he_capa *hecap_ie) +static void woal_uap_update_11ax_ie(t_u8 band, mlan_ds_11ax_he_capa *hecap_ie) { if (band == BAND_5GHZ) { hecap_ie->he_mac_cap[0] &= UAP_HE_MAC_CAP0_MASK; @@ -4497,6 +4507,7 @@ void woal_cfg80211_setup_he_cap(moal_private *priv, PRINTM(MERROR, "Fail to allocate iftype data\n"); goto done; } + memset(iftype_data, 0, sizeof(struct ieee80211_sband_iftype_data)); iftype_data->types_mask = MBIT(NL80211_IFTYPE_STATION) | MBIT(NL80211_IFTYPE_AP) | MBIT(NL80211_IFTYPE_P2P_CLIENT) | MBIT(NL80211_IFTYPE_P2P_GO); @@ -4548,6 +4559,8 @@ done: LEAVE(); } +#endif + /** * @brief free iftype_data * @@ -4556,20 +4569,24 @@ done: * * @return N/A */ -void woal_cfg80211_free_iftype_data(struct wiphy *wiphy) +void woal_cfg80211_free_bands(struct wiphy *wiphy) { enum nl80211_band band; for (band = NL80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; ++band) { if (!wiphy->bands[band]) continue; - if (!wiphy->bands[band]->iftype_data) - continue; - kfree(wiphy->bands[band]->iftype_data); - wiphy->bands[band]->n_iftype_data = 0; +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) + if (wiphy->bands[band]->iftype_data) { + kfree(wiphy->bands[band]->iftype_data); + wiphy->bands[band]->n_iftype_data = 0; + } +#endif + kfree(wiphy->bands[band]->channels); + kfree(wiphy->bands[band]); + wiphy->bands[band] = NULL; } } -#endif /* * @brief prepare and send fake deauth packet to cfg80211 to @@ -4881,6 +4898,10 @@ void woal_cfg80211_notify_antcfg(moal_private *priv, struct wiphy *wiphy, (__force __le16)0xfffe; bands->vht_cap.vht_mcs.tx_mcs_map = (__force __le16)0xfffe; + bands->vht_cap.vht_mcs.rx_highest = + (__force __le16)0x186; + bands->vht_cap.vht_mcs.tx_highest = + (__force __le16)0x186; #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) if (bands->n_iftype_data && bands->iftype_data && @@ -4911,6 +4932,10 @@ void woal_cfg80211_notify_antcfg(moal_private *priv, struct wiphy *wiphy, (__force __le16)0xfffa; bands->vht_cap.vht_mcs.tx_mcs_map = (__force __le16)0xfffa; + bands->vht_cap.vht_mcs.rx_highest = + (__force __le16)0x30c; + bands->vht_cap.vht_mcs.tx_highest = + (__force __le16)0x30c; #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) if (bands->n_iftype_data && bands->iftype_data && @@ -5003,3 +5028,169 @@ done: return status; } #endif + +/** + * @brief Set given radar channel dfs_state to AVAILABLE + * + * @param wiphy A pointer to struct wiphy + * + * @return N/A + */ +void woal_clear_wiphy_dfs_state(struct wiphy *wiphy) +{ + struct ieee80211_supported_band *sband; + int i; + + ENTER(); + if (!wiphy) { + LEAVE(); + return; + } + sband = wiphy->bands[NL80211_BAND_5GHZ]; + + if (!sband) { + LEAVE(); + return; + } + + for (i = 0; i < sband->n_channels; i++) { + if (sband->channels[i].flags & IEEE80211_CHAN_RADAR) { +#if CFG80211_VERSION_CODE > KERNEL_VERSION(3, 8, 13) + if (sband->channels[i].dfs_state == + NL80211_DFS_UNAVAILABLE) { + sband->channels[i].dfs_state = + NL80211_DFS_USABLE; + sband->channels[i].dfs_state_entered = jiffies; + } +#endif + } + } + LEAVE(); +} + +/** + * @brief Set given radar channel dfs_state to AVAILABLE + * + * @param wiphy A pointer to struct wiphy + * @param ch_dfs_state A pointer to struct mlan_ds_11h_chan_dfs_state + * + * @return N/A + */ +int woal_get_wiphy_chan_dfs_state(struct wiphy *wiphy, + mlan_ds_11h_chan_dfs_state *ch_dfs_state) +{ + struct ieee80211_supported_band *sband; + int i; + int ret = -1; + t_u8 channel = ch_dfs_state->channel; + + ENTER(); + if (!wiphy) { + LEAVE(); + return ret; + } + sband = wiphy->bands[NL80211_BAND_5GHZ]; + + if (!sband) { + LEAVE(); + return ret; + } + + for (i = 0; i < sband->n_channels; i++) { + if (sband->channels[i].flags & IEEE80211_CHAN_RADAR) { + if (sband->channels[i].hw_value == channel) { +#if CFG80211_VERSION_CODE > KERNEL_VERSION(3, 8, 13) + ch_dfs_state->dfs_state = + sband->channels[i].dfs_state; + ch_dfs_state->dfs_required = MTRUE; + ret = 0; +#endif + break; + } + } + } + LEAVE(); + return ret; +} + +/** + * @brief Set given radar channel dfs_state to AVAILABLE + * + * @param wiphy A pointer to struct wiphy + * @param channel given radar channel + * @param dfs_state dfs_state + * + * @return N/A + */ +static void woal_update_wiphy_chan_dfs_state(struct wiphy *wiphy, t_u8 channel, + t_u8 dfs_state) +{ + struct ieee80211_supported_band *sband; + int i; + + ENTER(); + if (!wiphy) { + LEAVE(); + return; + } + sband = wiphy->bands[NL80211_BAND_5GHZ]; + + if (!sband) { + LEAVE(); + return; + } + + for (i = 0; i < sband->n_channels; i++) { + if (sband->channels[i].flags & IEEE80211_CHAN_RADAR) { + if (sband->channels[i].hw_value == channel) { +#if CFG80211_VERSION_CODE > KERNEL_VERSION(3, 8, 13) + sband->channels[i].dfs_state = dfs_state; + sband->channels[i].dfs_state_entered = jiffies; +#endif + break; + } + } + } +#if CFG80211_VERSION_CODE > KERNEL_VERSION(3, 8, 13) + if (i < sband->n_channels) + PRINTM(MCMND, "ZERODFS: Set channel %d dfs_state: %d\n", + channel, sband->channels[i].dfs_state); +#endif + LEAVE(); +} +/** + * @brief Set given radar channel dfs_state + * + * @param wiphy A pointer to wiphy structure + * @param channel given radar channel + * @param dfs_state dfs_state + * + * @return N/A + */ +static void woal_update_wiphy_channel_dfs_state(struct wiphy *wiphy, + t_u8 channel, t_u8 dfs_state) +{ + if (!wiphy) { + LEAVE(); + return; + } + woal_update_wiphy_chan_dfs_state(wiphy, channel, dfs_state); +} + +/** + * @brief update channel dfs state to all wiphy + * + * @param channel given radar channel + * @param dfs_state dfs_state + * + * @return N/A + */ +void woal_update_channel_dfs_state(t_u8 channel, t_u8 dfs_state) +{ + int index; + for (index = 0; index < MAX_MLAN_ADAPTER; index++) { + if (m_handle[index] && m_handle[index]->wiphy) + woal_update_wiphy_channel_dfs_state( + m_handle[index]->wiphy, channel, dfs_state); + } +} diff --git a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h index e3b9ae3..c181153 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h @@ -3,7 +3,7 @@ * @brief This file contains the CFG80211 specific defines. * * - * Copyright 2011-2021 NXP + * Copyright 2011-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -324,9 +324,7 @@ int woal_cfg80211_del_virtual_intf(struct wiphy *wiphy, int woal_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev); #endif -#if defined(WIFI_DIRECT_SUPPORT) void woal_remove_virtual_interface(moal_handle *handle); -#endif #ifdef WIFI_DIRECT_SUPPORT /* Group Owner Negotiation Req */ @@ -490,9 +488,11 @@ mlan_status woal_chandef_create(moal_private *priv, #if KERNEL_VERSION(4, 20, 0) <= CFG80211_VERSION_CODE void woal_cfg80211_setup_he_cap(moal_private *priv, struct ieee80211_supported_band *band); -void woal_cfg80211_free_iftype_data(struct wiphy *wiphy); #endif +void woal_cfg80211_free_bands(struct wiphy *wiphy); +struct ieee80211_supported_band *woal_setup_wiphy_bands(t_u8 ieee_band); + void woal_clear_all_mgmt_ies(moal_private *priv, t_u8 wait_option); int woal_cfg80211_mgmt_frame_ie( moal_private *priv, const t_u8 *beacon_ies, size_t beacon_ies_len, @@ -512,4 +512,8 @@ void woal_cfg80211_setup_vht_cap(moal_private *priv, int woal_cfg80211_assoc(moal_private *priv, void *sme, t_u8 wait_option, pmlan_ds_misc_assoc_rsp assoc_rsp); +void woal_clear_wiphy_dfs_state(struct wiphy *wiphy); +void woal_update_channel_dfs_state(t_u8 channel, t_u8 dfs_state); +int woal_get_wiphy_chan_dfs_state(struct wiphy *wiphy, + mlan_ds_11h_chan_dfs_state *ch_dfs_state); #endif /* _MOAL_CFG80211_H_ */ diff --git a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.c b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.c index 38b16d9..f2abf69 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.c @@ -3,7 +3,7 @@ * @brief This file contains the functions for CFG80211 vendor. * * - * Copyright 2015-2021 NXP + * Copyright 2015-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -56,6 +56,14 @@ static const struct nl80211_vendor_cmd_info vendor_events[] = { .vendor_id = MRVL_VENDOR_ID, .subcmd = event_rssi_monitor, }, /*event_id 0x1501*/ + { + .vendor_id = MRVL_VENDOR_ID, + .subcmd = event_set_key_mgmt_offload, + }, /*event_id 0x10001*/ + { + .vendor_id = MRVL_VENDOR_ID, + .subcmd = event_fw_roam_success, + }, /*event_id 0x10002*/ { .vendor_id = MRVL_VENDOR_ID, .subcmd = event_cloud_keep_alive, @@ -748,9 +756,11 @@ static int woal_cfg80211_subcmd_get_supp_feature_set(struct wiphy *wiphy, int data_len) { struct sk_buff *skb = NULL; + struct net_device *dev = wdev->netdev; moal_private *priv = (moal_private *)woal_get_netdev_priv(dev); mlan_fw_info fw_info; + t_u32 reply_len = 0; int ret = 0; t_u32 supp_feature_set = 0; @@ -3233,6 +3243,170 @@ done: } #endif +/** + * @brief vendor command to key_mgmt_set_key + * + * @param wiphy A pointer to wiphy struct + * @param wdev A pointer to wireless_dev struct + * @param data a pointer to data + * @param len data length + * + * @return 0: success fail otherwise + */ +static int +woal_cfg80211_subcmd_set_roaming_offload_key(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + moal_private *priv; + struct net_device *dev; + struct sk_buff *skb = NULL; + t_u8 *pos = (t_u8 *)data; + int ret = MLAN_STATUS_SUCCESS; + + ENTER(); + + if (data) + DBG_HEXDUMP(MCMD_D, "Vendor pmk", (t_u8 *)data, data_len); + + if (!wdev || !wdev->netdev) { + LEAVE(); + return -EFAULT; + } + + dev = wdev->netdev; + priv = (moal_private *)woal_get_netdev_priv(dev); + if (!priv || !pos) { + LEAVE(); + return -EFAULT; + } + + if (data_len > MLAN_MAX_KEY_LENGTH) { + moal_memcpy_ext(priv->phandle, &priv->pmk.pmk_r0, pos, + MLAN_MAX_KEY_LENGTH, MLAN_MAX_KEY_LENGTH); + pos += MLAN_MAX_KEY_LENGTH; + moal_memcpy_ext(priv->phandle, &priv->pmk.pmk_r0_name, pos, + data_len - MLAN_MAX_KEY_LENGTH, + MLAN_MAX_PMKR0_NAME_LENGTH); + } else { + moal_memcpy_ext(priv->phandle, &priv->pmk.pmk, data, data_len, + MLAN_MAX_KEY_LENGTH); + } + priv->pmk_saved = MTRUE; + + /** Allocate skb for cmd reply*/ + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, data_len); + if (!skb) { + PRINTM(MERROR, "allocate memory fail for vendor cmd\n"); + LEAVE(); + return -EFAULT; + } + pos = skb_put(skb, data_len); + moal_memcpy_ext(priv->phandle, pos, data, data_len, data_len); + ret = cfg80211_vendor_cmd_reply(skb); + + LEAVE(); + return ret; +} + +/** + * @brief vendor command to supplicant to update AP info + * + * @param priv A pointer to moal_private + * @param data a pointer to data + * @param len data length + * + * @return 0: success 1: fail + */ +int woal_roam_ap_info(moal_private *priv, t_u8 *data, int len) +{ + struct wiphy *wiphy = priv->wdev->wiphy; + struct sk_buff *skb = NULL; + int ret = MLAN_STATUS_SUCCESS; + key_info *pkey = NULL; + apinfo *pinfo = NULL; + apinfo *req_tlv = NULL; + MrvlIEtypesHeader_t *tlv = NULL; + t_u16 tlv_type = 0, tlv_len = 0, tlv_buf_left = 0; + int event_id = 0; + t_u8 authorized = 1; + + ENTER(); + + event_id = woal_get_event_id(event_fw_roam_success); + if (event_max == event_id) { + PRINTM(MERROR, "Not find this event %d\n", event_id); + ret = 1; + LEAVE(); + return ret; + } + /**allocate skb*/ +#if KERNEL_VERSION(4, 1, 0) <= CFG80211_VERSION_CODE + skb = cfg80211_vendor_event_alloc(wiphy, priv->wdev, len + 50, +#else + skb = cfg80211_vendor_event_alloc(wiphy, len + 50, +#endif + event_id, GFP_ATOMIC); + + if (!skb) { + PRINTM(MERROR, "allocate memory fail for vendor event\n"); + ret = 1; + LEAVE(); + return ret; + } + + nla_put(skb, MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID, + MLAN_MAC_ADDR_LENGTH, (t_u8 *)data); + nla_put(skb, MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED, + sizeof(authorized), &authorized); + tlv = (MrvlIEtypesHeader_t *)(data + MLAN_MAC_ADDR_LENGTH); + tlv_buf_left = len - MLAN_MAC_ADDR_LENGTH; + while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t)) { + tlv_type = woal_le16_to_cpu(tlv->type); + tlv_len = woal_le16_to_cpu(tlv->len); + + if (tlv_buf_left < (tlv_len + sizeof(MrvlIEtypesHeader_t))) { + PRINTM(MERROR, + "Error processing firmware roam success TLVs, bytes left < TLV length\n"); + break; + } + + switch (tlv_type) { + case TLV_TYPE_APINFO: + pinfo = (apinfo *)tlv; + nla_put(skb, MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE, + pinfo->header.len, pinfo->rsp_ie); + break; + case TLV_TYPE_ASSOC_REQ_IE: + req_tlv = (apinfo *)tlv; + nla_put(skb, MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE, + req_tlv->header.len, req_tlv->rsp_ie); + break; + case TLV_TYPE_KEYINFO: + pkey = (key_info *)tlv; + nla_put(skb, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR, + MLAN_REPLAY_CTR_LEN, pkey->key.replay_ctr); + nla_put(skb, MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK, + MLAN_KCK_LEN, pkey->key.kck); + nla_put(skb, MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK, + MLAN_KEK_LEN, pkey->key.kek); + break; + default: + break; + } + tlv_buf_left -= tlv_len + sizeof(MrvlIEtypesHeader_t); + tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len + + sizeof(MrvlIEtypesHeader_t)); + } + + /**send event*/ + cfg80211_vendor_event(skb, GFP_ATOMIC); + + LEAVE(); + return ret; +} + /** * @brief vendor command to get fw roaming capability * @@ -3305,6 +3479,11 @@ static int woal_cfg80211_subcmd_fw_roaming_enable(struct wiphy *wiphy, const struct nlattr *iter; int type, rem, err; t_u32 fw_roaming_enable = 0; +#ifdef STA_CFG80211 +#if KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE + t_u8 enable = 0; +#endif +#endif ENTER(); @@ -3335,12 +3514,7 @@ static int woal_cfg80211_subcmd_fw_roaming_enable(struct wiphy *wiphy, PRINTM(MMSG, "FW roaming set enable=%d from wifi hal.\n", fw_roaming_enable); -#if defined(STA_CFG80211) - if (fw_roaming_enable) - priv->roaming_enabled = MTRUE; - else - priv->roaming_enabled = MFALSE; -#endif + ret = woal_enable_fw_roaming(priv, fw_roaming_enable); /* Alloc the SKB for vendor_event */ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(t_u32) + 50); if (unlikely(!skb)) { @@ -3354,6 +3528,14 @@ static int woal_cfg80211_subcmd_fw_roaming_enable(struct wiphy *wiphy, if (unlikely(err)) PRINTM(MERROR, "Vendor Command reply failed ret:%d\n", err); +#ifdef STA_CFG80211 +#if KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE + if (!fw_roaming_enable) + woal_cfg80211_vendor_event(priv, event_set_key_mgmt_offload, + &enable, sizeof(enable)); +#endif +#endif + done: LEAVE(); return ret; @@ -3378,6 +3560,7 @@ static int woal_cfg80211_subcmd_fw_roaming_config(struct wiphy *wiphy, int ret = MLAN_STATUS_SUCCESS; const struct nlattr *iter; int type, rem; + woal_roam_offload_cfg *roam_offload_cfg = NULL; wifi_bssid_params blacklist; wifi_ssid_params whitelist; @@ -3417,7 +3600,60 @@ static int woal_cfg80211_subcmd_fw_roaming_config(struct wiphy *wiphy, } } + if (moal_extflg_isset(priv->phandle, EXT_ROAMOFFLOAD_IN_HS)) { + /*save blacklist and whitelist in driver*/ + priv->phandle->fw_roam_params.black_list.ap_num = + blacklist.num_bssid; + moal_memcpy_ext( + priv->phandle, + (t_u8 *)priv->phandle->fw_roam_params.black_list.ap_mac, + (t_u8 *)blacklist.mac_addr, + sizeof(wifi_bssid_params) - sizeof(blacklist.num_bssid), + sizeof(mlan_ds_misc_roam_offload_aplist) - + sizeof(priv->phandle->fw_roam_params.black_list + .ap_num)); + priv->phandle->fw_roam_params.ssid_list.ssid_num = + whitelist.num_ssid; + moal_memcpy_ext( + priv->phandle, + (t_u8 *)priv->phandle->fw_roam_params.ssid_list.ssids, + (t_u8 *)whitelist.whitelist_ssid, + sizeof(wifi_ssid_params) - sizeof(whitelist.num_ssid), + MAX_SSID_NUM * sizeof(mlan_802_11_ssid)); + } else { + roam_offload_cfg = (woal_roam_offload_cfg *)kmalloc( + sizeof(woal_roam_offload_cfg), GFP_KERNEL); + if (!roam_offload_cfg) { + PRINTM(MERROR, "kmalloc failed!\n"); + ret = -ENOMEM; + goto done; + } + /*download parameters directly to fw*/ + memset((char *)roam_offload_cfg, 0, + sizeof(woal_roam_offload_cfg)); + roam_offload_cfg->black_list.ap_num = blacklist.num_bssid; + moal_memcpy_ext(priv->phandle, + (t_u8 *)&roam_offload_cfg->black_list.ap_mac, + (t_u8 *)blacklist.mac_addr, + sizeof(wifi_bssid_params) - + sizeof(blacklist.num_bssid), + sizeof(mlan_ds_misc_roam_offload_aplist) - + sizeof(priv->phandle->fw_roam_params + .black_list.ap_num)); + roam_offload_cfg->ssid_list.ssid_num = whitelist.num_ssid; + moal_memcpy_ext(priv->phandle, + (t_u8 *)&roam_offload_cfg->ssid_list.ssids, + (t_u8 *)whitelist.whitelist_ssid, + sizeof(wifi_ssid_params) - + sizeof(whitelist.num_ssid), + MAX_SSID_NUM * sizeof(mlan_802_11_ssid)); + woal_config_fw_roaming(priv, ROAM_OFFLOAD_PARAM_CFG, + roam_offload_cfg); + } + done: + if (roam_offload_cfg) + kfree(roam_offload_cfg); LEAVE(); return ret; } @@ -3789,6 +4025,348 @@ static int woal_cfg80211_subcmd_set_dfs_offload(struct wiphy *wiphy, return ret; } +#define CSI_DUMP_FILE_MAX 1200000 + +/** + * @brief vendor command to set CSI params + * + * @param wiphy A pointer to wiphy struct + * @param wdev A pointer to wireless_dev struct + * @param data a pointer to data + * @param len data length + * @param csi_enable enable/disable CSI + * + * @return 0: success -1: fail + */ +static int woal_cfg80211_subcmd_set_csi(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int len, + int csi_enable) +{ + struct net_device *dev = NULL; + moal_private *priv = NULL; + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *cfg = NULL; + struct nlattr *tb_vendor[ATTR_CSI_MAX + 1]; + int ret = 0; + int status = MLAN_STATUS_SUCCESS; + + ENTER(); + + if (!wdev || !wdev->netdev) { + LEAVE(); + return -EFAULT; + } + dev = wdev->netdev; + priv = (moal_private *)woal_get_netdev_priv(dev); + + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (req == NULL) { + PRINTM(MERROR, "Could not allocate mlan ioctl request!\n"); + ret = -EFAULT; + goto done; + } + req->req_id = MLAN_IOCTL_MISC_CFG; + cfg = (mlan_ds_misc_cfg *)req->pbuf; + cfg->sub_command = MLAN_OID_MISC_CSI; + + priv->csi_enable = csi_enable; + if (csi_enable == 1) { + nla_parse(tb_vendor, ATTR_CSI_MAX, (struct nlattr *)data, len, + NULL +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE + , + NULL +#endif + ); + if (!tb_vendor[ATTR_CSI_CONFIG]) { + ret = -EFAULT; + goto done; + } + moal_memcpy_ext(priv->phandle, &cfg->param.csi_params, + (mlan_ds_csi_params *)nla_data( + tb_vendor[ATTR_CSI_CONFIG]), + sizeof(mlan_ds_csi_params), + sizeof(mlan_ds_csi_params)); + moal_memcpy_ext(priv->phandle, &priv->csi_config, + &cfg->param.csi_params, + sizeof(mlan_ds_csi_params), + sizeof(mlan_ds_csi_params)); + if (tb_vendor[ATTR_CSI_DUMP_FORMAT]) + priv->csi_dump_format = + nla_get_u8(tb_vendor[ATTR_CSI_DUMP_FORMAT]); + } else if (csi_enable == 0) { + nla_parse(tb_vendor, ATTR_CSI_MAX, (struct nlattr *)data, len, + NULL +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE + , + NULL +#endif + ); + if (!tb_vendor[ATTR_PEER_MAC_ADDR]) { + ret = -EFAULT; + goto done; + } + memset(&cfg->param.csi_params, 0, sizeof(mlan_ds_csi_params)); + moal_memcpy_ext(priv->phandle, + cfg->param.csi_params.csi_filter[0].mac_addr, + (t_u8 *)nla_data(tb_vendor[ATTR_PEER_MAC_ADDR]), + MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH); + } + + status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } + +done: + if (status != MLAN_STATUS_PENDING) + kfree(req); + LEAVE(); + return ret; +} + +/** + * @brief vendor command to enable CSI + * + * @param wiphy A pointer to wiphy struct + * @param wdev A pointer to wireless_dev struct + * @param data a pointer to data + * @param len data length + * + * @return 0: success -1: fail + */ +static int woal_cfg80211_subcmd_csi_enable(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int len) +{ + int ret = 0; + + ENTER(); + + ret = woal_cfg80211_subcmd_set_csi(wiphy, wdev, data, len, 1); + + LEAVE(); + return ret; +} + +/** + * @brief vendor command to disable CSI + * + * @param wiphy A pointer to wiphy struct + * @param wdev A pointer to wireless_dev struct + * @param data a pointer to data + * @param len data length + * + * @return 0: success -1: fail + */ +static int woal_cfg80211_subcmd_csi_disable(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int len) +{ + int ret = 0; + + ENTER(); + + ret = woal_cfg80211_subcmd_set_csi(wiphy, wdev, data, len, 0); + + LEAVE(); + return ret; +} + +/** + * @brief vendor command to get CSI dump path + * + * @param wiphy A pointer to wiphy struct + * @param wdev A pointer to wireless_dev struct + * @param data a pointer to data + * @param len data length + * + * @return 0: success -1: fail + */ +static int woal_cfg80211_subcmd_get_csi_dump_path(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int len) +{ + int ret = 0; + struct net_device *dev = NULL; + moal_private *priv = NULL; + struct sk_buff *skb = NULL; + + ENTER(); + + if (!wdev || !wdev->netdev) { + LEAVE(); + return -EFAULT; + } + dev = wdev->netdev; + priv = (moal_private *)woal_get_netdev_priv(dev); + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + sizeof(priv->csi_dump_path)); + if (unlikely(!skb)) { + PRINTM(MERROR, "skb alloc failed\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + /* Push the data to the skb */ + nla_put(skb, ATTR_CSI_DUMP_PATH, sizeof(priv->csi_dump_path), + (t_u8 *)priv->csi_dump_path); + + ret = cfg80211_vendor_cmd_reply(skb); + if (unlikely(ret)) { + PRINTM(MERROR, "Vendor Command reply failed ret:%d\n", ret); + goto done; + } + +done: + LEAVE(); + return ret; +} + +/** + * @brief vendor command to get CSI config + * + * @param wiphy A pointer to wiphy struct + * @param wdev A pointer to wireless_dev struct + * @param data a pointer to data + * @param len data length + * + * @return 0: success -1: fail + */ +static int woal_cfg80211_subcmd_get_csi_config(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int len) +{ + int ret = 0; + struct net_device *dev = NULL; + moal_private *priv = NULL; + struct sk_buff *skb = NULL; + + ENTER(); + + if (!wdev || !wdev->netdev) { + LEAVE(); + return -EFAULT; + } + dev = wdev->netdev; + priv = (moal_private *)woal_get_netdev_priv(dev); + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + sizeof(priv->csi_config)); + if (unlikely(!skb)) { + PRINTM(MERROR, "skb alloc failed\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + /* Push the data to the skb */ + nla_put(skb, ATTR_CSI_CONFIG, sizeof(mlan_ds_csi_params), + (t_u8 *)&priv->csi_config); + + ret = cfg80211_vendor_cmd_reply(skb); + if (unlikely(ret)) { + PRINTM(MERROR, "Vendor Command reply failed ret:%d\n", ret); + goto done; + } + +done: + LEAVE(); + return ret; +} + +/** + * @brief vendor command to get CSI capability + * + * @param wiphy A pointer to wiphy struct + * @param wdev A pointer to wireless_dev struct + * @param data a pointer to data + * @param len data length + * + * @return 0: success -1: fail + */ +static int woal_cfg80211_subcmd_get_csi_capa(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int len) +{ + ENTER(); + LEAVE(); + return 0; +} + +/** + * @brief Save CSI dump to file + * + * @param dir_name Directory name + * @param file_name File name + * @param buf Pointer to dump buffer + * @param buf_len Length of buf + * @param name Full path name of CSI dump + * + * @return 0: success -1: fail + */ +static mlan_status woal_save_csi_dump_to_file(char *dir_name, char *file_name, + t_u8 *buf, int buf_len, + t_u8 format, char *name) +{ + mlan_status ret = MLAN_STATUS_SUCCESS; + ENTER(); + + if (!dir_name || !file_name || !buf) { + PRINTM(MERROR, "Can't save dump info to file\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } +done: + LEAVE(); + return ret; +} + +/** + * @brief vendor event to upload csi dump + * + * @param priv A pointer to moal_private + * @param data a pointer to data + * @param len data length + * + * @return mlan_status + */ +mlan_status woal_cfg80211_event_csi_dump(moal_private *priv, t_u8 *data, + int len) +{ + mlan_status ret = MLAN_STATUS_SUCCESS; + char path_name[20]; + char file_name[20]; + + ENTER(); + + DBG_HEXDUMP(MCMD_D, "CSI dump data", data, len); + sprintf(path_name, "/data"); + if (priv->csi_dump_format == 1) + sprintf(file_name, "csi_dump.bin"); + else + sprintf(file_name, "csi_dump.txt"); + priv->csi_dump_len += len; + if (priv->csi_dump_len > CSI_DUMP_FILE_MAX) { + PRINTM(MERROR, + "Reached file maximum size. Not saving CSI records.\n"); + goto done; + } + /* Save CSI dump to file */ + ret = woal_save_csi_dump_to_file(path_name, file_name, data, len, + priv->csi_dump_format, + priv->csi_dump_path); + if (ret != MLAN_STATUS_SUCCESS) { + PRINTM(MERROR, "Failed to save CSI dump to file\n"); + goto done; + } + +done: + LEAVE(); + return ret; +} + // clang-format off static const struct wiphy_vendor_command vendor_commands[] = { { @@ -3882,6 +4460,18 @@ static const struct wiphy_vendor_command vendor_commands[] = { #endif }, #endif + { + .info = { + .vendor_id = MRVL_VENDOR_ID, + .subcmd = sub_cmd_set_roaming_offload_key, + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = woal_cfg80211_subcmd_set_roaming_offload_key, +#if KERNEL_VERSION(5, 3, 0) <= CFG80211_VERSION_CODE + .policy = VENDOR_CMD_RAW_DATA, +#endif + }, { .info = { .vendor_id = MRVL_VENDOR_ID, @@ -4140,6 +4730,66 @@ static const struct wiphy_vendor_command vendor_commands[] = { .doit = woal_cfg80211_subcmd_get_packet_filter_capability, #if KERNEL_VERSION(5, 3, 0) <= CFG80211_VERSION_CODE .policy = VENDOR_CMD_RAW_DATA, +#endif + }, + { + .info = { + .vendor_id = MRVL_VENDOR_ID, + .subcmd = subcmd_cfr_request, + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = woal_cfg80211_subcmd_csi_enable, +#if KERNEL_VERSION(5, 3, 0) <= CFG80211_VERSION_CODE + .policy = VENDOR_CMD_RAW_DATA, +#endif + }, + { + .info = { + .vendor_id = MRVL_VENDOR_ID, + .subcmd = subcmd_cfr_cancel, + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = woal_cfg80211_subcmd_csi_disable, +#if KERNEL_VERSION(5, 3, 0) <= CFG80211_VERSION_CODE + .policy = VENDOR_CMD_RAW_DATA, +#endif + }, + { + .info = { + .vendor_id = MRVL_VENDOR_ID, + .subcmd = subcmd_get_csi_dump_path, + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = woal_cfg80211_subcmd_get_csi_dump_path, +#if KERNEL_VERSION(5, 3, 0) <= CFG80211_VERSION_CODE + .policy = VENDOR_CMD_RAW_DATA, +#endif + }, + { + .info = { + .vendor_id = MRVL_VENDOR_ID, + .subcmd = subcmd_get_csi_config, + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = woal_cfg80211_subcmd_get_csi_config, +#if KERNEL_VERSION(5, 3, 0) <= CFG80211_VERSION_CODE + .policy = VENDOR_CMD_RAW_DATA, +#endif + }, + { + .info = { + .vendor_id = MRVL_VENDOR_ID, + .subcmd = subcmd_get_csi_capa, + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = woal_cfg80211_subcmd_get_csi_capa, +#if KERNEL_VERSION(5, 3, 0) <= CFG80211_VERSION_CODE + .policy = VENDOR_CMD_RAW_DATA, #endif }, }; diff --git a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.h b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.h index 95781f0..07ed1f7 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.h @@ -3,7 +3,7 @@ * @brief This file contains the CFG80211 vendor specific defines. * * - * Copyright 2015-2020 NXP + * Copyright 2015-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -25,6 +25,26 @@ #include "moal_main.h" +#define TLV_TYPE_APINFO (PROPRIETARY_TLV_BASE_ID + 249) +#define TLV_TYPE_KEYINFO (PROPRIETARY_TLV_BASE_ID + 250) +#define TLV_TYPE_ASSOC_REQ_IE (PROPRIETARY_TLV_BASE_ID + 292) + +/** Key Info structure */ +typedef struct _key_info_tlv { + /** Header */ + MrvlIEtypesHeader_t header; + /** kck, kek, key_replay*/ + mlan_ds_misc_gtk_rekey_data key; +} key_info; + +/** APinfo TLV structure */ +typedef struct _apinfo_tlv { + /** Header */ + MrvlIEtypesHeader_t header; + /** Assoc response buffer */ + t_u8 rsp_ie[1]; +} apinfo; + #if KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE #define RING_NAME_MAX 32 typedef int wifi_ring_buffer_id; @@ -605,6 +625,8 @@ enum vendor_event { event_hang = 0, event_fw_dump_done = 1, event_rssi_monitor = 0x1501, + event_set_key_mgmt_offload = 0x10001, + event_fw_roam_success = 0x10002, event_cloud_keep_alive = 0x10003, event_dfs_radar_detected = 0x10004, event_dfs_cac_started = 0x10005, @@ -667,6 +689,7 @@ void woal_cfg80211_rssi_monitor_event(moal_private *priv, t_s16 rssi); /**vendor sub command*/ enum vendor_sub_command { sub_cmd_set_drvdbg = 0, + sub_cmd_set_roaming_offload_key = 0x0002, sub_cmd_start_keep_alive = 0x0003, sub_cmd_stop_keep_alive = 0x0004, sub_cmd_dfs_capability = 0x0005, @@ -694,6 +717,11 @@ enum vendor_sub_command { sub_cmd_get_roaming_capability = 0x1700, sub_cmd_fw_roaming_enable = 0x1701, sub_cmd_fw_roaming_config = 0x1702, + subcmd_cfr_request = 0x1900, + subcmd_cfr_cancel, + subcmd_get_csi_dump_path, + subcmd_get_csi_config, + subcmd_get_csi_capa, sub_cmd_max, }; @@ -733,6 +761,25 @@ enum mkeep_alive_attributes { MKEEP_ALIVE_ATTRIBUTE_MAX = MKEEP_ALIVE_ATTRIBUTE_AFTER_LAST - 1 }; +int woal_roam_ap_info(moal_private *priv, t_u8 *data, int len); + +/*Attribute for wpa_supplicant*/ +enum mrvl_wlan_vendor_attr_roam_auth { + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_INVALID = 0, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS, + /* keep last */ + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_AFTER_LAST, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX = + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_AFTER_LAST - 1 +}; + /** WiFi roaming capabilities structure */ typedef struct { /** max blacklist size */ @@ -778,5 +825,28 @@ enum mrvl_wlan_vendor_attr_fw_roaming { MRVL_WLAN_VENDOR_ATTR_FW_ROAMING_AFTER_LAST - 1 }; +enum attr_csi { + ATTR_CSI_INVALID = 0, + ATTR_CSI_CONFIG, + ATTR_PEER_MAC_ADDR, + ATTR_CSI_DUMP_PATH, + ATTR_CSI_CAPA, + ATTR_CSI_DUMP_FORMAT, + ATTR_CSI_AFTER_LAST, + ATTR_CSI_MAX = ATTR_CSI_AFTER_LAST - 1, +}; + +/** CSI capability structure */ +typedef struct { + /**Bit mask indicates what BW is supported */ + t_u8 bw_support; + /** Bit mask indicates what capturing method is supported */ + t_u8 method_support; + /** Max number of capture peers supported */ + t_u8 max_peer; +} wifi_csi_capabilities; + +mlan_status woal_cfg80211_event_csi_dump(moal_private *priv, t_u8 *data, + int len); #endif #endif /* _MOAL_CFGVENDOR_H_ */ diff --git a/mxm_wifiex/wlan_src/mlinux/moal_debug.c b/mxm_wifiex/wlan_src/mlinux/moal_debug.c index 6da6f99..dbbc0c9 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_debug.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_debug.c @@ -3,7 +3,7 @@ * @brief This file contains functions for debug proc file. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c b/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c index 553e738..bda779b 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c @@ -4,7 +4,7 @@ * @brief This file contains private ioctl functions * - * Copyright 2014-2021 NXP + * Copyright 2014-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -94,7 +94,7 @@ static t_u16 SupportedInfraBand[] = { }; /** Bands supported in Ad-Hoc mode */ -static t_u8 SupportedAdhocBand[] = { +static t_u16 SupportedAdhocBand[] = { BAND_B, BAND_B | BAND_G, BAND_G, @@ -1344,9 +1344,8 @@ done: * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING -- success, * otherwise fail */ -static mlan_status -woal_ioctl_aggr_prio_tbl(moal_private *priv, t_u32 action, - mlan_ds_11n_aggr_prio_tbl *aggr_prio_tbl) +mlan_status woal_ioctl_aggr_prio_tbl(moal_private *priv, t_u32 action, + mlan_ds_11n_aggr_prio_tbl *aggr_prio_tbl) { mlan_ioctl_req *req = NULL; mlan_ds_11n_cfg *cfg_11n = NULL; @@ -2976,25 +2975,33 @@ error: static int woal_priv_setuserscan(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen) { - wlan_user_scan_cfg scan_cfg; + wlan_user_scan_cfg *scan_cfg; int ret = 0; ENTER(); + scan_cfg = (wlan_user_scan_cfg *)kmalloc(sizeof(wlan_user_scan_cfg), + GFP_KERNEL); + if (!scan_cfg) { + PRINTM(MERROR, "Malloc buffer failed\n"); + LEAVE(); + return -ENOMEM; + } + /* Create the scan_cfg structure */ - memset(&scan_cfg, 0, sizeof(scan_cfg)); + memset(scan_cfg, 0, sizeof(wlan_user_scan_cfg)); /* We expect the scan_cfg structure to be passed in respbuf */ - moal_memcpy_ext(priv->phandle, (char *)&scan_cfg, + moal_memcpy_ext(priv->phandle, (char *)scan_cfg, respbuf + strlen(CMD_NXP) + strlen(PRIV_CMD_SETUSERSCAN), sizeof(wlan_user_scan_cfg), sizeof(wlan_user_scan_cfg)); - moal_memcpy_ext(priv->phandle, scan_cfg.random_mac, priv->random_mac, + moal_memcpy_ext(priv->phandle, scan_cfg->random_mac, priv->random_mac, ETH_ALEN, MLAN_MAC_ADDR_LENGTH); /* Call for scan */ - if (MLAN_STATUS_FAILURE == woal_do_scan(priv, &scan_cfg)) + if (MLAN_STATUS_FAILURE == woal_do_scan(priv, scan_cfg)) ret = -EFAULT; - + kfree(scan_cfg); LEAVE(); return ret; } @@ -4233,6 +4240,7 @@ done: #define PARAMETER_GPIO_INDICATION 1 #define PARAMETER_EXTEND_HSCFG 2 #define PARAMETER_HS_WAKEUP_INTERVAL 3 +#define PARAMETER_MIN_WAKE_HOLDOFF 4 /** * @brief Set/Get Host Sleep configuration * @@ -4246,7 +4254,7 @@ done: static int woal_priv_hscfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen, BOOLEAN invoke_hostcmd) { - int data[13] = {0}; + int data[15] = {0}; int *temp_data, type; int user_data_len = 0; int ret = 0; @@ -4296,7 +4304,7 @@ static int woal_priv_hscfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen, if (user_data_len == 0) { action = MLAN_ACT_GET; } else { - if (user_data_len >= 1 && user_data_len <= 13) { + if (user_data_len >= 1 && user_data_len <= 15) { action = MLAN_ACT_SET; } else { PRINTM(MERROR, "Invalid arguments\n"); @@ -4402,6 +4410,18 @@ static int woal_priv_hscfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen, user_data_len = user_data_len - 2; temp_data++; break; + case PARAMETER_MIN_WAKE_HOLDOFF: + if (user_data_len >= 2) + hscfg.min_wake_holdoff = *(++temp_data); + else { + PRINTM(MERROR, + "Invaild number of parameters\n"); + ret = -EINVAL; + goto done; + } + user_data_len = user_data_len - 2; + temp_data++; + break; default: PRINTM(MERROR, "Unsupported type\n"); ret = -EINVAL; @@ -4450,7 +4470,7 @@ done: static int woal_priv_hssetpara(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen) { - int data[13] = {0}; + int data[15] = {0}; int user_data_len = 0; int ret = 0; @@ -4474,7 +4494,7 @@ static int woal_priv_hssetpara(moal_private *priv, t_u8 *respbuf, return -EINVAL; } - if (user_data_len >= 1 && user_data_len <= 13) { + if (user_data_len >= 1 && user_data_len <= 15) { sprintf(respbuf, "%s%s%s", CMD_NXP, PRIV_CMD_HSCFG, respbuf + (strlen(CMD_NXP) + strlen(PRIV_CMD_HSSETPARA))); @@ -6684,7 +6704,7 @@ static int woal_priv_deauth_ctrl(moal_private *priv, t_u8 *respbuf, req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_snmp_mib)); if (req == NULL) { - ret = ENOMEM; + ret = -ENOMEM; goto done; } @@ -6764,7 +6784,7 @@ static int woal_priv_per_pkt_cfg(moal_private *priv, t_u8 *respbuf, req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); if (req == NULL) { - ret = ENOMEM; + ret = -ENOMEM; goto done; } @@ -7026,7 +7046,7 @@ static int woal_priv_getcfgchanlist(moal_private *priv, t_u8 *respbuf, sband->channels[i].flags; plist->chan_list[i + num_chan].max_power = sband->channels[i].max_power; -#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 8, 13) +#if CFG80211_VERSION_CODE > KERNEL_VERSION(3, 8, 13) plist->chan_list[i + num_chan].dfs_state = sband->channels[i].dfs_state; #endif @@ -8178,7 +8198,7 @@ static int woal_priv_get_driver_verext(moal_private *priv, t_u8 *respbuf, req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info)); if (req == NULL) { - ret = ENOMEM; + ret = -ENOMEM; goto done; } @@ -8366,7 +8386,7 @@ static int woal_priv_wmm_cfg(moal_private *priv, t_u8 *respbuf, req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg)); if (req == NULL) { - ret = ENOMEM; + ret = -ENOMEM; goto done; } @@ -8441,7 +8461,7 @@ static int woal_priv_min_ba_threshold_cfg(moal_private *priv, t_u8 *respbuf, req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg)); if (req == NULL) { - ret = ENOMEM; + ret = -ENOMEM; goto done; } cfg_11n = (mlan_ds_11n_cfg *)req->pbuf; @@ -8515,7 +8535,7 @@ static int woal_priv_11d_cfg(moal_private *priv, t_u8 *respbuf, req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11d_cfg)); if (req == NULL) { - ret = ENOMEM; + ret = -ENOMEM; goto done; } @@ -8588,7 +8608,7 @@ static int woal_priv_11d_clr_chan_tbl(moal_private *priv, t_u8 *respbuf, req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11d_cfg)); if (req == NULL) { - ret = ENOMEM; + ret = -ENOMEM; goto done; } @@ -8642,7 +8662,7 @@ static int woal_priv_wws_cfg(moal_private *priv, t_u8 *respbuf, req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); if (req == NULL) { - ret = ENOMEM; + ret = -ENOMEM; goto done; } @@ -8775,7 +8795,7 @@ static int woal_priv_txbuf_cfg(moal_private *priv, t_u8 *respbuf, req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg)); if (req == NULL) { - ret = ENOMEM; + ret = -ENOMEM; goto done; } @@ -8901,7 +8921,7 @@ static int woal_priv_11h_local_pwr_constraint(moal_private *priv, t_u8 *respbuf, req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11h_cfg)); if (req == NULL) { - ret = ENOMEM; + ret = -ENOMEM; goto done; } @@ -8971,7 +8991,7 @@ static int woal_priv_ht_stream_cfg(moal_private *priv, t_u8 *respbuf, req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg)); if (req == NULL) { - ret = ENOMEM; + ret = -ENOMEM; goto done; } @@ -9044,7 +9064,7 @@ static int woal_priv_mimo_switch(moal_private *priv, t_u8 *respbuf, req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_radio_cfg)); if (req == NULL) { - ret = ENOMEM; + ret = -ENOMEM; goto done; } @@ -9105,7 +9125,7 @@ static int woal_priv_thermal(moal_private *priv, t_u8 *respbuf, req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); if (req == NULL) { - ret = ENOMEM; + ret = -ENOMEM; goto done; } @@ -9163,7 +9183,7 @@ static int woal_priv_beacon_interval(moal_private *priv, t_u8 *respbuf, req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss)); if (req == NULL) { - ret = ENOMEM; + ret = -ENOMEM; goto done; } @@ -10372,6 +10392,282 @@ done: return ret; } +#ifdef UAP_SUPPORT +/** + * @brief Set/Get network monitor configurations + * + * @param priv Pointer to moal_private structure + * @param respbuf Pointer to response buffer + * @param resplen Response buffer length + * + * @return Number of bytes written, negative for failure. + */ +static int woal_priv_net_monitor_ioctl(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + int user_data_len = 0, header_len = 0; + int data_length = 0; + int data[5] = {0}; + int ret = 0; + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *misc = NULL; + mlan_ds_misc_net_monitor *net_mon = NULL; + mlan_status status = MLAN_STATUS_SUCCESS; +#if defined(STA_CFG80211) || defined(UAP_CFG80211) + moal_handle *handle = priv->phandle; + monitor_iface *mon_if = NULL; + struct net_device *ndev = NULL; +#endif + + ENTER(); + + header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_NET_MON); + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (req == NULL) { + LEAVE(); + return -ENOMEM; + } + misc = (mlan_ds_misc_cfg *)req->pbuf; + net_mon = (mlan_ds_misc_net_monitor *)&misc->param.net_mon; + misc->sub_command = MLAN_OID_MISC_NET_MONITOR; + req->req_id = MLAN_IOCTL_MISC_CFG; + if ((int)strlen(respbuf) == header_len) { + /* GET operation */ + user_data_len = 0; + req->action = MLAN_ACT_GET; + } else { + /* SET operation */ + parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data), + &user_data_len); + if (user_data_len == 1 || user_data_len == 4 || + user_data_len == 5) { + if (data[0] != MFALSE && + data[0] != CHANNEL_SPEC_SNIFFER_MODE) { + PRINTM(MERROR, + "NET_MON: Activity should be enable(=1/2)/disable(=0)\n"); + ret = -EINVAL; + goto done; + } + if ((data[0] == MFALSE && user_data_len != 1) || + (data[0] == CHANNEL_SPEC_SNIFFER_MODE && + (user_data_len != 4 && user_data_len != 5))) { + PRINTM(MERROR, + "NET_MON: Sniffer activity not match with user_data_len\n"); + ret = -EINVAL; + goto done; + } + net_mon->enable_net_mon = data[0]; + if (data[0] == CHANNEL_SPEC_SNIFFER_MODE) { + int i; + if (user_data_len != 4 && user_data_len != 5) { + PRINTM(MERROR, + "NET_MON: Invalid number of args!\n"); + ret = -EINVAL; + goto done; + } + /* Supported filter flags */ + if (!data[1] || + data[1] & ~(MLAN_NETMON_DATA_FRAME | + MLAN_NETMON_MANAGEMENT_FRAME | + MLAN_NETMON_CONTROL_FRAME)) { + PRINTM(MERROR, + "NET_MON: Invalid filter flag\n"); + ret = -EINVAL; + goto done; + } + + if (user_data_len > 2) { + /* Supported bands */ + + for (i = 0; + i < + (int)(sizeof(SupportedInfraBand) / + sizeof(SupportedInfraBand[0])); + i++) + if (data[2] == + SupportedInfraBand[i]) + break; + if (i == sizeof(SupportedInfraBand)) { + PRINTM(MERROR, + "NET_MON: Invalid band\n"); + ret = -EINVAL; + goto done; + } + } + /* Supported channel */ + if (user_data_len > 3 && + (data[3] < 1 || + data[3] > MLAN_MAX_CHANNEL)) { + PRINTM(MERROR, + "NET_MON: Invalid channel number\n"); + ret = -EINVAL; + goto done; + } + if (user_data_len == 5) { + /* Secondary channel offset */ + if (!(data[2] & (BAND_GN | BAND_AN))) { + PRINTM(MERROR, + "No 11n in band, can not set " + "secondary channel offset\n"); + ret = -EINVAL; + goto done; + } + if ((data[4] != CHANNEL_BW_20MHZ) && + (data[4] != + CHANNEL_BW_40MHZ_ABOVE) && + (data[4] != + CHANNEL_BW_40MHZ_BELOW) && + (data[4] != CHANNEL_BW_80MHZ)) { + PRINTM(MERROR, + "Invalid secondary channel bandwidth, " + "only allowed 0, 1, 3 or 4\n"); + ret = -EINVAL; + goto done; + } + net_mon->chan_bandwidth = data[4]; + } + + net_mon->filter_flag = data[1]; + net_mon->band = data[2]; + net_mon->channel = data[3]; + } + req->action = MLAN_ACT_SET; + } else { + PRINTM(MERROR, "NET_MON: Invalid number of args!\n"); + ret = -EINVAL; + goto done; + } + } + + status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + PRINTM(MERROR, "NET_MON: woal_request_ioctl fail\n"); + ret = -EFAULT; + goto done; + } + +#if defined(STA_CFG80211) || defined(UAP_CFG80211) + if (req->action == MLAN_ACT_SET) { + if (data[0]) { /** Enable sniffer mode: 1/2 */ + if (!handle->mon_if) { + mon_if = woal_prepare_mon_if(priv, "rtap", 0, + data[0]); + if (!mon_if) { + PRINTM(MFATAL, + "Prepare mon_if fail.\n"); + ret = -EFAULT; + goto done; + } + ndev = mon_if->mon_ndev; + ret = register_netdevice(ndev); + if (ret) { + PRINTM(MFATAL, + "register net_device failed, ret=%d\n", + ret); + free_netdev(ndev); + ret = -EFAULT; + goto done; + } + handle->mon_if = mon_if; + } + /* Save band channel config */ + handle->mon_if->band_chan_cfg.band = net_mon->band; + handle->mon_if->band_chan_cfg.channel = + net_mon->channel; + handle->mon_if->band_chan_cfg.chan_bandwidth = + net_mon->chan_bandwidth; + } else { /** Disable sniffer mode: 0 */ + if (handle->mon_if) { + ndev = handle->mon_if->mon_ndev; + handle->mon_if = NULL; + unregister_netdevice(ndev); + } + } + } +#endif + + data[0] = net_mon->enable_net_mon; + data[1] = net_mon->filter_flag; + data[2] = net_mon->band; + data[3] = net_mon->channel; + data[4] = net_mon->chan_bandwidth; + data_length = 5; + moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data, + sizeof(int) * data_length, respbuflen); + ret = sizeof(int) * data_length; + +done: + if (status != MLAN_STATUS_PENDING) + kfree(req); + + LEAVE(); + return ret; +} +#endif + +#if defined(STA_CFG80211) && defined(UAP_CFG80211) +/** + * @brief Set/Get monitor mode + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return 0 --success, otherwise fail + */ +static int woal_priv_set_get_monitor_mode(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + int ret = 0; + int data = 0; + int user_data_len = 0, header_len = 0; + t_u32 action = MLAN_ACT_GET; + + ENTER(); + + header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_MONITOR_MODE); + + if ((int)strlen(respbuf) == header_len) { + /* GET operation */ + user_data_len = 0; + action = MLAN_ACT_GET; + } else { + /* SET operation */ + parse_arguments(respbuf + header_len, &data, + sizeof(data) / sizeof(int), &user_data_len); + action = MLAN_ACT_SET; + } + + if (sizeof(int) * user_data_len > sizeof(data)) { + PRINTM(MERROR, "Too many arguments\n"); + ret = -EINVAL; + goto done; + } + + if (action == MLAN_ACT_SET) { + if (data == 1) { + priv->phandle->wiphy->interface_modes |= + MBIT(NL80211_IFTYPE_MONITOR); + } else if (data == 0) { + priv->phandle->wiphy->interface_modes &= + ~(MBIT(NL80211_IFTYPE_MONITOR)); + } else { + PRINTM(MERROR, "Invalid input arguments\n"); + ret = -EINVAL; + goto done; + } + } + data = !!(priv->phandle->wiphy->interface_modes & + MBIT(NL80211_IFTYPE_MONITOR)); + + ret = sprintf(respbuf, "Monitor mode: %d\n", data) + 1; + +done: + LEAVE(); + return ret; +} +#endif + /** * @brief clear NOP list * @@ -10424,15 +10720,70 @@ static int woal_priv_clear_nop(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen) { int ret = 0; +#if defined(STA_CFG80211) || defined(UAP_CFG80211) + struct wiphy *wiphy = priv->phandle->wiphy; +#endif ENTER(); PRINTM(MCMND, "clear nop\n"); ret = woal_uap_clear_nop(priv); +#if defined(STA_CFG80211) || defined(UAP_CFG80211) + if (IS_STA_OR_UAP_CFG80211(priv->phandle->params.cfg80211_wext)) { + if (wiphy) + woal_clear_wiphy_dfs_state(wiphy); + } +#endif ret = sizeof(int); LEAVE(); return ret; } +/** + * @brief This function detects fake RADAR. + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return positive for success, negative for failure. + */ +static int woal_priv_fake_radar(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + mlan_ioctl_req *ioctl_req = NULL; + mlan_ds_snmp_mib *snmp = NULL; + int ret = 0; + mlan_status status = MLAN_STATUS_SUCCESS; + ENTER(); +#ifdef UAP_CFG80211 +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + if (priv && !(priv->chan.chan->flags & IEEE80211_CHAN_RADAR)) { + PRINTM(MERROR, "Current op channel NOT DFS\n"); + LEAVE(); + return -EINVAL; + } +#endif +#endif + ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_snmp_mib)); + if (ioctl_req == NULL) { + LEAVE(); + return -ENOMEM; + } + snmp = (mlan_ds_snmp_mib *)ioctl_req->pbuf; + ioctl_req->req_id = MLAN_IOCTL_SNMP_MIB; + snmp->sub_command = MLAN_OID_SNMP_MIB_DOT11H_FAKERADAR; + status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } +done: + if (status != MLAN_STATUS_PENDING) + kfree(ioctl_req); + LEAVE(); + return ret; +} + /** * @brief Set/Get DFS Testing settings * @@ -10643,7 +10994,7 @@ done: * @return channel center frequency center, if found; O, otherwise */ -static t_u8 woal_get_center_freq_idx(moal_private *priv, t_u8 band, +static t_u8 woal_get_center_freq_idx(moal_private *priv, t_u16 band, t_u32 pri_chan, t_u8 chan_bw) { t_u8 center_freq_idx = 0; @@ -11044,6 +11395,677 @@ done: } #endif +#ifdef UAP_SUPPORT +/** + * @brief Given bandwidth and channel, create Band_Config + * + * @param priv A pointer to moal_private + * @param bandcfg A pointer to Band_Config_t structure + * @param channel A pointer to cfg80211_chan_def structure + * @param bandwidth 0/1/3/4 + * + * @return N/A + */ +static void woal_convert_chanbw_to_bandconfig(moal_private *priv, + Band_Config_t *bandcfg, + t_u8 channel, t_u8 bandwidth) +{ + ENTER(); + + if (channel <= MAX_BG_CHANNEL) + bandcfg->chanBand = BAND_2GHZ; + else + bandcfg->chanBand = BAND_5GHZ; + switch (bandwidth) { + case CHANNEL_BW_40MHZ_ABOVE: + bandcfg->chanWidth = CHAN_BW_40MHZ; + bandcfg->chan2Offset = SEC_CHAN_ABOVE; + break; + case CHANNEL_BW_40MHZ_BELOW: + bandcfg->chanWidth = CHAN_BW_40MHZ; + bandcfg->chan2Offset = SEC_CHAN_BELOW; + break; + case CHANNEL_BW_80MHZ: + bandcfg->chanWidth = CHAN_BW_80MHZ; + bandcfg->chan2Offset = + woal_get_second_channel_offset(priv, channel); + break; + case CHANNEL_BW_20MHZ: + default: + bandcfg->chanWidth = CHAN_BW_20MHZ; + break; + } + LEAVE(); + return; +} + +/** + * @brief Get DFS channel list + * + * @param priv A pointer to moal_private + * + * @return N/A + */ +static void woal_get_dfs_chan_list(moal_private *priv) +{ +#if defined(STA_CFG80211) || defined(UAP_CFG80211) + struct wiphy *wiphy = priv->phandle->wiphy; + struct ieee80211_supported_band *sband; +#endif + int i; + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *cfp_misc = NULL; + mlan_status status = MLAN_STATUS_SUCCESS; + +#if defined(STA_CFG80211) || defined(UAP_CFG80211) + if (IS_STA_OR_UAP_CFG80211(priv->phandle->params.cfg80211_wext) && + wiphy) { + sband = wiphy->bands[NL80211_BAND_5GHZ]; + if (sband) { + for (i = 0; i < sband->n_channels; i++) { + if (sband->channels[i].flags & + IEEE80211_CHAN_RADAR) { + priv->auto_dfs_cfg.dfs_chan_list + [priv->auto_dfs_cfg.num_of_chan] = + sband->channels[i].hw_value; + priv->auto_dfs_cfg.num_of_chan++; + } + } + return; + } + } +#endif + /* Allocate an IOCTL request buffer */ + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (req == NULL) + goto done; + + /* Fill request buffer */ + cfp_misc = (mlan_ds_misc_cfg *)req->pbuf; + cfp_misc->sub_command = MLAN_OID_MISC_CFP_TABLE; + req->req_id = MLAN_IOCTL_MISC_CFG; + req->action = MLAN_ACT_GET; + cfp_misc->param.cfp.band = BAND_A; + + /* Send IOCTL request to MLAN */ + status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) + goto done; + + for (i = 0; i < cfp_misc->param.cfp.num_chan; i++) { + if (cfp_misc->param.cfp.cfp_tbl[i].dynamic.flags & + NXP_CHANNEL_DISABLED) + continue; + if (cfp_misc->param.cfp.cfp_tbl[i].passive_scan_or_radar_detect) { + priv->auto_dfs_cfg + .dfs_chan_list[priv->auto_dfs_cfg.num_of_chan] = + cfp_misc->param.cfp.cfp_tbl[i].channel; + priv->auto_dfs_cfg.num_of_chan++; + } + } +done: + if (status != MLAN_STATUS_PENDING) + kfree(req); + + LEAVE(); + return; +} + +/** + * @brief Process dfs cac command + * + * @param priv a pointer to moal_private structure + * @param ch_rpt_req a pointer to mlan_ds_11h_chan_rep_req structure + * + * @return MLAN_STATUS_FAILRUE or MLAN_STATUS_SUCCESS + */ +static mlan_status woal_do_dfs_cac(moal_private *priv, + mlan_ds_11h_chan_rep_req *ch_rpt_req) +{ + mlan_ioctl_req *req = NULL; + mlan_ds_11h_cfg *p11h_cfg = NULL; + mlan_ds_11h_chan_rep_req *pchan_rpt_req = NULL; + mlan_status status = MLAN_STATUS_SUCCESS; + + ENTER(); + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11h_cfg)); + if (NULL == req) { + LEAVE(); + return MLAN_STATUS_FAILURE; + } + p11h_cfg = (mlan_ds_11h_cfg *)req->pbuf; + pchan_rpt_req = &p11h_cfg->param.chan_rpt_req; + + moal_memcpy_ext(priv->phandle, pchan_rpt_req, ch_rpt_req, + sizeof(mlan_ds_11h_chan_rep_req), + sizeof(mlan_ds_11h_chan_rep_req)); + + if (priv->bss_type == MLAN_BSS_TYPE_DFS) + p11h_cfg->sub_command = MLAN_OID_11H_CHAN_REPORT_REQUEST; + else + p11h_cfg->sub_command = MLAN_OID_11H_CHANNEL_CHECK; + + req->req_id = MLAN_IOCTL_11H_CFG; + + req->action = MLAN_ACT_SET; + /* Send Channel Check command and wait until the report is ready */ + status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_PENDING) + kfree(req); + LEAVE(); + return status; +} + +/** + * @brief Get Next DFS channel from dfs_chan_list + * + * @param priv a pointer to moal_private structure + * + * @return N/A + * + */ +static t_u8 woal_get_next_dfs_chan(moal_private *priv) +{ + int i; + int idx = priv->curr_cac_idx; + mlan_ds_11h_chan_dfs_state ch_dfs_state; + t_u8 chan = 0; + ENTER(); + idx++; + if (idx >= priv->auto_dfs_cfg.num_of_chan) + idx = 0; + for (i = 0; i < priv->auto_dfs_cfg.num_of_chan; i++) { + if (priv->chan_rpt_req.chanNum != + priv->auto_dfs_cfg.dfs_chan_list[idx]) { + memset(&ch_dfs_state, 0, sizeof(ch_dfs_state)); + ch_dfs_state.channel = + priv->auto_dfs_cfg.dfs_chan_list[idx]; + woal_11h_chan_dfs_state(priv, MLAN_ACT_GET, + &ch_dfs_state); + if (ch_dfs_state.dfs_state != DFS_UNAVAILABLE) { + chan = priv->auto_dfs_cfg.dfs_chan_list[idx]; + priv->curr_cac_idx = idx; + break; + } + } + idx++; + if (idx >= priv->auto_dfs_cfg.num_of_chan) + idx = 0; + } + LEAVE(); + return chan; +} + +/** + * @brief Process auto dfs cac + * + * @param priv a pointer to moal_private structure + * + * @return N/A + * + */ +static void woal_do_auto_dfs(moal_private *priv) +{ + mlan_ds_11h_chan_rep_req chan_rpt_req; + ENTER(); + if (priv->auto_dfs_cfg.multi_chan_dfs && + priv->auto_dfs_cfg.num_of_chan) { + memset(&chan_rpt_req, 0, sizeof(chan_rpt_req)); + chan_rpt_req.startFreq = START_FREQ_11A_BAND; + chan_rpt_req.chanNum = woal_get_next_dfs_chan(priv); + if (priv->chan_rpt_req.chanNum) { + woal_11h_cancel_chan_report_ioctl(priv, + MOAL_IOCTL_WAIT); + memset(&priv->chan_rpt_req, 0, + sizeof(mlan_ds_11h_chan_rep_req)); + } + if (chan_rpt_req.chanNum) { + chan_rpt_req.bandcfg.chanBand = BAND_5GHZ; + chan_rpt_req.bandcfg.chanWidth = priv->auto_dfs_cfg.bw; + chan_rpt_req.millisec_dwell_time = + priv->auto_dfs_cfg.cac_timer; + moal_memcpy_ext(priv->phandle, &priv->chan_rpt_req, + &chan_rpt_req, + sizeof(mlan_ds_11h_chan_rep_req), + sizeof(mlan_ds_11h_chan_rep_req)); + PRINTM(MCMND, + "ZeroDFS: AUTO DFS Start Radar detect on channel=%d, bandwidth=%d, cac time=%d\n", + chan_rpt_req.chanNum, + (int)(chan_rpt_req.bandcfg.chanWidth), + chan_rpt_req.millisec_dwell_time); + woal_do_dfs_cac(priv, &chan_rpt_req); + } + } + LEAVE(); + return; +} + +/* + * @brief prepare and send WOAL_EVENT_CHAN_RPT/WOAL_EVENT_RADAR + * + * @param priv A pointer moal_private structure + * @param type WOAL_EVENT_CHAN_RPT/WOAL_EVENT_RADAR + * @param channel channel + * @param radar MTRUE/MFALSE + * + * @return N/A + */ +void woal_chan_event(moal_private *priv, t_u8 type, t_u8 channel, t_u8 radar) +{ + struct woal_event *evt; + unsigned long flags; + moal_handle *handle = priv->phandle; + + evt = kzalloc(sizeof(struct woal_event), GFP_ATOMIC); + if (!evt) { + PRINTM(MERROR, "Fail to alloc memory for deauth event\n"); + LEAVE(); + return; + } + evt->priv = priv; + evt->type = type; + evt->radar_info.channel = channel; + evt->radar_info.radar = radar; + INIT_LIST_HEAD(&evt->link); + spin_lock_irqsave(&handle->evt_lock, flags); + list_add_tail(&evt->link, &handle->evt_queue); + spin_unlock_irqrestore(&handle->evt_lock, flags); + queue_work(handle->evt_workqueue, &handle->evt_work); +} + +/** + * @brief Get active UAP handler + * + * @param handle a pointer to moal_handle structure + * + * @return N/A + * + */ +static moal_private *woal_get_active_uap_interface(moal_handle *handle) +{ + int i; + moal_private *priv = NULL; + for (i = 0; i < handle->priv_num; i++) { + if (GET_BSS_ROLE(handle->priv[i]) == MLAN_BSS_ROLE_UAP) { + if (handle->priv[i]->bss_started == MTRUE) { + priv = handle->priv[i]; + break; + } + } + } + return priv; +} + +/** + * @brief handle auto uap channel switch + * + * @param priv a pointer to moal_private structure + * @param channel channel + * + * @return N/A + * + */ +static void woal_auto_uap_channel_switch(moal_private *priv, t_u8 channel) +{ + moal_private *pmpriv = NULL; + chan_band_info chaninfo; + moal_handle *ref_handle; + t_u8 band_width = CHANNEL_BW_20MHZ; + + pmpriv = woal_get_active_uap_interface(priv->phandle); + if (!pmpriv) { + ref_handle = (moal_handle *)priv->phandle->pref_mac; + pmpriv = woal_get_active_uap_interface(ref_handle); + } + if (pmpriv) { + if (MLAN_STATUS_SUCCESS != + woal_set_get_ap_channel(pmpriv, MLAN_ACT_GET, + MOAL_IOCTL_WAIT, &chaninfo)) { + PRINTM(MERROR, "Fail to get ap channel \n"); + return; + } + if (chaninfo.channel != channel) { + switch (chaninfo.bandcfg.chanWidth) { + case CHAN_BW_40MHZ: + if (chaninfo.bandcfg.chan2Offset == + SEC_CHAN_BELOW) + band_width = CHANNEL_BW_40MHZ_BELOW; + else if (chaninfo.bandcfg.chan2Offset == + SEC_CHAN_ABOVE) + band_width = CHANNEL_BW_40MHZ_ABOVE; + break; + case CHAN_BW_80MHZ: + band_width = CHANNEL_BW_80MHZ; + break; + default: + band_width = CHANNEL_BW_20MHZ; + break; + } +#define DEF_SWITCH_COUNT 10 + woal_channel_switch(pmpriv, MTRUE, 0, channel, + DEF_SWITCH_COUNT, band_width, + MTRUE); + } + } +} + +/** + * @brief Process channel event + * + * @param priv a pointer to moal_private structure + * @param type WOAL_EVENT_CHAN_RPT/WOAL_EVENT_RADAR + * @param channel channel + * @param radar radar + * + * @return N/A + * + */ +void woal_process_chan_event(moal_private *priv, t_u8 type, t_u8 channel, + t_u8 radar) +{ + mlan_ds_11h_chan_rep_req chan_rpt_req; + + if (!priv->auto_dfs_cfg.start_auto_zero_dfs) + return; + if (type == WOAL_EVENT_CHAN_RPT) { + if (priv->auto_dfs_cfg.uap_chan_switch && !radar) { + priv->auto_dfs_cfg.uap_chan_switch = MFALSE; + PRINTM(MCMND, "Trying uap_chan_switch to %d\n", + channel); + woal_auto_uap_channel_switch(priv, channel); + } + woal_do_auto_dfs(priv); + } else if (type == WOAL_EVENT_RADAR) { + memset(&chan_rpt_req, 0, sizeof(chan_rpt_req)); + chan_rpt_req.startFreq = START_FREQ_11A_BAND; + chan_rpt_req.chanNum = woal_get_next_dfs_chan(priv); + if (priv->chan_rpt_req.chanNum) { + woal_11h_cancel_chan_report_ioctl(priv, + MOAL_IOCTL_WAIT); + memset(&priv->chan_rpt_req, 0, + sizeof(mlan_ds_11h_chan_rep_req)); + } + if (chan_rpt_req.chanNum) { + chan_rpt_req.bandcfg.chanBand = BAND_5GHZ; + chan_rpt_req.bandcfg.chanWidth = priv->auto_dfs_cfg.bw; + chan_rpt_req.millisec_dwell_time = + priv->auto_dfs_cfg.cac_timer; + moal_memcpy_ext(priv->phandle, &priv->chan_rpt_req, + &chan_rpt_req, + sizeof(mlan_ds_11h_chan_rep_req), + sizeof(mlan_ds_11h_chan_rep_req)); + PRINTM(MCMND, + "ZeroDFS: AUTO DFS Start Radar detect on channel=%d, bandwidth=%d, cac time=%d\n", + chan_rpt_req.chanNum, + (int)(chan_rpt_req.bandcfg.chanWidth), + chan_rpt_req.millisec_dwell_time); + woal_do_dfs_cac(priv, &chan_rpt_req); + } + } +} + +/** + * @brief Process dfs cac command + * + * @param priv a pointer to moal_private structure + * @param respbuf respbuf buffer + * @param respbuflen respbuf length + * + * @return length + */ + +static int woal_priv_do_dfs_cac(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + int ret = 0; + int data[3] = {0}; + int user_data_len = 0, header_len = 0; + mlan_ds_11h_chan_rep_req chan_rpt_req; + mlan_status status = MLAN_STATUS_SUCCESS; + mlan_ds_11h_chan_dfs_state ch_dfs_state; + + ENTER(); + + header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_DFS_CAC); + + if ((int)strlen(respbuf) >= header_len) { + memset(&chan_rpt_req, 0, sizeof(chan_rpt_req)); + /* SET operation */ + parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data), + &user_data_len); + if (user_data_len >= 1) { + if (!data[0] || + (priv->chan_rpt_req.chanNum && + (priv->chan_rpt_req.chanNum != data[0]))) { + if (priv->chan_rpt_pending) { + woal_11h_cancel_chan_report_ioctl( + priv, MOAL_IOCTL_WAIT); + priv->chan_rpt_pending = MFALSE; + } + memset(&priv->chan_rpt_req, 0, + sizeof(mlan_ds_11h_chan_rep_req)); + PRINTM(MCMND, "ZeroDFS: Stop Radar detect\n"); + if (!data[0]) { + woal_uap_11h_ctrl(priv, MFALSE); + LEAVE(); + return ret; + } + } + if (data[0] == priv->chan_rpt_req.chanNum) + woal_uap_11h_ctrl(priv, MFALSE); + memset(&ch_dfs_state, 0, sizeof(ch_dfs_state)); + ch_dfs_state.channel = data[0]; + woal_11h_chan_dfs_state(priv, MLAN_ACT_GET, + &ch_dfs_state); + if (!ch_dfs_state.dfs_required || + ch_dfs_state.dfs_state == DFS_UNAVAILABLE) { + PRINTM(MCMND, + "ZeroDFS: This channel=%d under NOP or not DFS channel\n", + data[0]); + LEAVE(); + return -EINVAL; + } + chan_rpt_req.startFreq = START_FREQ_11A_BAND; + chan_rpt_req.chanNum = data[0]; + chan_rpt_req.bandcfg.chanBand = BAND_5GHZ; + chan_rpt_req.bandcfg.chanWidth = CHAN_BW_20MHZ; + chan_rpt_req.millisec_dwell_time = DEF_CAC_DWELL_TIME; + chan_rpt_req.host_based = MTRUE; + } + if (user_data_len >= 2) { + if (data[1] < 0 || data[1] > CHANNEL_BW_80MHZ) { + PRINTM(MERROR, "Inavalid bandwidth %d\n", + data[1]); + LEAVE(); + return -EINVAL; + } + woal_convert_chanbw_to_bandconfig(priv, + &chan_rpt_req.bandcfg, + chan_rpt_req.chanNum, + data[1]); + } + if (user_data_len >= 3) + chan_rpt_req.millisec_dwell_time = + MIN(MAX_CAC_DWELL_TIME, data[2] * 1000); +#if defined(STA_CFG80211) || defined(UAP_CFG80211) + else { + if ((woal_is_etsi_country( + priv->phandle->country_code) == MTRUE)) { + if (chan_rpt_req.chanNum == 120 || + chan_rpt_req.chanNum == 124 || + chan_rpt_req.chanNum == 128) { + chan_rpt_req.millisec_dwell_time = + DEF_CAC_DWELL_TIME * 10; + } + if (chan_rpt_req.chanNum == 116 && + user_data_len >= 2 && data[1] > 0) + chan_rpt_req.millisec_dwell_time = + DEF_CAC_DWELL_TIME * 10; + } + } +#endif + moal_memcpy_ext(priv->phandle, &priv->chan_rpt_req, + &chan_rpt_req, sizeof(mlan_ds_11h_chan_rep_req), + sizeof(mlan_ds_11h_chan_rep_req)); + PRINTM(MCMND, + "ZeroDFS: Start Radar detect on channel=%d, bandwidth=%d, cac time=%d\n", + chan_rpt_req.chanNum, + (int)(chan_rpt_req.bandcfg.chanWidth), + chan_rpt_req.millisec_dwell_time); + status = woal_do_dfs_cac(priv, &chan_rpt_req); + if (status != MLAN_STATUS_SUCCESS) + ret = -EFAULT; + else + priv->chan_rpt_pending = MTRUE; + } + LEAVE(); + return ret; +} + +/** + * @brief Set Auto Zero DFS configure + * + * @param priv Pointer to moal_private structure + * @param respbuf Pointer to response buffer + * @param resplen Response buffer length + * + * @return 0 --success, otherwise fail + */ +static int woal_priv_auto_dfs_cfg(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + int ret = 0; + int header_len = 0; + auto_zero_dfs_cfg *auto_dfs_cfg = NULL; + int i; + int idx = 0; + mlan_ds_11h_chan_dfs_state ch_dfs_state; + mlan_ds_11h_chan_rep_req chan_rpt_req; + + ENTER(); + if (priv->bss_type != MLAN_BSS_TYPE_DFS) { + PRINTM(MWARN, "Invalid BSS type\n"); + ret = -EINVAL; + goto done; + } + + header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_AUTODFS); + auto_dfs_cfg = (auto_zero_dfs_cfg *)(respbuf + header_len); + /** Auto DFS is enabled and save config to moal_private structure */ + if (auto_dfs_cfg->start_auto_zero_dfs) { + if (priv->auto_dfs_cfg.start_auto_zero_dfs || + priv->chan_rpt_req.chanNum) { + woal_11h_cancel_chan_report_ioctl(priv, + MOAL_IOCTL_WAIT); + memset(&priv->chan_rpt_req, 0, + sizeof(mlan_ds_11h_chan_rep_req)); + } + memset(&priv->auto_dfs_cfg, 0, sizeof(auto_zero_dfs_cfg)); + if (auto_dfs_cfg->cac_start_chan) { + memset(&ch_dfs_state, 0, sizeof(ch_dfs_state)); + ch_dfs_state.channel = auto_dfs_cfg->cac_start_chan; + woal_11h_chan_dfs_state(priv, MLAN_ACT_GET, + &ch_dfs_state); + if (!ch_dfs_state.dfs_required || + ch_dfs_state.dfs_state == DFS_UNAVAILABLE) { + PRINTM(MCMND, + "ZeroDFS: This channel=%d under NOP or not DFS channel\n", + auto_dfs_cfg->cac_start_chan); + LEAVE(); + return -EINVAL; + } + } + priv->auto_dfs_cfg.cac_start_chan = + auto_dfs_cfg->cac_start_chan; + if (auto_dfs_cfg->cac_timer) + priv->auto_dfs_cfg.cac_timer = + MIN(MAX_CAC_DWELL_TIME, + auto_dfs_cfg->cac_timer * 1000); + else + priv->auto_dfs_cfg.cac_timer = DEF_CAC_DWELL_TIME; + if ((auto_dfs_cfg->bw != CHANNEL_BW_20MHZ) && + (auto_dfs_cfg->bw != CHANNEL_BW_40MHZ_ABOVE) && + (auto_dfs_cfg->bw != CHANNEL_BW_40MHZ_BELOW) && + (auto_dfs_cfg->bw != CHANNEL_BW_80MHZ)) { + PRINTM(MERROR, "ZeroDFS: Invalid bw = %d\n", + auto_dfs_cfg->bw); + LEAVE(); + return -EINVAL; + } + priv->auto_dfs_cfg.bw = auto_dfs_cfg->bw; + priv->auto_dfs_cfg.uap_chan_switch = + auto_dfs_cfg->uap_chan_switch; + priv->auto_dfs_cfg.multi_chan_dfs = + auto_dfs_cfg->multi_chan_dfs; + if (auto_dfs_cfg->num_of_chan) { + for (i = 0; i < auto_dfs_cfg->num_of_chan; i++) { + memset(&ch_dfs_state, 0, sizeof(ch_dfs_state)); + ch_dfs_state.channel = + auto_dfs_cfg->dfs_chan_list[i]; + woal_11h_chan_dfs_state(priv, MLAN_ACT_GET, + &ch_dfs_state); + if (!ch_dfs_state.dfs_required) + continue; + priv->auto_dfs_cfg.dfs_chan_list[idx] = + auto_dfs_cfg->dfs_chan_list[i]; + idx++; + } + priv->auto_dfs_cfg.num_of_chan = idx; + } + if (!priv->auto_dfs_cfg.num_of_chan) + woal_get_dfs_chan_list(priv); + priv->curr_cac_idx = -1; + if (!priv->auto_dfs_cfg.cac_start_chan) + priv->auto_dfs_cfg.cac_start_chan = + woal_get_next_dfs_chan(priv); + PRINTM(MCMND, "Start Auto ZeroDFS\n"); + PRINTM(MCMND, "cac_start_chan=%d\n", + priv->auto_dfs_cfg.cac_start_chan); + PRINTM(MCMND, "cac_timer=%d\n", priv->auto_dfs_cfg.cac_timer); + PRINTM(MCMND, "bw=%d\n", priv->auto_dfs_cfg.bw); + PRINTM(MCMND, "uap_chan_switch=%d\n", + priv->auto_dfs_cfg.uap_chan_switch); + PRINTM(MCMND, "multi_chan_dfs=%d\n", + priv->auto_dfs_cfg.multi_chan_dfs); + PRINTM(MCMND, "num of chan=%d\n", + priv->auto_dfs_cfg.num_of_chan); + DBG_HEXDUMP(MCMD_D, "dfs chan list", + priv->auto_dfs_cfg.dfs_chan_list, + priv->auto_dfs_cfg.num_of_chan); + if (priv->auto_dfs_cfg.cac_start_chan) { + priv->auto_dfs_cfg.start_auto_zero_dfs = MTRUE; + memset(&chan_rpt_req, 0, sizeof(chan_rpt_req)); + chan_rpt_req.startFreq = START_FREQ_11A_BAND; + chan_rpt_req.chanNum = + priv->auto_dfs_cfg.cac_start_chan; + chan_rpt_req.bandcfg.chanBand = BAND_5GHZ; + chan_rpt_req.bandcfg.chanWidth = priv->auto_dfs_cfg.bw; + chan_rpt_req.millisec_dwell_time = + priv->auto_dfs_cfg.cac_timer; + moal_memcpy_ext(priv->phandle, &priv->chan_rpt_req, + &chan_rpt_req, + sizeof(mlan_ds_11h_chan_rep_req), + sizeof(mlan_ds_11h_chan_rep_req)); + PRINTM(MCMND, + "ZeroDFS: AUTO DFS Start Radar detect on channel=%d, bandwidth=%d, cac time=%d\n", + chan_rpt_req.chanNum, + (int)(chan_rpt_req.bandcfg.chanWidth), + chan_rpt_req.millisec_dwell_time); + woal_do_dfs_cac(priv, &chan_rpt_req); + } + } else { + PRINTM(MCMND, "Stop Auto ZeroDFS\n"); + woal_11h_cancel_chan_report_ioctl(priv, MOAL_IOCTL_WAIT); + memset(&priv->chan_rpt_req, 0, + sizeof(mlan_ds_11h_chan_rep_req)); + memset(&priv->auto_dfs_cfg, 0, sizeof(auto_zero_dfs_cfg)); + } +done: + LEAVE(); + return ret; +} +#endif + /** * @brief Set/Get CFP table codes * @@ -11123,6 +12145,183 @@ done: return ret; } +/** + * @brief mcast aggr group configure + * + * @param priv Pointer to moal_private structure + * @param respbuf Pointer to response buffer + * @param resplen Response buffer length + * + * @return 0 --success, otherwise fail + */ +static int woal_priv_mcast_aggr_group_cfg(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + int ret = 0; + int header_len = 0; + mcast_aggr_group *mcast_cfg = NULL; + int index = 0; + struct mcast_node *node = NULL; + unsigned long flags; + + ENTER(); + + header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_MCAST_AGGR_GROUP); + mcast_cfg = (mcast_aggr_group *)(respbuf + header_len); + if (mcast_cfg->action == ACTION_ADD) { + if (priv->num_mcast_addr >= MLAN_MAX_MULTICAST_LIST_SIZE) { + PRINTM(MERROR, "mcast_aggr_group already full!\n"); + ret = -EINVAL; + goto done; + } + woal_add_mcast_node(priv, mcast_cfg->mcast_addr); + } else if (mcast_cfg->action == ACTION_REMOVE) { + woal_remove_mcast_node(priv, mcast_cfg->mcast_addr); + } + memset(mcast_cfg, 0, sizeof(mcast_aggr_group)); + + spin_lock_irqsave(&priv->mcast_lock, flags); + list_for_each_entry (node, &priv->mcast_list, link) { + moal_memcpy_ext(priv->phandle, &mcast_cfg->mac_list[index], + node->mcast_addr, ETH_ALEN, ETH_ALEN); + index++; + } + spin_unlock_irqrestore(&priv->mcast_lock, flags); + mcast_cfg->num_mcast_addr = index; + priv->num_mcast_addr = index; + ret = header_len + sizeof(mcast_aggr_group); +done: + LEAVE(); + return ret; +} + +/** + * @brief mcast aggr configure + * + * @param priv Pointer to moal_private structure + * @param respbuf Pointer to response buffer + * @param resplen Response buffer length + * + * @return 0 --success, otherwise fail + */ +static int woal_priv_mc_aggr_cfg(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + mlan_ioctl_req *ioctl_req = NULL; + mlan_ds_misc_cfg *misc = NULL; + mlan_status status = MLAN_STATUS_SUCCESS; + mlan_ds_mc_aggr_cfg *mc_cfg; + int ret = 0; + int header_len = 0; + + ENTER(); + + if (!priv || !priv->phandle) { + PRINTM(MERROR, "priv or handle is null\n"); + ret = -EFAULT; + goto done; + } + + ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (ioctl_req == NULL) { + ret = -ENOMEM; + goto done; + } + + misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf; + misc->sub_command = MLAN_OID_MISC_MC_AGGR_CFG; + ioctl_req->req_id = MLAN_IOCTL_MISC_CFG; + + header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_MC_AGGR_CFG); + mc_cfg = (mlan_ds_mc_aggr_cfg *)(respbuf + header_len); + ioctl_req->action = mc_cfg->action; + misc->param.mc_aggr_cfg.enable_bitmap = mc_cfg->enable_bitmap; + misc->param.mc_aggr_cfg.mask_bitmap = mc_cfg->mask_bitmap; + misc->param.mc_aggr_cfg.cts2self_offset = mc_cfg->cts2self_offset; + + status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } + if (mc_cfg->mask_bitmap & MC_AGGR_CTRL) { + if (mc_cfg->enable_bitmap & MC_AGGR_CTRL) + priv->enable_mc_aggr = MTRUE; + else + priv->enable_mc_aggr = MFALSE; + } + + mc_cfg->enable_bitmap = misc->param.mc_aggr_cfg.enable_bitmap; + mc_cfg->mask_bitmap = misc->param.mc_aggr_cfg.mask_bitmap; + mc_cfg->cts2self_offset = misc->param.mc_aggr_cfg.cts2self_offset; + ret = header_len + sizeof(misc->param.mc_aggr_cfg); + +done: + if (status != MLAN_STATUS_PENDING) + kfree(ioctl_req); + + LEAVE(); + return ret; +} +/** + * @brief get channel load + * + * @param priv Pointer to moal_private structure + * @param respbuf Pointer to response buffer + * @param resplen Response buffer length + * + * @return 0 --success, otherwise fail + */ +static int woal_priv_get_ch_load(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + mlan_ioctl_req *ioctl_req = NULL; + mlan_ds_misc_cfg *misc = NULL; + mlan_status status = MLAN_STATUS_SUCCESS; + mlan_ds_ch_load *cl_cfg; + int ret = 0; + int header_len = 0; + + ENTER(); + + if (!priv || !priv->phandle) { + PRINTM(MERROR, "priv or handle is null\n"); + ret = -EFAULT; + goto done; + } + + ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (ioctl_req == NULL) { + ret = -ENOMEM; + goto done; + } + + misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf; + misc->sub_command = MLAN_OID_MISC_CH_LOAD; + ioctl_req->req_id = MLAN_IOCTL_MISC_CFG; + + header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_CH_LOAD); + cl_cfg = (mlan_ds_ch_load *)(respbuf + header_len); + ioctl_req->action = cl_cfg->action; + misc->param.ch_load.ch_load_param = cl_cfg->ch_load_param; + + status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } + + cl_cfg->ch_load_param = misc->param.ch_load.ch_load_param; + ret = header_len + sizeof(misc->param.ch_load); + +done: + if (status != MLAN_STATUS_PENDING) + kfree(ioctl_req); + + LEAVE(); + return ret; +} + /** * @brief Set/Get Tx/Rx antenna * @@ -12590,6 +13789,70 @@ done: return ret; } +/** + * @brief Enable/disable CSI support + * + * The command structure contains the following parameters + * csi_enable: 1: enable, 0: diable + * csi_filter_cnt: Number of CSI filters + * csi_filter: CSI filters + * + * @param priv Pointer to the mlan_private driver data struct + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written if successful else negative value + */ +static int woal_priv_csi_cmd(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *cfg = NULL; + int ret = 0; + mlan_ds_csi_params *data_ptr; + mlan_status status = MLAN_STATUS_SUCCESS; + + ENTER(); + + data_ptr = (mlan_ds_csi_params *)respbuf; + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (req == NULL) { + ret = -ENOMEM; + goto done; + } + + req->req_id = MLAN_IOCTL_MISC_CFG; + cfg = (mlan_ds_misc_cfg *)req->pbuf; + cfg->sub_command = MLAN_OID_MISC_CSI; + + cfg->param.csi_params.csi_enable = data_ptr->csi_enable; + if (data_ptr->csi_enable == 1) { + cfg->param.csi_params.head_id = data_ptr->head_id; + cfg->param.csi_params.tail_id = data_ptr->tail_id; + cfg->param.csi_params.csi_filter_cnt = data_ptr->csi_filter_cnt; + cfg->param.csi_params.chip_id = data_ptr->chip_id; + if (cfg->param.csi_params.csi_filter_cnt > CSI_FILTER_MAX) + cfg->param.csi_params.csi_filter_cnt = CSI_FILTER_MAX; + moal_memcpy_ext(priv->phandle, cfg->param.csi_params.csi_filter, + data_ptr->csi_filter, + sizeof(mlan_csi_filter_t) * + cfg->param.csi_params.csi_filter_cnt, + sizeof(mlan_csi_filter_t) * CSI_FILTER_MAX); + } + + status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } + +done: + if (status != MLAN_STATUS_PENDING) + kfree(req); + LEAVE(); + return ret; +} + /** * @brief configure 11ax HE capability or HE operation * @@ -13101,15 +14364,15 @@ done: } /** - * @brief Set/Get transition channel + * @brief Set/Get target channel * @param priv Pointer to moal_private structure * @param respbuf Pointer to response buffer * @param resplen Response buffer length * * @return Number of bytes written, negative for failure. */ -static int woal_priv_transition_channel(moal_private *priv, t_u8 *respbuf, - t_u32 respbuflen) +static int woal_priv_target_channel(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) { int header_len = 0, user_data_len = 0; int ret = 0, data[1]; @@ -13122,7 +14385,7 @@ static int woal_priv_transition_channel(moal_private *priv, t_u8 *respbuf, return ret; } - header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_TRANSITION_CHANNEL); + header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_TARGET_CHANNEL); if ((int)strlen(respbuf) == header_len) { /* GET operation */ user_data_len = 0; @@ -13136,9 +14399,57 @@ static int woal_priv_transition_channel(moal_private *priv, t_u8 *respbuf, goto done; } if (user_data_len) - priv->trans_chan = data[0]; + priv->target_chan = data[0]; } - data[0] = priv->trans_chan; + data[0] = priv->target_chan; + moal_memcpy_ext(priv->phandle, respbuf, &data, sizeof(data), + respbuflen); + ret = sizeof(int); +done: + + LEAVE(); + return ret; +} + +/** + * @brief Set/Get backup channel + * @param priv Pointer to moal_private structure + * @param respbuf Pointer to response buffer + * @param resplen Response buffer length + * + * @return Number of bytes written, negative for failure. + */ +static int woal_priv_backup_channel(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + int header_len = 0, user_data_len = 0; + int ret = 0, data[1]; + + ENTER(); + if (!priv || (priv->bss_type != MLAN_BSS_TYPE_UAP)) { + PRINTM(MERROR, "priv is null or interface is not AP"); + ret = -EFAULT; + LEAVE(); + return ret; + } + + header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_BACKUP_CHANNEL); + if ((int)strlen(respbuf) == header_len) { + /* GET operation */ + user_data_len = 0; + } else { + /* SET operation */ + parse_arguments(respbuf + header_len, data, + sizeof(data) / sizeof(int), &user_data_len); + if (user_data_len > 1) { + PRINTM(MERROR, "Invalid parameter number\n"); + ret = -EINVAL; + goto done; + } + if (user_data_len) + priv->backup_chan = data[0]; + } + data[0] = priv->backup_chan; moal_memcpy_ext(priv->phandle, respbuf, &data, sizeof(data), respbuflen); ret = sizeof(int); @@ -14123,6 +15434,45 @@ done: return ret; } +/** + * @brief Enable radar detect for DFS channel + * + * @param priv A pointer to moal private structure + * @param chan channel + * @return N/A + */ +static void woal_enable_dfs(moal_private *priv, t_u8 channel, t_u8 wait_option) +{ + mlan_ioctl_req *req = NULL; + mlan_ds_11h_chan_rep_req *pchan_rpt_req = NULL; + mlan_ds_11h_cfg *p11h_cfg = NULL; + mlan_status status = MLAN_STATUS_SUCCESS; + ENTER(); + PRINTM(MCMND, "Enable Radar detect, chan %d\n", channel); + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11h_cfg)); + if (NULL == req) { + PRINTM(MIOCTL, "No Memory to allocate ioctl buffer\n"); + LEAVE(); + return; + } + p11h_cfg = (mlan_ds_11h_cfg *)req->pbuf; + pchan_rpt_req = &p11h_cfg->param.chan_rpt_req; + pchan_rpt_req->startFreq = 5000; + pchan_rpt_req->chanNum = channel; + pchan_rpt_req->host_based = MTRUE; + pchan_rpt_req->millisec_dwell_time = 0; + + p11h_cfg->sub_command = MLAN_OID_11H_CHANNEL_CHECK; + req->req_id = MLAN_IOCTL_11H_CFG; + req->action = MLAN_ACT_SET; + /* Send Channel Check command and wait until the report is ready */ + status = woal_request_ioctl(priv, req, wait_option); + if (status != MLAN_STATUS_PENDING) + kfree(req); + LEAVE(); + return; +} + /** * @brief send CSA/ECSA action frame * @@ -14157,7 +15507,11 @@ static int woal_action_channel_switch(moal_private *priv, t_u8 block_tx, req->action = MLAN_ACT_SET; bss->param.chanswitch.chan_switch_mode = block_tx; bss->param.chanswitch.new_channel_num = channel; - bss->param.chanswitch.chan_switch_count = switch_count; + if (!switch_count) + bss->param.chanswitch.chan_switch_count = DEF_NUM_PKTS; + else + bss->param.chanswitch.chan_switch_count = + MIN(switch_count, MAX_NUM_PKTS); bss->param.chanswitch.new_oper_class = oper_class; ret = woal_request_ioctl(priv, req, wait_option); if (ret != MLAN_STATUS_SUCCESS) @@ -14169,6 +15523,34 @@ done: return ret; } +/** + * @brief move the uAP to transition channel + * + * @param priv Pointer to moal_private structure + * + * @return N/A + */ +void woal_move_to_next_channel(moal_private *priv) +{ + mlan_ds_11h_chan_dfs_state ch_dfs; + t_u8 next_chan = 0; + if (priv->target_chan) { + next_chan = priv->target_chan; + priv->target_chan = 0; + } else if (priv->backup_chan) { + next_chan = priv->backup_chan; + } + if (!next_chan) + return; + memset(&ch_dfs, 0, sizeof(ch_dfs)); + ch_dfs.channel = next_chan; + woal_11h_chan_dfs_state(priv, MLAN_ACT_GET, &ch_dfs); + if (ch_dfs.dfs_required) + woal_enable_dfs(priv, next_chan, MOAL_NO_WAIT); + woal_action_channel_switch(priv, MTRUE, 0, next_chan, 0, MOAL_NO_WAIT); + return; +} + /** * @brief Set extended channel switch ie * @@ -14184,6 +15566,7 @@ static int woal_priv_extend_channel_switch(moal_private *priv, t_u8 *respbuf, int ret = 0; int user_data_len = 0; int data[5] = {0}; + mlan_ds_11h_chan_dfs_state ch_dfs; ENTER(); if (!priv || !priv->phandle || (priv->bss_role != MLAN_BSS_ROLE_UAP) || @@ -14212,6 +15595,20 @@ static int woal_priv_extend_channel_switch(moal_private *priv, t_u8 *respbuf, LEAVE(); return ret; } + memset(&ch_dfs, 0, sizeof(ch_dfs)); + ch_dfs.channel = data[2]; + woal_11h_chan_dfs_state(priv, MLAN_ACT_GET, &ch_dfs); + if (ch_dfs.dfs_required && (ch_dfs.dfs_state == DFS_UNAVAILABLE || + ch_dfs.dfs_state == DFS_USABLE)) { + PRINTM(MERROR, + "DFS: Channel=%d is not Available, cannot switch to this channel\n", + data[2]); + ret = -EFAULT; + LEAVE(); + return ret; + } + if (ch_dfs.dfs_required) + woal_enable_dfs(priv, data[2], MOAL_IOCTL_WAIT); if (data[1]) { if (woal_check_valid_channel_operclass(priv, data[2], data[1])) { @@ -14225,7 +15622,7 @@ static int woal_priv_extend_channel_switch(moal_private *priv, t_u8 *respbuf, data[4], MFALSE); else woal_action_channel_switch(priv, data[0], data[1], data[2], - data[3], MOAL_IOCTL_WAIT); + data[4], MOAL_IOCTL_WAIT); done: LEAVE(); return ret; @@ -14441,6 +15838,717 @@ done: return ret; } +/** + * @brief enable/disable roaming offload to firmware + * + * @param priv Pointer to moal_private structure + * @param respbuf Pointer to response buffer + * @param resplen Response buffer length + + * @return Number of bytes written, negative for failure. + */ +static int woal_priv_set_roam_offload(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + int user_data_len = 0, header_len = 0, ret = 0; + int data = 0; +#ifdef STA_CFG80211 +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) + t_u8 enable = 0; +#endif +#endif + + ENTER(); + + if (!priv || !priv->phandle) { + PRINTM(MERROR, "priv or handle is null\n"); + ret = -EFAULT; + goto done; + } + +#ifdef STA_CFG80211 +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + if (moal_extflg_isset(priv->phandle, EXT_HOST_MLME)) { + ret = -EFAULT; + goto done; + } +#endif +#endif + + header_len = strlen("SETROAMOFFLOAD"); + parse_arguments(respbuf + header_len + 1, &data, 1, &user_data_len); + + if (data < 0 || data > 5) { + PRINTM(MERROR, "Invalid parameters\n"); + ret = -EFAULT; + goto done; + } + +#ifdef STA_CFG80211 +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) + if (!data) { + woal_cfg80211_vendor_event(priv, event_set_key_mgmt_offload, + &enable, sizeof(enable)); + } +#endif +#endif + + ret = woal_enable_fw_roaming(priv, data); +done: + + LEAVE(); + return ret; +} + +/** + * @brief set roaming offload aplist to firmware + * + * @param priv Pointer to moal_private structure + * @param respbuf Pointer to response buffer + * @param resplen Response buffer length + + * @return Number of bytes written, negative for failure. + */ +static int woal_priv_set_roam_offload_aplist(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + mlan_ioctl_req *ioctl_req = NULL; + mlan_ds_misc_cfg *misc = NULL; + mlan_ds_misc_roam_offload *roam = NULL; + mlan_ds_misc_roam_offload_aplist *aplist = NULL; + mlan_status status = MLAN_STATUS_SUCCESS; + int ret = 0, i = 0; + int user_data_len = 0, header_len = 0; + int ap_count = 0; + char *begin = NULL, *end = NULL; + t_u8 mac_addr[6]; + + ENTER(); + + if (!priv || !priv->phandle) { + PRINTM(MERROR, "priv or handle is null\n"); + ret = -EFAULT; + goto done; + } + +#ifdef STA_CFG80211 +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + if (moal_extflg_isset(priv->phandle, EXT_HOST_MLME)) { + ret = -EFAULT; + goto done; + } +#endif +#endif + + ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (ioctl_req == NULL) { + ret = -ENOMEM; + goto done; + } + + misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf; + misc->sub_command = MLAN_OID_MISC_ROAM_OFFLOAD_APLIST; + ioctl_req->req_id = MLAN_IOCTL_MISC_CFG; + + roam = (mlan_ds_misc_roam_offload *)&misc->param.roam_offload; + /*Set enable to invalid value(valid: 0, 1, 2)*/ + roam->enable = 3; + aplist = &roam->aplist; + + header_len = strlen("SETROAMOFFLAPLIST"); + user_data_len = strlen(respbuf) - header_len; + if (!user_data_len) { + /* GET operation */ + ioctl_req->action = MLAN_ACT_GET; + } else { + begin = &respbuf[header_len + 1]; + end = begin; + while (begin && *begin == ' ') { + begin++; + end++; + } + while (end && *end != ' ') + end++; + if (end != NULL) + *end = '\0'; + end++; + if (begin) { + if (woal_atoi(&ap_count, begin) != + MLAN_STATUS_SUCCESS) { + ret = -EINVAL; + goto done; + } + } + aplist->ap_num = ap_count; + if (ap_count > 0 && ap_count <= MAX_AP_LIST) { + /* SET operation */ + ioctl_req->action = MLAN_ACT_SET; + for (i = 0; i < ap_count; i++) { + begin = end; + while (begin && *begin == ' ') { + begin++; + end++; + } + while (end && *end != ' ' && *end != '\0') + end++; + if (end == begin) { + PRINTM(MERROR, + "AP number %d is wrong\n", + ap_count); + ret = -EINVAL; + goto done; + } + if (end != NULL) + *end = '\0'; + end++; + woal_mac2u8(mac_addr, begin); + moal_memcpy_ext(priv->phandle, + aplist->ap_mac[i], mac_addr, + MLAN_MAC_ADDR_LENGTH, + MLAN_MAC_ADDR_LENGTH); + } + } else { + PRINTM(MERROR, + "AP number is wrong.Support max 8 APs\n"); + ret = -EINVAL; + goto done; + } + } + + DBG_HEXDUMP(MERROR, "APLIST", (t_u8 *)aplist->ap_mac, + aplist->ap_num * MLAN_MAC_ADDR_LENGTH); + status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } + +done: + if (status != MLAN_STATUS_PENDING) + kfree(ioctl_req); + + LEAVE(); + return ret; +} +/** + * @brief Configure roaming offload to firmware + * + * @param priv Pointer to moal_private structure + * @param respbuf Pointer to response buffer + * @param resplen Response buffer length + + * @return Number of bytes written, negative for failure. + */ +static int woal_priv_roam_offload_cfg(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + int ret = 0, user_data_len = 0, header_len = 0, data = 0; + char *begin = NULL, *end = NULL, *pvariable_name = NULL; + t_u8 mac_addr[MLAN_MAC_ADDR_LENGTH]; + woal_roam_offload_cfg roam_offload_cfg; + t_u8 len = 0; + int count = 0, i = 0; + + ENTER(); + + if (!priv || !priv->phandle) { + PRINTM(MERROR, "priv or handle is null\n"); + ret = -EFAULT; + goto done; + } + +#ifdef STA_CFG80211 +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + if (moal_extflg_isset(priv->phandle, EXT_HOST_MLME)) { + ret = -EFAULT; + goto done; + } +#endif +#endif + + memset((char *)&roam_offload_cfg, 0, sizeof(roam_offload_cfg)); + header_len = strlen("CFGROAMOFFLOAD"); + user_data_len = strlen(respbuf) - header_len; + if (!user_data_len) { + PRINTM(MERROR, "Invalid number of parameters\n"); + ret = -EINVAL; + goto done; + } + roam_offload_cfg.band_rssi.band_preferred = 0xff; + roam_offload_cfg.trigger_condition = 0xff; + end = &respbuf[header_len]; + while (((t_u8 *)end - &respbuf[header_len]) < user_data_len - 1) { + end++; + begin = end; + while (begin && *begin == ' ') { + begin++; + end++; + } + while (end && *end != ' ' && *end != '\0' && *end != '=') + end++; + if (end == begin) { + PRINTM(MERROR, "Invalid command specified!\n"); + ret = -EINVAL; + goto done; + } + if (end) + *end = '\0'; + pvariable_name = begin; + + if (((t_u8 *)end - &respbuf[header_len]) >= user_data_len) { + PRINTM(MERROR, "Invalid command length!\n"); + ret = -EINVAL; + goto done; + } + end++; + begin = end; + while (begin && (*begin == ' ' || *begin == '=')) { + begin++; + end++; + } + while (end && *end != ' ' && *end != '\0' && *end != '=') + end++; + if (end == begin) { + PRINTM(MERROR, "Invalid command specified!\n"); + ret = -EINVAL; + goto done; + } + if (end != NULL) + *end = '\0'; + if (pvariable_name && begin) { + if (strcmp(pvariable_name, "AUTO_RECONNECT") == 0) { + woal_atoi(&data, begin); + } else if (strcmp(pvariable_name, "BSSID") == 0) { + woal_mac2u8(mac_addr, begin); + moal_memcpy_ext(priv->phandle, + roam_offload_cfg.bssid, + mac_addr, MLAN_MAC_ADDR_LENGTH, + MLAN_MAC_ADDR_LENGTH); + } else if (strcmp(pvariable_name, "BLACKLIST") == 0) { + if (woal_atoi(&count, begin) != + MLAN_STATUS_SUCCESS) { + ret = -EINVAL; + goto done; + } + if (count > 0 && count <= MAX_AP_LIST) { + roam_offload_cfg.black_list.ap_num = + count; + for (i = 0; i < count; i++) { + end++; + begin = end; + while (begin && *begin == ' ') { + begin++; + end++; + } + while (end && *end != ' ' && + *end != '\0') + end++; + if (end == begin) { + PRINTM(MERROR, + "BSSID %d is wrong\n", + count); + ret = -EINVAL; + goto done; + } + if (end != NULL) + *end = '\0'; + woal_mac2u8(mac_addr, begin); + moal_memcpy_ext( + priv->phandle, + roam_offload_cfg + .black_list + .ap_mac[i], + mac_addr, + MLAN_MAC_ADDR_LENGTH, + MLAN_MAC_ADDR_LENGTH); + } + } else { + PRINTM(MERROR, + "BSSID number is wrong.Support max %d BSSIDs\n", + MAX_AP_LIST); + ret = -EINVAL; + goto done; + } + } else if (strcmp(pvariable_name, "SSID") == 0) { + if (woal_atoi(&count, begin) != + MLAN_STATUS_SUCCESS) { + ret = -EINVAL; + goto done; + } + if (count > 0 && count <= MAX_SSID_NUM) { + roam_offload_cfg.ssid_list.ssid_num = + count; + for (i = 0; i < count; i++) { + end++; + begin = end; + while (begin && *begin == ' ') { + begin++; + end++; + } + while (end && *end != ' ' && + *end != '\0') { + end++; + len++; + } + if ((end == begin) || + len >= MLAN_MAX_SSID_LENGTH) { + PRINTM(MERROR, + "SSID %d is wrong\n", + count); + ret = -EINVAL; + goto done; + } + if (end != NULL) + *end = '\0'; + roam_offload_cfg.ssid_list + .ssids[i] + .ssid_len = len + 1; + moal_memcpy_ext( + priv->phandle, + (t_u8 *)&roam_offload_cfg + .ssid_list + .ssids[i] + .ssid, + begin, len + 1, + MLAN_MAX_SSID_LENGTH); + len = 0; + } + } else { + PRINTM(MERROR, + "SSID number is wrong.Support max %d SSIDs\n", + MAX_SSID_NUM); + ret = -EINVAL; + goto done; + } + } else if (strcmp(pvariable_name, "RETRY_COUNT") == 0) { + woal_atoi(&data, begin); + roam_offload_cfg.retry_count = (t_u8)data; + } else if (strcmp(pvariable_name, + "TRIGGER_CONDITION") == 0) { + woal_atoi(&data, begin); + roam_offload_cfg.trigger_condition = + (t_u16)data; + } else if (strcmp(pvariable_name, "MAX_RSSI") == 0) { + woal_atoi(&data, begin); + roam_offload_cfg.max_rssi = (t_u8)data; + roam_offload_cfg.rssi_param_set_flag = 1; + } else if (strcmp(pvariable_name, "MIN_RSSI") == 0) { + woal_atoi(&data, begin); + roam_offload_cfg.min_rssi = (t_u8)data; + roam_offload_cfg.rssi_param_set_flag = 1; + } else if (strcmp(pvariable_name, "STEP_RSSI") == 0) { + woal_atoi(&data, begin); + roam_offload_cfg.step_rssi = (t_u8)data; + roam_offload_cfg.rssi_param_set_flag = 1; + } else if (strcmp(pvariable_name, "BAND_PREFER") == 0) { + woal_atoi(&data, begin); + roam_offload_cfg.band_rssi.band_preferred = + (t_u8)data; + roam_offload_cfg.band_rssi_flag = 1; + } else if (strcmp(pvariable_name, "RSSI_HYSTERESIS") == + 0) { + woal_atoi(&data, begin); + roam_offload_cfg.band_rssi.rssi_hysteresis = + (t_u8)data; + roam_offload_cfg.band_rssi_flag = 1; + } + + else if (strcmp(pvariable_name, "BSSTYPE") == 0) { + woal_atoi(&data, begin); + roam_offload_cfg.bgscan_cfg.bss_type = + (t_u8)data; + roam_offload_cfg.bgscan_set_flag++; + } else if (strcmp(pvariable_name, "CHANSPERSCAN") == + 0) { + woal_atoi(&data, begin); + roam_offload_cfg.bgscan_cfg.channels_per_scan = + (t_u8)data; + roam_offload_cfg.bgscan_set_flag++; + } else if (strcmp(pvariable_name, "BGRPTCONDITION") == + 0) { + woal_atoi(&data, begin); + roam_offload_cfg.bgscan_cfg.bg_rpt_condition = + (t_u32)data; + roam_offload_cfg.bgscan_set_flag++; + } else if (strcmp(pvariable_name, "SCANINTERVAL") == + 0) { + woal_atoi(&data, begin); + roam_offload_cfg.bgscan_cfg.scan_interval = + (t_u32)data; + roam_offload_cfg.bgscan_set_flag++; + } + + else if (strcmp(pvariable_name, "EESMODE") == 0) { + woal_atoi(&data, begin); + roam_offload_cfg.ees_cfg.ees_mode = (t_u16)data; + roam_offload_cfg.ees_param_set_flag++; + } else if (strcmp(pvariable_name, "EESRPTCONDITION") == + 0) { + woal_atoi(&data, begin); + roam_offload_cfg.ees_cfg.ees_rpt_condition = + (t_u16)data; + roam_offload_cfg.ees_param_set_flag++; + } else if (strcmp(pvariable_name, "HIGHSCANPERIOD") == + 0) { + woal_atoi(&data, begin); + roam_offload_cfg.ees_cfg.high_scan_period = + (t_u16)data; + roam_offload_cfg.ees_param_set_flag++; + } else if (strcmp(pvariable_name, "HIGHSCANCOUNT") == + 0) { + woal_atoi(&data, begin); + roam_offload_cfg.ees_cfg.high_scan_count = + (t_u16)data; + roam_offload_cfg.ees_param_set_flag++; + } else if (strcmp(pvariable_name, "MIDSCANPERIOD") == + 0) { + woal_atoi(&data, begin); + roam_offload_cfg.ees_cfg.mid_scan_period = + (t_u16)data; + roam_offload_cfg.ees_param_set_flag++; + } else if (strcmp(pvariable_name, "MIDSCANCOUNT") == + 0) { + woal_atoi(&data, begin); + roam_offload_cfg.ees_cfg.mid_scan_count = + (t_u16)data; + roam_offload_cfg.ees_param_set_flag++; + } else if (strcmp(pvariable_name, "LOWSCANPERIOD") == + 0) { + woal_atoi(&data, begin); + roam_offload_cfg.ees_cfg.low_scan_period = + (t_u16)data; + roam_offload_cfg.ees_param_set_flag++; + } else if (strcmp(pvariable_name, "LOWSCANCOUNT") == + 0) { + woal_atoi(&data, begin); + roam_offload_cfg.ees_cfg.low_scan_count = + (t_u16)data; + roam_offload_cfg.ees_param_set_flag++; + } + + else if (strcmp(pvariable_name, "BCNMISSTHRESHOLD") == + 0) { + woal_atoi(&data, begin); + roam_offload_cfg.bcn_miss_threshold = + (t_u8)data; + } + + else if (strcmp(pvariable_name, + "PREBCNMISSTHRESHOLD") == 0) { + woal_atoi(&data, begin); + roam_offload_cfg.pre_bcn_miss_threshold = + (t_u8)data; + } else if (strcmp(pvariable_name, "REPEATCOUNT") == 0) { + woal_atoi(&data, begin); + roam_offload_cfg.repeat_count = (t_u16)data; + } else { + PRINTM(MERROR, "Un-support parameter: %s\n", + pvariable_name); + ret = -EINVAL; + goto done; + } + } + } + if (priv->phandle->fw_roam_enable == AUTO_RECONNECT) { + moal_memcpy_ext(priv->phandle, + priv->phandle->auto_reconnect_bssid, + roam_offload_cfg.bssid, MLAN_MAC_ADDR_LENGTH, + sizeof(mlan_802_11_mac_addr)); + moal_memcpy_ext(priv->phandle, + &priv->phandle->auto_reconnect_ssid, + &roam_offload_cfg.ssid_list.ssids[0], + sizeof(mlan_802_11_ssid), + sizeof(mlan_802_11_ssid)); + priv->phandle->auto_reconnect_retry_count = (t_u8)data; + } else { + if (moal_extflg_isset(priv->phandle, EXT_ROAMOFFLOAD_IN_HS)) + moal_memcpy_ext(priv->phandle, + (void *)&priv->phandle->fw_roam_params, + (void *)&roam_offload_cfg, + sizeof(roam_offload_cfg), + sizeof(priv->phandle->fw_roam_params)); + else + woal_config_fw_roaming(priv, ROAM_OFFLOAD_PARAM_CFG, + &roam_offload_cfg); + } +done: + LEAVE(); + return ret; +} + +/** + * @brief Configure roaming SSID passphrase + * + * @param priv Pointer to moal_private structure + * @param respbuf Pointer to response buffer + * @param resplen Response buffer length + + * @return Number of bytes written, negative for failure. + */ +static int woal_priv_set_roam_passphrase(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + mlan_ioctl_req *req = NULL; + mlan_ds_sec_cfg *sec = NULL; + int ret = 0, action = -1; + int user_data_len = 0, header_len = 0; + char *begin, *end, *opt, *item; + mlan_status status = MLAN_STATUS_SUCCESS; + woal_roam_offload_cfg roam_offload_cfg; + mlan_ds_passphrase *ssid_passphrase = NULL; + + ENTER(); + + if (!priv || !priv->phandle) { + PRINTM(MERROR, "priv or handle is null\n"); + ret = -EFAULT; + goto done; + } + +#ifdef STA_CFG80211 +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + if (moal_extflg_isset(priv->phandle, EXT_HOST_MLME)) { + ret = -EFAULT; + goto done; + } +#endif +#endif + + memset((char *)&roam_offload_cfg, 0, sizeof(roam_offload_cfg)); + header_len = strlen("SETROAMPASSPHRASE"); + user_data_len = strlen(respbuf) - header_len; + if (!user_data_len) { + PRINTM(MERROR, "Invalid number of parameters\n"); + ret = -EINVAL; + goto done; + } + + /* Parse the buf to get the cmd_action */ + begin = respbuf + header_len; + while (begin && *begin == ' ') + begin++; + end = woal_strsep(&begin, ';', '/'); + if (end) + action = woal_atox(end); + PRINTM(MMSG, "action= %d\n", action); + if (action != 1 || end[1] != '\0') { + PRINTM(MERROR, "Invalid action argument %s\n", end); + ret = -EINVAL; + goto done; + } + + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg)); + if (req == NULL) { + ret = -ENOMEM; + goto done; + } + + req->req_id = MLAN_IOCTL_SEC_CFG; + sec = (mlan_ds_sec_cfg *)req->pbuf; + sec->sub_command = MLAN_OID_SEC_CFG_PASSPHRASE; + sec->multi_passphrase = 1; + req->action = MLAN_ACT_SET; + + /*Parse the buffer like "ssid=xxx passphrase=xxxx;ssid=xxx + * passphrase=xxx"*/ + while (begin) { + while (begin && *begin == ' ') + begin++; + end = woal_strsep(&begin, ';', '/'); + item = woal_strsep(&end, ' ', '/'); + opt = woal_strsep(&item, '=', '/'); + while (opt) { + if (roam_offload_cfg.userset_passphrase >= + MAX_SEC_SSID_NUM - 1) { + PRINTM(MERROR, + "Support max %d security SSIDs!\n", + MAX_SEC_SSID_NUM); + break; + } + ssid_passphrase = + &sec->param.roam_passphrase + [roam_offload_cfg.userset_passphrase]; + if (!opt || !item || !end) { + PRINTM(MERROR, "Invalid option\n"); + ret = -EINVAL; + goto done; + } else if (!strnicmp(opt, "ssid", strlen(opt))) { + if (strlen(end) > MLAN_MAX_SSID_LENGTH) { + PRINTM(MERROR, + "SSID length exceeds max length\n"); + ret = -EFAULT; + goto done; + } + ssid_passphrase->ssid.ssid_len = strlen(item); + strncpy((char *)ssid_passphrase->ssid.ssid, + item, + MIN(strlen(item), + MLAN_MAX_SSID_LENGTH)); + PRINTM(MINFO, "ssid=%s, len=%d\n", + ssid_passphrase->ssid.ssid, + (int)ssid_passphrase->ssid.ssid_len); + } else if (!strnicmp(opt, "passphrase", strlen(opt)) && + req->action == MLAN_ACT_SET) { + if (strlen(item) < MLAN_MIN_PASSPHRASE_LENGTH || + strlen(item) > MLAN_MAX_PASSPHRASE_LENGTH) { + PRINTM(MERROR, + "Invalid length for passphrase\n"); + ret = -EINVAL; + goto done; + } + ssid_passphrase->psk_type = MLAN_PSK_PASSPHRASE; + moal_memcpy_ext(priv->phandle, + ssid_passphrase->psk.passphrase + .passphrase, + item, strlen(item), + MLAN_MAX_PASSPHRASE_LENGTH); + ssid_passphrase->psk.passphrase.passphrase_len = + strlen(item); + PRINTM(MINFO, "passphrase=%s, len=%d\n", + ssid_passphrase->psk.passphrase + .passphrase, + (int)ssid_passphrase->psk.passphrase + .passphrase_len); + } else { + PRINTM(MERROR, "Invalid option %s\n", opt); + ret = -EINVAL; + goto done; + } + if (!end || *end == '\0') + break; + while (end && *end == ' ') + end++; + item = woal_strsep(&end, ' ', '/'); + opt = woal_strsep(&item, '=', '/'); + } + roam_offload_cfg.userset_passphrase++; + } + + if (moal_extflg_isset(priv->phandle, EXT_ROAMOFFLOAD_IN_HS)) { + moal_memcpy_ext(priv->phandle, + (char *)priv->phandle->ssid_passphrase, + (char *)sec->param.roam_passphrase, + MAX_SEC_SSID_NUM * sizeof(mlan_ds_passphrase), + MAX_SEC_SSID_NUM * sizeof(mlan_ds_passphrase)); + priv->phandle->fw_roam_params.userset_passphrase = + roam_offload_cfg.userset_passphrase; + goto done; + } + + woal_config_fw_roaming(priv, ROAM_OFFLOAD_ENABLE, &roam_offload_cfg); + status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } + +done: + if (status != MLAN_STATUS_PENDING) + kfree(req); + LEAVE(); + return ret; +} + /** * @brief Download start keep alive parameters * @@ -16332,6 +18440,15 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) strlen(PRIV_CMD_HAL_PHY_CFG) - strlen(CMD_NXP); len = woal_priv_hal_phy_cfg_cmd(priv, pdata, len); goto handled; + } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_CSI, + strlen(PRIV_CMD_CSI)) == 0) { + /* Set CSI config */ + pdata = buf + strlen(CMD_NXP) + strlen(PRIV_CMD_CSI); + len = priv_cmd.total_len - strlen(PRIV_CMD_CSI) - + strlen(CMD_NXP); + priv->csi_seq = 0; + len = woal_priv_csi_cmd(priv, pdata, len); + goto handled; #ifdef STA_SUPPORT } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_ARPFILTER, strlen(PRIV_CMD_ARPFILTER)) == 0) { @@ -16629,6 +18746,25 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) len = woal_priv_11n_amsdu_aggr_ctrl(priv, buf, priv_cmd.total_len); goto handled; + } else if (strnicmp(buf + strlen(CMD_NXP), + PRIV_CMD_MCAST_AGGR_GROUP, + strlen(PRIV_CMD_MCAST_AGGR_GROUP)) == 0) { + /* mcast_aggr_group cfg*/ + len = woal_priv_mcast_aggr_group_cfg( + priv, buf, priv_cmd.total_len); + goto handled; + } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_MC_AGGR_CFG, + strlen(PRIV_CMD_MC_AGGR_CFG)) == 0) { + /* mc_aggr_cfg*/ + len = woal_priv_mc_aggr_cfg(priv, buf, + priv_cmd.total_len); + goto handled; + } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_CH_LOAD, + strlen(PRIV_CMD_CH_LOAD)) == 0) { + /* mc_aggr_cfg*/ + len = woal_priv_get_ch_load(priv, buf, + priv_cmd.total_len); + goto handled; } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_TX_BF_CAP, strlen(PRIV_CMD_TX_BF_CAP)) == 0) { /* Set/Get Transmit beamforming capabilities */ @@ -16642,6 +18778,28 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) len = woal_priv_sleep_params_ioctl(priv, buf, priv_cmd.total_len); goto handled; +#ifdef UAP_SUPPORT + } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_NET_MON, + strlen(PRIV_CMD_NET_MON)) == 0) { + /* Set/Get network monitor configurations */ + len = woal_priv_net_monitor_ioctl(priv, buf, + priv_cmd.total_len); + goto handled; +#endif +#if defined(STA_CFG80211) && defined(UAP_CFG80211) + } else if (strnicmp(buf + strlen(CMD_NXP), + PRIV_CMD_MONITOR_MODE, + strlen(PRIV_CMD_MONITOR_MODE)) == 0) { + if (IS_STA_CFG80211(cfg80211_wext)) { + /* Set/Get monitor mode */ + len = woal_priv_set_get_monitor_mode( + priv, buf, priv_cmd.total_len); + } else + len = sprintf(buf, + "CFG80211 is not enabled\n") + + 1; + goto handled; +#endif } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DFS_TESTING, strlen(PRIV_CMD_DFS_TESTING)) == 0) { /* Set/Get DFS Testing settings */ @@ -16654,11 +18812,30 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) len = woal_priv_clear_nop(priv, buf, priv_cmd.total_len); goto handled; + } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_FAKE_RADAR, + strlen(PRIV_CMD_FAKE_RADAR)) == 0) { + /* mcast_aggr_group cfg*/ + len = woal_priv_fake_radar(priv, buf, + priv_cmd.total_len); + goto handled; } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DFS53_CFG, strlen(PRIV_CMD_DFS53_CFG)) == 0) { /* Set/Get DFS W53 settings */ len = woal_priv_dfs53cfg(priv, buf, priv_cmd.total_len); goto handled; +#ifdef UAP_SUPPORT + } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DFS_CAC, + strlen(PRIV_CMD_DFS_CAC)) == 0) { + /* perform CAC */ + len = woal_priv_do_dfs_cac(priv, buf, + priv_cmd.total_len); + goto handled; + } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_AUTODFS, + strlen(PRIV_CMD_AUTODFS)) == 0) { + len = woal_priv_auto_dfs_cfg(priv, buf, + priv_cmd.total_len); + goto handled; +#endif } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_ARB_CFG, strlen(PRIV_CMD_ARB_CFG)) == 0) { /* Set/Get CFP table codes */ @@ -16752,13 +18929,19 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) priv_cmd.total_len); goto handled; } else if (strnicmp(buf + strlen(CMD_NXP), - PRIV_CMD_TRANSITION_CHANNEL, - strlen(PRIV_CMD_TRANSITION_CHANNEL)) == 0) { - /* Get/Set Transition channel*/ - len = woal_priv_transition_channel(priv, buf, - priv_cmd.total_len); + PRIV_CMD_TARGET_CHANNEL, + strlen(PRIV_CMD_TARGET_CHANNEL)) == 0) { + /* Get/Set Target channel*/ + len = woal_priv_target_channel(priv, buf, + priv_cmd.total_len); + goto handled; + } else if (strnicmp(buf + strlen(CMD_NXP), + PRIV_CMD_BACKUP_CHANNEL, + strlen(PRIV_CMD_BACKUP_CHANNEL)) == 0) { + /* Get/Set Backup channel*/ + len = woal_priv_backup_channel(priv, buf, + priv_cmd.total_len); goto handled; - } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DFS_REPEATER_CFG, strlen(PRIV_CMD_DFS_REPEATER_CFG)) == 0) { @@ -17393,6 +19576,20 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) else if (strncmp(buf, "FAKEMAC", strlen("FAKEMAC")) == 0) { len = woal_priv_config_random_mac(priv, buf, priv_cmd.total_len); + } else if (strncmp(buf, "SETROAMOFFLOAD", strlen("SETROAMOFFLOAD")) == + 0) { + len = woal_priv_set_roam_offload(priv, buf, priv_cmd.total_len); + } else if (strncmp(buf, "SETROAMOFFLAPLIST", + strlen("SETROAMOFFLAPLIST")) == 0) { + len = woal_priv_set_roam_offload_aplist(priv, buf, + priv_cmd.total_len); + } else if (strncmp(buf, "CFGROAMOFFLOAD", strlen("CFGROAMOFFLOAD")) == + 0) { + len = woal_priv_roam_offload_cfg(priv, buf, priv_cmd.total_len); + } else if (strncmp(buf, "SETROAMPASSPHRASE", + strlen("SETROAMPASSPHRASE")) == 0) { + len = woal_priv_set_roam_passphrase(priv, buf, + priv_cmd.total_len); } else if (strncmp(buf, PRIV_CMD_CLOUD_KEEP_ALIVE, strlen(PRIV_CMD_CLOUD_KEEP_ALIVE)) == 0) { len = woal_priv_cloud_keep_alive(priv, buf, priv_cmd.total_len); diff --git a/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h b/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h index d280174..c3eb98c 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h @@ -4,7 +4,7 @@ * @brief This file contains definition for private IOCTL call. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -213,9 +213,16 @@ typedef struct _chan_stats { #define PRIV_CMD_MPA_CTRL "mpactrl" #endif #define PRIV_CMD_SLEEP_PARAMS "sleepparams" +#define PRIV_CMD_NET_MON "netmon" +#if defined(STA_CFG80211) && defined(UAP_CFG80211) +#define PRIV_CMD_MONITOR_MODE "monitormode" +#endif #define PRIV_CMD_DFS_TESTING "dfstesting" #define PRIV_CMD_CLEAR_NOP "clear_nop" +#define PRIV_CMD_FAKE_RADAR "fake_radar" #define PRIV_CMD_DFS53_CFG "dfs53cfg" +#define PRIV_CMD_DFS_CAC "dfs_cac" +#define PRIV_CMD_AUTODFS "autodfs" #define PRIV_CMD_CFP_CODE "cfpcode" #define PRIV_CMD_CWMODE "cwmode" #define PRIV_CMD_ANT_CFG "antcfg" @@ -239,7 +246,8 @@ typedef struct _chan_stats { #endif #define PRIV_CMD_CFG_CLOCK_SYNC "clocksync" #define PRIV_CMD_CFG_GET_TSF_INFO "gettsfinfo" -#define PRIV_CMD_TRANSITION_CHANNEL "transchan" +#define PRIV_CMD_TARGET_CHANNEL "targetchan" +#define PRIV_CMD_BACKUP_CHANNEL "backupchan" #define PRIV_CMD_DFS_REPEATER_CFG "dfs_repeater" #ifdef WIFI_DIRECT_SUPPORT @@ -284,6 +292,10 @@ typedef struct _chan_stats { /**Private command ID to set/get independent reset*/ #define PRIV_CMD_IND_RST_CFG "indrstcfg" +#define PRIV_CMD_MCAST_AGGR_GROUP "mcast_aggr_group" +#define PRIV_CMD_MC_AGGR_CFG "mc_aggr_cfg" +#define PRIV_CMD_CH_LOAD "getchload" + #define PRIV_CMD_ARB_CFG "arb" /**Private command to configure static rx abort config */ @@ -356,6 +368,8 @@ typedef struct _ssu_params_cfg { } __attribute__((packed)) ssu_params_cfg; #endif +#define PRIV_CMD_CSI "csi" + #define PRIV_CMD_BOOTSLEEP "bootsleep" /** Private command: 11AX Cfg */ @@ -510,6 +524,27 @@ typedef struct woal_priv_addba { t_u32 rx_amsdu; } woal_addba; +/** Action field value : get */ +#define ACTION_GET 0 +/** Action field value : set */ +#define ACTION_SET 1 +/** Action field value: add */ +#define ACTION_ADD 2 +/** Action field value: remove */ +#define ACTION_REMOVE 3 +#define MC_AGGR_CTRL MBIT(0) +/* mcast_aggr_group */ +typedef struct _mcast_aggr_group { + /** action */ + t_u32 action; + /** mcast addr */ + t_u8 mcast_addr[ETH_ALEN]; + /** Number of multicast addresses in the list */ + t_u32 num_mcast_addr; + /** Multicast address list */ + mlan_802_11_mac_addr mac_list[MLAN_MAX_MULTICAST_LIST_SIZE]; +} mcast_aggr_group, *pmcast_aggr_group; + typedef struct _txrate_setting { t_u16 preamble : 2; /*BIT1-BIT0: * For legacy 11b: preamble type diff --git a/mxm_wifiex/wlan_src/mlinux/moal_init.c b/mxm_wifiex/wlan_src/mlinux/moal_init.c index 7f1d6be..4bdd115 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_init.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_init.c @@ -4,7 +4,7 @@ * driver. * * - * Copyright 2018-2021 NXP + * Copyright 2018-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -65,6 +65,8 @@ static int host_mlme; #endif #endif +static int roamoffload_in_hs; + /** Auto deep sleep */ static int auto_ds; @@ -135,6 +137,8 @@ static int pmqos = 1; static int pmqos = 0; #endif +static int chan_track = 0; + #if defined(STA_SUPPORT) /** 802.11d configuration */ static int cfg_11d; @@ -209,7 +213,9 @@ int dts_enable = 1; static int dfs_offload; #endif +#ifdef ANDROID_KERNEL int wakelock_timeout = WAKE_LOCK_TIMEOUT; +#endif #if defined(STA_SUPPORT) && defined(UAP_SUPPORT) #ifdef WIFI_DIRECT_SUPPORT @@ -299,6 +305,9 @@ static card_type_entry card_type_map_tbl[] = { #ifdef SD9177 {CARD_TYPE_SD9177, 0, CARD_SD9177}, #endif +#ifdef SDNW62X + {CARD_TYPE_SDNW62X, 0, CARD_SDNW62X}, +#endif #ifdef PCIE8897 {CARD_TYPE_PCIE8897, 0, CARD_PCIE8897}, #endif @@ -311,6 +320,9 @@ static card_type_entry card_type_map_tbl[] = { #ifdef PCIE9098 {CARD_TYPE_PCIE9098, 0, CARD_PCIE9098}, #endif +#ifdef PCIENW62X + {CARD_TYPE_PCIENW62X, 0, CARD_PCIENW62X}, +#endif #ifdef USB8801 {CARD_TYPE_USB8801, 0, CARD_USB8801}, #endif @@ -330,6 +342,10 @@ static card_type_entry card_type_map_tbl[] = { #ifdef USB9097 {CARD_TYPE_USB9097, 0, CARD_USB9097}, #endif +#ifdef USBNW62X + {CARD_TYPE_USBNW62X, 0, CARD_USBNW62X}, +#endif + }; static int dfs53cfg = DFS_W53_DEFAULT_FW; @@ -970,16 +986,20 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size, moal_extflg_isset(handle, EXT_LOW_PW_MODE) ? "on" : "off"); - } else if (strncmp(line, "wakelock_timeout", - strlen("wakelock_timeout")) == 0) { + } +#ifdef ANDROID_KERNEL + else if (strncmp(line, "wakelock_timeout", + strlen("wakelock_timeout")) == 0) { if (parse_line_read_int(line, &out_data) != MLAN_STATUS_SUCCESS) goto err; params->wakelock_timeout = out_data; PRINTM(MMSG, "wakelock_timeout=%d\n", params->wakelock_timeout); - } else if (strncmp(line, "dev_cap_mask", - strlen("dev_cap_mask")) == 0) { + } +#endif + else if (strncmp(line, "dev_cap_mask", + strlen("dev_cap_mask")) == 0) { if (parse_line_read_int(line, &out_data) != MLAN_STATUS_SUCCESS) goto err; @@ -1002,11 +1022,6 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size, "off"); } #endif -#if defined(SD8997) || defined(PCIE8997) || defined(USB8997) || \ - defined(SD8977) || defined(SD8987) || defined(SD9098) || \ - defined(USB9098) || defined(PCIE9098) || defined(SD9097) || \ - defined(USB9097) || defined(PCIE9097) || defined(SD8978) || \ - defined(SD9177) else if (strncmp(line, "pmic", strlen("pmic")) == 0) { if (parse_line_read_int(line, &out_data) != MLAN_STATUS_SUCCESS) @@ -1018,9 +1033,7 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size, PRINTM(MMSG, "pmic %s\n", moal_extflg_isset(handle, EXT_PMIC) ? "on" : "off"); - } -#endif - else if (strncmp(line, "antcfg", strlen("antcfg")) == 0) { + } else if (strncmp(line, "antcfg", strlen("antcfg")) == 0) { if (parse_line_read_int(line, &out_data) != MLAN_STATUS_SUCCESS) goto err; @@ -1206,6 +1219,22 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size, "off"); } #endif + else if (strncmp(line, "roamoffload_in_hs", + strlen("roamoffload_in_hs")) == 0) { + if (parse_line_read_int(line, &out_data) != + MLAN_STATUS_SUCCESS) + goto err; + if (out_data) + moal_extflg_set(handle, EXT_ROAMOFFLOAD_IN_HS); + else + moal_extflg_clear(handle, + EXT_ROAMOFFLOAD_IN_HS); + PRINTM(MMSG, "roamoffload_in_hs %s\n", + moal_extflg_isset(handle, + EXT_ROAMOFFLOAD_IN_HS) ? + "on" : + "off"); + } #if defined(STA_CFG80211) || defined(UAP_CFG80211) else if (strncmp(line, "disable_regd_by_driver", strlen("disable_regd_by_driver")) == 0) { @@ -1303,6 +1332,17 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size, goto err; params->dfs53cfg = out_data; PRINTM(MMSG, "dfs53cfg= %d\n", params->dfs53cfg); + } else if (strncmp(line, "chan_track", strlen("chan_track")) == + 0) { + if (parse_line_read_int(line, &out_data) != + MLAN_STATUS_SUCCESS) + goto err; + if (out_data) + moal_extflg_set(handle, EXT_CHAN_TRACK); + + PRINTM(MMSG, "chan_track= %s\n", + moal_extflg_isset(handle, EXT_PMQOS) ? "on" : + "off"); } } if (end) @@ -1509,9 +1549,11 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params) if (low_power_mode_enable) moal_extflg_set(handle, EXT_LOW_PW_MODE); +#ifdef ANDROID_KERNEL handle->params.wakelock_timeout = wakelock_timeout; if (params) handle->params.wakelock_timeout = params->wakelock_timeout; +#endif handle->params.dev_cap_mask = dev_cap_mask; if (params) handle->params.dev_cap_mask = params->dev_cap_mask; @@ -1519,14 +1561,8 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params) if (sdio_rx_aggr) moal_extflg_set(handle, EXT_SDIO_RX_AGGR); #endif -#if defined(SD8997) || defined(PCIE8997) || defined(USB8997) || \ - defined(SD8977) || defined(SD8987) || defined(SD9098) || \ - defined(USB9098) || defined(PCIE9098) || defined(SD9097) || \ - defined(USB9097) || defined(PCIE9097) || defined(SD8978) || \ - defined(SD9177) if (pmic) moal_extflg_set(handle, EXT_PMIC); -#endif handle->params.antcfg = antcfg; if (params) handle->params.antcfg = params->antcfg; @@ -1573,10 +1609,15 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params) if (pmqos) moal_extflg_set(handle, EXT_PMQOS); + if (chan_track) + moal_extflg_set(handle, EXT_CHAN_TRACK); + #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) if (dfs_offload) moal_extflg_set(handle, EXT_DFS_OFFLOAD); #endif + if (roamoffload_in_hs) + moal_extflg_set(handle, EXT_ROAMOFFLOAD_IN_HS); #if defined(STA_CFG80211) || defined(UAP_CFG80211) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) if (host_mlme) @@ -2035,8 +2076,15 @@ void woal_init_from_dev_tree(void) } } #endif - else if (!strncmp(prop->name, "gtk_rekey_offload", - strlen("gtk_rekey_offload"))) { + else if (!strncmp(prop->name, "roamoffload_in_hs", + strlen("roamoffload_in_hs"))) { + if (!of_property_read_u32(dt_node, prop->name, &data)) { + roamoffload_in_hs = data; + PRINTM(MIOCTL, "roamoffload_in_hs=%d\n", + roamoffload_in_hs); + } + } else if (!strncmp(prop->name, "gtk_rekey_offload", + strlen("gtk_rekey_offload"))) { if (!of_property_read_u32(dt_node, prop->name, &data)) { gtk_rekey_offload = data; PRINTM(MIOCTL, "gtk_rekey_offload=%d\n", @@ -2075,6 +2123,12 @@ void woal_init_from_dev_tree(void) PRINTM(MIOCTL, "sched_scan=%d\n", data); sched_scan = data; } + } else if (!strncmp(prop->name, "chan_track", + strlen("chan_track"))) { + if (!of_property_read_u32(dt_node, prop->name, &data)) { + chan_track = data; + PRINTM(MIOCTL, "chan_track=%d\n", chan_track); + } } } LEAVE(); @@ -2293,7 +2347,8 @@ MODULE_PARM_DESC(mfg_mode, "0: Download normal firmware; 1: Download MFG firmware"); #endif /* MFG_CMD_SUPPORT */ module_param(drv_mode, int, 0660); -MODULE_PARM_DESC(drv_mode, "Bit 0: STA; Bit 1: uAP; Bit 2: WIFIDIRECT"); +MODULE_PARM_DESC(drv_mode, + "Bit 0: STA; Bit 1: uAP; Bit 2: WIFIDIRECT; Bit 7: ZERO_DFS"); #ifdef STA_SUPPORT module_param(max_sta_bss, int, 0); @@ -2439,8 +2494,10 @@ MODULE_PARM_DESC(pcie_int_mode, "0: Legacy mode; 1: MSI mode; 2: MSI-X mode"); module_param(low_power_mode_enable, int, 0); MODULE_PARM_DESC(low_power_mode_enable, "0/1: Disable/Enable Low Power Mode"); +#ifdef ANDROID_KERNEL module_param(wakelock_timeout, int, 0); MODULE_PARM_DESC(wakelock_timeout, "set wakelock_timeout value (ms)"); +#endif module_param(dev_cap_mask, uint, 0); MODULE_PARM_DESC(dev_cap_mask, "Device capability mask"); @@ -2522,6 +2579,11 @@ module_param(dfs_offload, int, 0); MODULE_PARM_DESC(dfs_offload, "1: enable dfs offload; 0: disable dfs offload."); #endif +module_param(roamoffload_in_hs, int, 0); +MODULE_PARM_DESC( + roamoffload_in_hs, + "1: enable fw roaming only when host suspend; 0: always enable fw roaming."); + #ifdef UAP_SUPPORT module_param(uap_max_sta, int, 0); MODULE_PARM_DESC(uap_max_sta, "Maximum station number for UAP/GO."); @@ -2558,3 +2620,8 @@ MODULE_PARM_DESC(beacon_hints, module_param(dfs53cfg, int, 0); MODULE_PARM_DESC(dfs53cfg, "0: fw default; 1: new w53 dfs; 2: old w53 dfs"); + +module_param(chan_track, int, 0); +MODULE_PARM_DESC( + chan_track, + "1: Set channel tracking; 0: Restore channel tracking for 9098 only"); diff --git a/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c b/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c index 07d64d8..80b27dc 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c @@ -3,7 +3,7 @@ * @brief This file contains ioctl function to MLAN * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -113,11 +113,11 @@ static t_u8 eu_country_code_table[][COUNTRY_CODE_LEN] = { "LU", "MT", "MD", "MC", "ME", "NL", "NO", "PL", "RO", "SM", "RS", "SI", "SK", "ES", "SE", "CH", "TR", "UA", "UK", "GB", "NE", "NZ", "DZ", "AO", "AM", "AW", "BH", "BD", "BT", "BO", "BQ", "BW", "VG", "BF", "BI", "KH", - "CL", "CN", "KM", "CG", "CD", "CW", "EG", "FO", "GF", "PF", "GE", "GI", - "GP", "HK", "IN", "ID", "IM", "IL", "JE", "KE", "XK", "KW", "LA", "LR", - "MW", "MV", "MQ", "MR", "YT", "MA", "MZ", "MM", "NA", "NC", "NG", "OM", - "PS", "PT", "QA", "RW", "RE", "BL", "MF", "VC", "SA", "SC", "ZA", "SZ", - "SY", "TZ", "TG", "TN", "AE", "VA", "EH", "YE", "ZM", "ZW"}; + "CL", "KM", "CG", "CD", "CW", "EG", "FO", "GF", "PF", "GE", "GI", "GP", + "HK", "IN", "ID", "IM", "IL", "JE", "KE", "XK", "KW", "LA", "LR", "MW", + "MV", "MQ", "MR", "YT", "MA", "MZ", "MM", "NA", "NC", "NG", "OM", "PS", + "PT", "QA", "RW", "RE", "BL", "MF", "VC", "SA", "SC", "ZA", "SZ", "SY", + "TZ", "TG", "TN", "AE", "VA", "EH", "YE", "ZM", "ZW"}; /******************************************************** Global Variables @@ -269,7 +269,7 @@ t_u8 woal_get_second_channel_offset(moal_private *priv, int chan) /* Special Case: 20Mhz-only Channel */ woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info); - if (chan == 165) + if (bss_info.region_code != COUNTRY_CODE_US && chan == 165) return chan2Offset; switch (chan) { @@ -285,6 +285,8 @@ t_u8 woal_get_second_channel_offset(moal_private *priv, int chan) case 140: case 149: case 157: + case 165: + case 173: chan2Offset = SEC_CHAN_ABOVE; break; case 40: @@ -299,6 +301,8 @@ t_u8 woal_get_second_channel_offset(moal_private *priv, int chan) case 144: case 153: case 161: + case 169: + case 177: chan2Offset = SEC_CHAN_BELOW; break; } @@ -1926,8 +1930,11 @@ mlan_status woal_request_get_fw_info(moal_private *priv, t_u8 wait_option, priv->phandle->fw_hotfix_version = info->param.fw_info.hotfix_version; priv->phandle->fw_ecsa_enable = info->param.fw_info.ecsa_enable; + priv->phandle->fw_bands = info->param.fw_info.fw_bands; priv->phandle->fw_getlog_enable = info->param.fw_info.getlog_enable; + priv->phandle->fw_roaming_support = + info->param.fw_info.fw_roaming_support; if (priv->current_addr[0] == 0xff) moal_memcpy_ext(priv->phandle, priv->current_addr, &info->param.fw_info.mac_addr, @@ -2841,6 +2848,94 @@ done: return ret; } +static mlan_status woal_set_wake_on_mdns(moal_handle *handle, t_u8 enable) +{ + mlan_status ret = MLAN_STATUS_SUCCESS; + mlan_ds_misc_cfg *misc = NULL; + mlan_ioctl_req *req = NULL; + mlan_ds_misc_mef_flt_cfg *mef_cfg = NULL; + mef_entry_t *entry = NULL; + mef_filter_t *filter = NULL; + + ENTER(); + + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (req == NULL) { + PRINTM(MIOCTL, "IOCTL req allocated failed!\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + misc = (mlan_ds_misc_cfg *)req->pbuf; + misc->sub_command = MLAN_OID_MISC_MEF_FLT_CFG; + req->req_id = MLAN_IOCTL_MISC_CFG; + req->action = MLAN_ACT_SET; + + mef_cfg = (mlan_ds_misc_mef_flt_cfg *)(&misc->param.mef_flt_cfg); + mef_cfg->mef_act_type = MEF_ACT_WOWLAN; + mef_cfg->criteria = MBIT(3); + + entry = (mef_entry_t *)&mef_cfg->mef_entry; + entry->mode = MBIT(0); + entry->action = 3; + + filter = (mef_filter_t *)entry->filter_item; + filter->fill_flag = (FILLING_TYPE | FILLING_REPEAT | FILLING_OFFSET | + FILLING_BYTE_SEQ); + filter->type = TYPE_BYTE_EQ; + filter->repeat = 1; + filter->offset = 20; + filter->num_byte_seq = 2; + moal_memcpy_ext(handle, filter->byte_seq, "\x08\x00", 2, + sizeof(filter->byte_seq)); + entry->rpn[1] = RPN_TYPE_AND; + + filter++; + filter->fill_flag = (FILLING_TYPE | FILLING_REPEAT | FILLING_OFFSET | + FILLING_BYTE_SEQ); + filter->type = TYPE_BYTE_EQ; + filter->repeat = 1; + filter->offset = 38; + filter->num_bytes = 4; + moal_memcpy_ext(handle, filter->byte_seq, "\xe0\x00\x00\xfb", 4, + sizeof(filter->byte_seq)); + entry->rpn[2] = RPN_TYPE_AND; + filter++; + + filter->fill_flag = (FILLING_TYPE | FILLING_PATTERN | FILLING_OFFSET | + FILLING_NUM_BYTES); + filter->type = TYPE_BYTE_EQ + 1; + filter->pattern = 17; + filter->offset = 31; + filter->num_bytes = 1; + entry->rpn[3] = RPN_TYPE_AND; + filter++; + + filter->fill_flag = (FILLING_TYPE | FILLING_PATTERN | FILLING_OFFSET | + FILLING_NUM_BYTES); + filter->type = TYPE_BYTE_EQ + 1; + filter->pattern = 5353; + filter->offset = 44; + filter->num_bytes = 2; + filter++; + entry->filter_num = 4; + if (enable) { + ret = woal_request_ioctl(woal_get_priv(handle, + MLAN_BSS_ROLE_ANY), + req, MOAL_NO_WAIT); + if (ret != MLAN_STATUS_SUCCESS && ret != MLAN_STATUS_PENDING) + PRINTM(MIOCTL, "Set Mdns wake up failed! ret=%d\n", + ret); + } else { + PRINTM(MIOCTL, "Mdns wake up is disable\n"); + } + +done: + if (ret != MLAN_STATUS_PENDING) + kfree(req); + LEAVE(); + return ret; +} + /** * @brief Enable IPv6 Neighbor Solicitation offload * @@ -2879,7 +2974,6 @@ static mlan_status woal_set_ipv6_ns_offload(moal_handle *handle) entry = (mef_entry_t *)&mef_cfg->mef_entry; entry->mode = MBIT(0); entry->action = 0x40; - filter = (mef_filter_t *)entry->filter_item; filter->fill_flag = (FILLING_TYPE | FILLING_REPEAT | FILLING_OFFSET | FILLING_BYTE_SEQ); @@ -2900,7 +2994,6 @@ static mlan_status woal_set_ipv6_ns_offload(moal_handle *handle) filter->num_byte_seq = 1; moal_memcpy_ext(handle, filter->byte_seq, "\x87", 1, sizeof(filter->byte_seq)); - entry->filter_num = 2; ret = woal_request_ioctl(woal_get_priv(handle, MLAN_BSS_ROLE_ANY), req, @@ -3311,14 +3404,33 @@ mlan_status woal_cancel_hs(moal_private *priv, t_u8 wait_option) hscfg.is_invoke_hostcmd = MTRUE; ret = woal_set_get_hs_params(priv, MLAN_ACT_SET, wait_option, &hscfg); + if (moal_extflg_isset(priv->phandle, EXT_ROAMOFFLOAD_IN_HS)) { + /*Disable firmware roaming*/ + woal_enable_fw_roaming(priv, 0); + } + if (priv->phandle->fw_roam_enable == ROAM_OFFLOAD_WITH_BSSID || + priv->phandle->fw_roam_enable == ROAM_OFFLOAD_WITH_SSID || + priv->phandle->fw_roam_enable == AUTO_RECONNECT) + woal_config_fw_roaming(priv, ROAM_OFFLOAD_RESUME_CFG, NULL); +#ifdef STA_CFG80211 + if (priv->phandle->fw_roam_enable == AUTO_RECONNECT) + woal_set_clear_pmk(priv, MLAN_ACT_CLEAR); +#endif + #if IS_ENABLED(CONFIG_IPV6) if (priv->phandle->hs_auto_arp) { - PRINTM(MIOCTL, "Canecl Host Sleep... remove ipv6 offload\n"); + PRINTM(MIOCTL, "Cancel Host Sleep... remove ipv6 offload\n"); /** Set ipv6 router advertisement message offload */ woal_set_ipv6_ra_offload(priv->phandle, MFALSE); } #endif + if (priv->phandle->hs_auto_arp) { + PRINTM(MIOCTL, "Cancel Host Sleep... remove Mdns wake up\n"); + /** Set ipv6 router advertisement message offload */ + woal_set_wake_on_mdns(priv->phandle, MFALSE); + } + if (priv->phandle->hs_auto_arp) { PRINTM(MIOCTL, "Cancel Host Sleep... remove FW auto arp\n"); /* remove auto arp from FW */ @@ -3350,6 +3462,154 @@ mlan_status woal_cancel_hs(moal_private *priv, t_u8 wait_option) return ret; } +/** @brief This function config fw roaming parameters + * + * @param priv A Pointer to the moal_private structure + * @return MTRUE or MFALSE + */ +static int woal_set_fw_roaming_params(moal_private *priv) +{ + int ret = 0; + mlan_status status = MLAN_STATUS_SUCCESS; + mlan_ioctl_req *req = NULL; + mlan_ds_sec_cfg *sec = NULL; + woal_roam_offload_cfg roam_offload_cfg; +#ifdef STA_CFG80211 + t_u8 zero[MLAN_MAX_KEY_LENGTH] = {0}; +#endif + + /*Enable fw roaming*/ + woal_config_fw_roaming(priv, ROAM_OFFLOAD_ENABLE, NULL); + /*Download fw roaming parameters*/ + woal_config_fw_roaming(priv, ROAM_OFFLOAD_PARAM_CFG, + &priv->phandle->fw_roam_params); + + /*Download userset passphrase key and current connection's PMK*/ +#ifdef STA_CFG80211 + if (!priv->phandle->fw_roam_params.userset_passphrase) { + woal_set_clear_pmk(priv, MLAN_ACT_SET); + goto done; + } +#endif + + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg)); + if (req == NULL) { + ret = -ENOMEM; + goto done; + } + + req->req_id = MLAN_IOCTL_SEC_CFG; + sec = (mlan_ds_sec_cfg *)req->pbuf; + sec->sub_command = MLAN_OID_SEC_CFG_PASSPHRASE; + sec->multi_passphrase = 1; + req->action = MLAN_ACT_SET; + + /*Copy user set passphrase*/ + moal_memcpy_ext(priv->phandle, (char *)sec->param.roam_passphrase, + (char *)priv->phandle->ssid_passphrase, + MAX_SEC_SSID_NUM * sizeof(mlan_ds_passphrase), + MAX_SEC_SSID_NUM * sizeof(mlan_ds_passphrase)); + roam_offload_cfg.userset_passphrase = + priv->phandle->fw_roam_params.userset_passphrase; +#ifdef STA_CFG80211 + if (memcmp(priv->pmk.pmk, zero, MLAN_MAX_KEY_LENGTH)) { + /*Download current connection PMK*/ + if (priv->pmk_saved) { + woal_set_clear_pmk(priv, MLAN_ACT_SET); + priv->pmk_saved = false; + } + } +#endif + /*Set userset to mlan adapter*/ + woal_config_fw_roaming(priv, ROAM_OFFLOAD_ENABLE, &roam_offload_cfg); + + status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } +done: + if (status != MLAN_STATUS_PENDING) + kfree(req); + LEAVE(); + return ret; +} + +/** @brief This function enable/disable fw roaming + * + * @param priv A Pointer to the moal_private structure + * @param enable Enable/disable fw roaming + * @return MTRUE or MFALSE + */ +int woal_enable_fw_roaming(moal_private *priv, int data) +{ + mlan_ioctl_req *ioctl_req = NULL; + mlan_ds_misc_cfg *misc = NULL; + mlan_ds_misc_roam_offload *roam = NULL; + mlan_status status = MLAN_STATUS_SUCCESS; + int ret = 0; + + ENTER(); + + if (!priv || !priv->phandle) { + PRINTM(MERROR, "priv or handle is null\n"); + ret = -EFAULT; + goto done; + } + + ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (ioctl_req == NULL) { + ret = -ENOMEM; + goto done; + } + + if (!data && !priv->phandle->fw_roam_enable) { + PRINTM(MIOCTL, "Fw roaming already disabled\n"); + goto done; + } + + misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf; + misc->sub_command = MLAN_OID_MISC_ROAM_OFFLOAD; + ioctl_req->req_id = MLAN_IOCTL_MISC_CFG; + + roam = (mlan_ds_misc_roam_offload *)&misc->param.roam_offload; + roam->aplist.ap_num = 0; + /* SET operation */ + ioctl_req->action = MLAN_ACT_SET; + roam->enable = data; + roam->config_mode = ROAM_OFFLOAD_ENABLE; + + if (moal_extflg_isset(priv->phandle, EXT_ROAMOFFLOAD_IN_HS) && data) { + priv->phandle->fw_roam_enable = data; + goto done; + } + + status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } + priv->phandle->fw_roam_enable = data; + if (!data) { + memset((char *)&priv->phandle->fw_roam_params, 0, + sizeof(woal_roam_offload_cfg)); + memset((char *)&priv->phandle->ssid_passphrase, 0, + MAX_SEC_SSID_NUM * sizeof(mlan_ds_passphrase)); + } +#ifdef STA_CFG80211 + else if (priv->media_connected && priv->pmk_saved) { + woal_set_clear_pmk(priv, MLAN_ACT_SET); + priv->pmk_saved = false; + } +#endif +done: + if (status != MLAN_STATUS_PENDING) + kfree(ioctl_req); + + LEAVE(); + return ret; +} + /** @brief This function enables the host sleep * * @param priv A Pointer to the moal_private structure @@ -3438,6 +3698,19 @@ int woal_enable_hs(moal_private *priv) woal_reconfig_bgscan(priv->phandle); #endif + if (moal_extflg_isset(priv->phandle, EXT_ROAMOFFLOAD_IN_HS) && + handle->fw_roam_enable) { + woal_set_fw_roaming_params(priv); + } + if (handle->fw_roam_enable == ROAM_OFFLOAD_WITH_BSSID || + handle->fw_roam_enable == ROAM_OFFLOAD_WITH_SSID || + handle->fw_roam_enable == AUTO_RECONNECT) { + woal_config_fw_roaming(priv, ROAM_OFFLOAD_SUSPEND_CFG, NULL); +#ifdef STA_CFG80211 + if (priv->phandle->fw_roam_enable == AUTO_RECONNECT) + woal_set_clear_pmk(priv, MLAN_ACT_SET); +#endif + } media_connected = woal_check_media_connected(handle); #if IS_ENABLED(CONFIG_IPV6) if (handle->hs_auto_arp && media_connected) { @@ -3448,6 +3721,13 @@ int woal_enable_hs(moal_private *priv) woal_set_ipv6_ns_offload(handle); } #endif + + if (handle->hs_auto_arp) { + PRINTM(MIOCTL, "Host Sleep enabled... set mdns wake up\n"); + /**MDNS wake up**/ + woal_set_wake_on_mdns(handle, MTRUE); + } + if (handle->hs_auto_arp && media_connected) { PRINTM(MIOCTL, "Host Sleep enabled... set FW auto arp\n"); /* Set auto arp response configuration to Fw */ @@ -5544,6 +5824,136 @@ int woal_find_essid(moal_private *priv, mlan_ssid_bssid *ssid_bssid, return ret; } +/** + * @brief auto reconnection configure + * + * @param priv Pointer to moal_private structure + * @param cfg_mode configure mode + * @param roam_offload_cfg Pointer to woal_roam_offload_cfg structure + * + * @return Number of bytes written, negative for failure. + */ +mlan_status woal_config_fw_roaming(moal_private *priv, t_u8 cfg_mode, + woal_roam_offload_cfg *roam_offload_cfg) +{ + mlan_ioctl_req *ioctl_req = NULL; + mlan_ds_misc_cfg *misc = NULL; + mlan_ds_misc_roam_offload *roam = NULL; + mlan_status status = MLAN_STATUS_SUCCESS; + int ret = 0; + + ENTER(); + + if (!priv || !priv->phandle) { + PRINTM(MERROR, "priv or handle is null\n"); + ret = -EFAULT; + goto done; + } + + ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (ioctl_req == NULL) { + ret = -ENOMEM; + goto done; + } + + misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf; + misc->sub_command = MLAN_OID_MISC_ROAM_OFFLOAD; + ioctl_req->req_id = MLAN_IOCTL_MISC_CFG; + + roam = (mlan_ds_misc_roam_offload *)&misc->param.roam_offload; + roam->aplist.ap_num = 0; + ioctl_req->action = MLAN_ACT_SET; + roam->enable = priv->phandle->fw_roam_enable; + roam->config_mode = cfg_mode; + + if ((roam->config_mode == ROAM_OFFLOAD_ENABLE) && roam_offload_cfg) { + roam->userset_passphrase = roam_offload_cfg->userset_passphrase; + if (roam->userset_passphrase) + roam->enable = 0; + } + if (roam->config_mode == ROAM_OFFLOAD_PARAM_CFG) { + moal_memcpy_ext(priv->phandle, (t_u8 *)&roam->bssid_reconnect, + (t_u8 *)&roam_offload_cfg->bssid, + MLAN_MAC_ADDR_LENGTH, + sizeof(roam->bssid_reconnect)); + if (roam_offload_cfg->ssid_list.ssid_num) { + moal_memcpy_ext(priv->phandle, (t_u8 *)&roam->ssid_list, + (t_u8 *)&roam_offload_cfg->ssid_list, + sizeof(mlan_ds_misc_ssid_list), + sizeof(mlan_ds_misc_ssid_list)); + } + if (roam_offload_cfg->black_list.ap_num) { + moal_memcpy_ext( + priv->phandle, (t_u8 *)&roam->black_list, + (t_u8 *)&roam_offload_cfg->black_list, + sizeof(mlan_ds_misc_roam_offload_aplist), + sizeof(mlan_ds_misc_roam_offload_aplist)); + } + roam->trigger_condition = roam_offload_cfg->trigger_condition; + roam->retry_count = roam_offload_cfg->retry_count; + if (roam_offload_cfg->rssi_param_set_flag) { + roam->para_rssi.set_flag = 1; + roam->para_rssi.max_rssi = roam_offload_cfg->max_rssi; + roam->para_rssi.min_rssi = roam_offload_cfg->min_rssi; + roam->para_rssi.step_rssi = roam_offload_cfg->step_rssi; + } + if (roam_offload_cfg->band_rssi_flag) { + roam->band_rssi_flag = roam_offload_cfg->band_rssi_flag; + moal_memcpy_ext(priv->phandle, (t_u8 *)&roam->band_rssi, + (t_u8 *)&roam_offload_cfg->band_rssi, + sizeof(mlan_ds_misc_band_rssi), + sizeof(mlan_ds_misc_band_rssi)); + } + if (roam_offload_cfg->bgscan_set_flag) { + roam->bgscan_set_flag = + roam_offload_cfg->bgscan_set_flag; + moal_memcpy_ext(priv->phandle, + (t_u8 *)&roam->bgscan_cfg, + (t_u8 *)&roam_offload_cfg->bgscan_cfg, + sizeof(mlan_ds_misc_bgscan_cfg), + sizeof(mlan_ds_misc_bgscan_cfg)); + } + if (roam_offload_cfg->ees_param_set_flag) { + roam->ees_param_set_flag = + roam_offload_cfg->ees_param_set_flag; + moal_memcpy_ext(priv->phandle, (t_u8 *)&roam->ees_cfg, + (t_u8 *)&roam_offload_cfg->ees_cfg, + sizeof(mlan_ds_misc_ees_cfg), + sizeof(mlan_ds_misc_ees_cfg)); + } + roam->bcn_miss_threshold = roam_offload_cfg->bcn_miss_threshold; + roam->pre_bcn_miss_threshold = + roam_offload_cfg->pre_bcn_miss_threshold; + roam->repeat_count = roam_offload_cfg->repeat_count; + } + if (roam->config_mode == ROAM_OFFLOAD_SUSPEND_CFG) { + moal_memcpy_ext(priv->phandle, roam->bssid_reconnect, + priv->phandle->auto_reconnect_bssid, + MLAN_MAC_ADDR_LENGTH, + sizeof(roam->bssid_reconnect)); + roam->ssid_list.ssid_num = 1; + moal_memcpy_ext( + priv->phandle, (t_u8 *)&roam->ssid_list.ssids[0].ssid, + (t_u8 *)&priv->phandle->auto_reconnect_ssid.ssid, + priv->phandle->auto_reconnect_ssid.ssid_len, + MLAN_MAX_SSID_LENGTH); + roam->retry_count = priv->phandle->auto_reconnect_retry_count; + } + + status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } + +done: + if (status != MLAN_STATUS_PENDING) + kfree(ioctl_req); + + LEAVE(); + return ret; +} + /** * @brief Request user scan * @@ -6114,7 +6524,7 @@ done: int woal_set_combo_scan(moal_private *priv, char *buf, int length) { int ret = 0; - wlan_user_scan_cfg scan_cfg; + wlan_user_scan_cfg *scan_cfg; t_u8 *ptr = buf + WEXT_CSCAN_HEADER_SIZE; int buf_left = length - WEXT_CSCAN_HEADER_SIZE; int num_ssid = 0; @@ -6125,7 +6535,16 @@ int woal_set_combo_scan(moal_private *priv, char *buf, int length) t_u16 specific_scan_time = 0; ENTER(); - memset(&scan_cfg, 0, sizeof(scan_cfg)); + + scan_cfg = (wlan_user_scan_cfg *)kmalloc(sizeof(wlan_user_scan_cfg), + GFP_KERNEL); + if (!scan_cfg) { + PRINTM(MERROR, "Malloc buffer failed\n"); + LEAVE(); + return -ENOMEM; + } + + memset(scan_cfg, 0, sizeof(wlan_user_scan_cfg)); while (buf_left >= 2) { switch (*ptr) { case WEXT_CSCAN_SSID_SECTION: @@ -6140,11 +6559,11 @@ int woal_set_combo_scan(moal_private *priv, char *buf, int length) } if (ssid_len && (num_ssid < (MRVDRV_MAX_SSID_LIST_LENGTH - 1))) { - strncpy(scan_cfg.ssid_list[num_ssid].ssid, + strncpy(scan_cfg->ssid_list[num_ssid].ssid, ptr + 2, ssid_len); - scan_cfg.ssid_list[num_ssid].max_len = 0; + scan_cfg->ssid_list[num_ssid].max_len = 0; PRINTM(MIOCTL, "Combo scan: ssid=%s\n", - scan_cfg.ssid_list[num_ssid].ssid); + scan_cfg->ssid_list[num_ssid].ssid); num_ssid++; } buf_left -= ssid_len + 2; @@ -6161,9 +6580,9 @@ int woal_set_combo_scan(moal_private *priv, char *buf, int length) break; } for (i = 0; i < num_chan; i++) { - scan_cfg.chan_list[i].chan_number = ptr[2 + i]; + scan_cfg->chan_list[i].chan_number = ptr[2 + i]; PRINTM(MIOCTL, "Combo scan: chan=%d\n", - scan_cfg.chan_list[i].chan_number); + scan_cfg->chan_list[i].chan_number); } buf_left -= 2 + num_chan; ptr += 2 + num_chan; @@ -6211,11 +6630,11 @@ int woal_set_combo_scan(moal_private *priv, char *buf, int length) if (num_ssid || num_chan) { if (num_ssid) { /* Add broadcast scan to ssid_list */ - scan_cfg.ssid_list[num_ssid].max_len = 0xff; + scan_cfg->ssid_list[num_ssid].max_len = 0xff; if (priv->scan_type == MLAN_SCAN_TYPE_PASSIVE) woal_set_scan_type(priv, MLAN_SCAN_TYPE_ACTIVE); } - if (MLAN_STATUS_FAILURE == woal_do_scan(priv, &scan_cfg)) + if (MLAN_STATUS_FAILURE == woal_do_scan(priv, scan_cfg)) ret = -EFAULT; if (num_ssid && (priv->scan_type == MLAN_SCAN_TYPE_PASSIVE)) woal_set_scan_type(priv, MLAN_SCAN_TYPE_PASSIVE); @@ -6225,6 +6644,7 @@ int woal_set_combo_scan(moal_private *priv, char *buf, int length) ret = -EFAULT; } done: + kfree(scan_cfg); LEAVE(); return ret; } @@ -6854,6 +7274,65 @@ done: return ret; } +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) +/** + * @brief Set/Get network monitor configurations + * + * @param priv Pointer to moal_private structure + * @param wait_option wait option + * @param enable Enable/Disable + * @param filter Filter flag - Management/Control/Data + * @param band_chan_cfg Network monitor band channel config + * + * @return MLAN_STATUS_SUCCESS -- success, otherwise fail + */ +mlan_status woal_set_net_monitor(moal_private *priv, t_u8 wait_option, + t_u8 enable, t_u8 filter, + netmon_band_chan_cfg *band_chan_cfg) +{ + mlan_status ret = MLAN_STATUS_SUCCESS; + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *misc = NULL; + mlan_ds_misc_net_monitor *net_mon = NULL; + mlan_status status = MLAN_STATUS_SUCCESS; + + ENTER(); + + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (req == NULL) { + ret = MLAN_STATUS_FAILURE; + goto done; + } + misc = (mlan_ds_misc_cfg *)req->pbuf; + net_mon = (mlan_ds_misc_net_monitor *)&misc->param.net_mon; + misc->sub_command = MLAN_OID_MISC_NET_MONITOR; + req->req_id = MLAN_IOCTL_MISC_CFG; + req->action = MLAN_ACT_SET; + net_mon->enable_net_mon = enable; + if (net_mon->enable_net_mon) { + net_mon->filter_flag = filter; + if (net_mon->enable_net_mon == CHANNEL_SPEC_SNIFFER_MODE) { + net_mon->band = band_chan_cfg->band; + net_mon->channel = band_chan_cfg->channel; + net_mon->chan_bandwidth = band_chan_cfg->chan_bandwidth; + } + } + + status = woal_request_ioctl(priv, req, wait_option); + if (status != MLAN_STATUS_SUCCESS) { + ret = MLAN_STATUS_FAILURE; + goto done; + } + +done: + if (status != MLAN_STATUS_PENDING) + kfree(req); + + LEAVE(); + return ret; +} +#endif + /** * @brief Send delelte all BA command to MLAN * diff --git a/mxm_wifiex/wlan_src/mlinux/moal_main.c b/mxm_wifiex/wlan_src/mlinux/moal_main.c index 7a64a77..edad2d3 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_main.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_main.c @@ -4,7 +4,7 @@ * driver. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -60,6 +60,10 @@ Change log: #include #include #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0) +#include +#endif +#include #ifdef CONFIG_OF #include @@ -81,7 +85,7 @@ struct semaphore AddRemoveCardSem; * structure variable **/ moal_handle *m_handle[MAX_MLAN_ADAPTER]; - +static int reg_work; /******************************************************** Local Variables ********************************************************/ @@ -118,6 +122,7 @@ static struct _card_info card_info_SD8801 = { .slew_rate_reg = 0x8000231C, .slew_rate_bit_offset = 14, #endif + .sniffer_support = 1, .per_pkt_cfg_support = 0, }; #endif @@ -153,6 +158,7 @@ static struct _card_info card_info_SD8887 = { .slew_rate_reg = 0x80002328, .slew_rate_bit_offset = 12, #endif + .sniffer_support = 0, .per_pkt_cfg_support = 0, }; #endif @@ -188,6 +194,7 @@ static struct _card_info card_info_SD8897 = { .slew_rate_reg = 0x80002328, .slew_rate_bit_offset = 12, #endif + .sniffer_support = 0, .per_pkt_cfg_support = 0, }; #endif @@ -207,6 +214,7 @@ static struct _card_info card_info_PCIE8897 = { .rev_id_reg = 0x0c58, .fw_name = PCIE8897_DEFAULT_COMBO_FW_NAME, .fw_name_wlan = PCIE8897_DEFAULT_WLAN_FW_NAME, + .sniffer_support = 0, .per_pkt_cfg_support = 0, }; #endif @@ -225,6 +233,7 @@ static struct _card_info card_info_USB8897 = { .feature_control = FEATURE_CTRL_DEFAULT, .fw_name = USB8897_DEFAULT_COMBO_FW_NAME, .fw_name_wlan = USB8897_DEFAULT_WLAN_FW_NAME, + .sniffer_support = 0, .per_pkt_cfg_support = 0, }; #endif @@ -263,6 +272,7 @@ static struct _card_info card_info_SD8977 = { .slew_rate_reg = 0x80002328, .slew_rate_bit_offset = 12, #endif + .sniffer_support = 1, .per_pkt_cfg_support = 1, }; #endif @@ -301,6 +311,7 @@ static struct _card_info card_info_SD8978 = { .slew_rate_reg = 0x80002328, .slew_rate_bit_offset = 12, #endif + .sniffer_support = 1, .per_pkt_cfg_support = 1, }; #endif @@ -339,6 +350,7 @@ static struct _card_info card_info_SD8997 = { .slew_rate_reg = 0x80002328, .slew_rate_bit_offset = 12, #endif + .sniffer_support = 1, .per_pkt_cfg_support = 1, }; #endif @@ -378,6 +390,7 @@ static struct _card_info card_info_SD9098 = { .slew_rate_reg = 0x90002328, .slew_rate_bit_offset = 12, #endif + .sniffer_support = 1, .per_pkt_cfg_support = 1, }; #endif @@ -417,6 +430,47 @@ static struct _card_info card_info_SD9097 = { .slew_rate_reg = 0x90002328, .slew_rate_bit_offset = 12, #endif + .sniffer_support = 1, + .per_pkt_cfg_support = 1, +}; +#endif + +#ifdef SDNW62X +static struct _card_info card_info_SDNW62X = { + .embedded_supp = 1, + .drcs = 1, + .go_noa = 1, + .v16_fw_api = 1, + .v17_fw_api = 1, + .pmic = 1, + .cal_data_cfg = 0, + .low_power_enable = 0, + .rx_rate_max = 412, + .histogram_table_num = 3, + .feature_control = FEATURE_CTRL_DEFAULT, + .rev_id_reg = 0xc8, + .host_strap_reg = 0xf4, + .magic_reg = 0xf0, + .fw_name = SDNW62X_DEFAULT_COMBO_FW_NAME, + .fw_name_wlan = SDNW62X_DEFAULT_WLAN_FW_NAME, +#ifdef SDIO + .dump_fw_info = DUMP_FW_SDIO_V3, + .dump_fw_ctrl_reg = 0xf9, + .dump_fw_start_reg = 0xf1, + .dump_fw_end_reg = 0xf8, + .dump_fw_host_ready = 0xcc, + .dump_reg.reg_table = {0x08, 0x58, 0x5C, 0x5D, 0x60, 0x61, 0x62, 0x64, + 0x65, 0x66, 0x68, 0x69, 0x6a}, + .dump_reg.reg_table_size = 13, + .scratch_reg = 0xe8, + .func1_reg_start = 0x10, + .func1_reg_end = 0x17, + .fw_reset_reg = 0x0EE, + .fw_reset_val = 0x99, + .slew_rate_reg = 0x90002328, + .slew_rate_bit_offset = 12, +#endif + .sniffer_support = 1, .per_pkt_cfg_support = 1, }; #endif @@ -456,6 +510,7 @@ static struct _card_info card_info_SD9177 = { .slew_rate_reg = 0x90002328, .slew_rate_bit_offset = 12, #endif + .sniffer_support = 1, .per_pkt_cfg_support = 1, }; #endif @@ -477,6 +532,7 @@ static struct _card_info card_info_PCIE8997 = { .magic_reg = 0x0cd4, .fw_name = PCIE8997_DEFAULT_COMBO_FW_NAME, .fw_name_wlan = PCIE8997_DEFAULT_WLAN_FW_NAME, + .sniffer_support = 1, .per_pkt_cfg_support = 1, }; #endif @@ -499,6 +555,7 @@ static struct _card_info card_info_PCIE9097 = { .magic_reg = 0x1c74, .fw_name = PCIE9097_DEFAULT_COMBO_FW_NAME, .fw_name_wlan = PCIE9097_DEFAULT_WLAN_FW_NAME, + .sniffer_support = 1, .per_pkt_cfg_support = 1, }; #endif @@ -521,6 +578,30 @@ static struct _card_info card_info_PCIE9098 = { .magic_reg = 0x1c74, .fw_name = PCIE9098_DEFAULT_COMBO_FW_NAME, .fw_name_wlan = PCIE9098_DEFAULT_WLAN_FW_NAME, + .sniffer_support = 1, + .per_pkt_cfg_support = 1, +}; +#endif + +#ifdef PCIENW62X +static struct _card_info card_info_PCIENW62X = { + .embedded_supp = 1, + .drcs = 1, + .go_noa = 1, + .v16_fw_api = 1, + .v17_fw_api = 1, + .pmic = 1, + .cal_data_cfg = 0, + .low_power_enable = 0, + .rx_rate_max = 412, + .histogram_table_num = 3, + .feature_control = FEATURE_CTRL_DEFAULT, + .rev_id_reg = 0x8, + .host_strap_reg = 0x1c70, + .magic_reg = 0x1c74, + .fw_name = PCIENW62X_DEFAULT_COMBO_FW_NAME, + .fw_name_wlan = PCIENW62X_DEFAULT_WLAN_FW_NAME, + .sniffer_support = 1, .per_pkt_cfg_support = 1, }; #endif @@ -541,6 +622,7 @@ static struct _card_info card_info_USB8801 = { .histogram_table_num = 1, .fw_name = USB8801_DEFAULT_WLAN_FW_NAME, .fw_name_wlan = USB8801_DEFAULT_WLAN_FW_NAME, + .sniffer_support = 1, .per_pkt_cfg_support = 0, }; #endif @@ -559,6 +641,7 @@ static struct _card_info card_info_USB8978 = { .histogram_table_num = 1, .fw_name = USB8978_DEFAULT_COMBO_FW_NAME, .fw_name_wlan = USB8978_DEFAULT_WLAN_FW_NAME, + .sniffer_support = 1, .per_pkt_cfg_support = 1, }; #endif @@ -577,6 +660,7 @@ static struct _card_info card_info_USB8997 = { .histogram_table_num = 3, .fw_name = USB8997_DEFAULT_COMBO_FW_NAME, .fw_name_wlan = USB8997_DEFAULT_WLAN_FW_NAME, + .sniffer_support = 1, .per_pkt_cfg_support = 1, }; #endif @@ -596,6 +680,7 @@ static struct _card_info card_info_USB9098 = { .histogram_table_num = 3, .fw_name = USB9098_DEFAULT_COMBO_FW_NAME, .fw_name_wlan = USB9098_DEFAULT_WLAN_FW_NAME, + .sniffer_support = 1, .per_pkt_cfg_support = 1, }; #endif @@ -615,9 +700,31 @@ static struct _card_info card_info_USB9097 = { .histogram_table_num = 3, .fw_name = USBUSB9097_COMBO_V1_FW_NAME, .fw_name_wlan = USB9097_WLAN_V1_FW_NAME, + .sniffer_support = 1, .per_pkt_cfg_support = 1, }; #endif + +#ifdef USBNW62X +static struct _card_info card_info_USBNW62X = { + .embedded_supp = 1, + .drcs = 1, + .go_noa = 1, + .v16_fw_api = 1, + .v17_fw_api = 1, + .pmic = 1, + .cal_data_cfg = 0, + .low_power_enable = 0, + .rx_rate_max = 412, + .feature_control = FEATURE_CTRL_DEFAULT, + .histogram_table_num = 3, + .fw_name = USBNW62X_DEFAULT_COMBO_FW_NAME, + .fw_name_wlan = USBNW62X_DEFAULT_WLAN_FW_NAME, + .sniffer_support = 1, + .per_pkt_cfg_support = 1, +}; +#endif + #ifdef SD8987 static struct _card_info card_info_SD8987 = { .embedded_supp = 1, @@ -651,6 +758,7 @@ static struct _card_info card_info_SD8987 = { .slew_rate_reg = 0x80002328, .slew_rate_bit_offset = 12, #endif + .sniffer_support = 1, .per_pkt_cfg_support = 1, }; #endif @@ -735,6 +843,7 @@ static mlan_callbacks woal_callbacks = { int woal_open(struct net_device *dev); int woal_close(struct net_device *dev); int woal_set_mac_address(struct net_device *dev, void *addr); +int woal_change_mtu(struct net_device *dev, int new_mtu); void woal_tx_timeout(struct net_device *dev #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) , @@ -921,12 +1030,14 @@ void woal_process_hang(moal_handle *handle) PRINTM(MMSG, "Start to process hanging\n"); reset_handle = handle; queue_work(hang_workqueue, &hang_work); +#ifdef ANDROID_KERNEL #define WAKE_LOCK_HANG 5000 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) __pm_wakeup_event(&reset_handle->ws, WAKE_LOCK_HANG); #else wake_lock_timeout(&reset_handle->wake_lock, msecs_to_jiffies(WAKE_LOCK_HANG)); +#endif #endif } LEAVE(); @@ -962,6 +1073,75 @@ t_u8 woal_is_any_interface_active(moal_handle *handle) return MFALSE; } +#ifdef STA_CFG80211 +/** @brief This function set/clear pmk to FW + * + * @param priv A Pointer to the moal_private structure + * @param action set/clear action + * + * @return 0: success fail otherwise + */ +int woal_set_clear_pmk(moal_private *priv, t_u8 action) +{ + mlan_ioctl_req *req; + mlan_ds_sec_cfg *sec; + mlan_status status; + int ret = 0; + t_u8 zero[MLAN_MAX_KEY_LENGTH] = {0}; + ENTER(); + + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg)); + + if (req == NULL) { + ret = -ENOMEM; + } else { + sec = (mlan_ds_sec_cfg *)req->pbuf; + sec->sub_command = MLAN_OID_SEC_CFG_PASSPHRASE; + req->req_id = MLAN_IOCTL_SEC_CFG; + req->action = action; + + if (action == MLAN_ACT_SET) { + sec->param.passphrase.psk_type = MLAN_PSK_PMK; + if (memcmp(priv->pmk.pmk, zero, MLAN_MAX_KEY_LENGTH)) + moal_memcpy_ext( + priv->phandle, + &sec->param.passphrase.psk.pmk.pmk, + priv->pmk.pmk, MLAN_MAX_KEY_LENGTH, + sizeof(sec->param.passphrase.psk.pmk + .pmk)); + if (memcmp(priv->pmk.pmk_r0, zero, + MLAN_MAX_KEY_LENGTH) && + memcmp(priv->pmk.pmk_r0_name, zero, + MLAN_MAX_PMKR0_NAME_LENGTH)) { + moal_memcpy_ext( + priv->phandle, + &sec->param.passphrase.psk.pmk.pmk_r0, + priv->pmk.pmk_r0, MLAN_MAX_KEY_LENGTH, + sizeof(sec->param.passphrase.psk.pmk + .pmk_r0)); + moal_memcpy_ext( + priv->phandle, + &sec->param.passphrase.psk.pmk + .pmk_r0_name, + priv->pmk.pmk_r0_name, + MLAN_MAX_PMKR0_NAME_LENGTH, + sizeof(sec->param.passphrase.psk.pmk + .pmk_r0_name)); + } + } + + status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); + if (MLAN_STATUS_SUCCESS != status) + ret = -EFAULT; + if (status != MLAN_STATUS_PENDING) + kfree(req); + } + + LEAVE(); + return ret; +} +#endif + /** * @brief This function handle the net interface ipaddr change event * @@ -1027,6 +1207,20 @@ static int woal_netdevice_event(struct notifier_block *nb, unsigned long event, woal_set_rssi_low_threshold(priv, rssi_low, MOAL_IOCTL_WAIT); } +#endif +#ifdef STA_CFG80211 + if (priv->phandle->fw_roam_enable && + (priv->phandle->fw_roam_enable != AUTO_RECONNECT) && + !moal_extflg_isset(priv->phandle, EXT_ROAMOFFLOAD_IN_HS)) { + snprintf(rssi_low, sizeof(rssi_low), "%d", + priv->rssi_low); + woal_set_rssi_low_threshold(priv, rssi_low, + MOAL_IOCTL_WAIT); + if (priv->pmk_saved) { + woal_set_clear_pmk(priv, MLAN_ACT_SET); + priv->pmk_saved = false; + } + } #endif break; case NETDEV_DOWN: @@ -1441,6 +1635,7 @@ mlan_status woal_update_drv_tbl(moal_handle *handle, int drv_mode_local) #ifdef WIFI_DIRECT_SUPPORT int max_wfd_bss = handle->params.max_wfd_bss; #endif + int max_dfs_bss = MAX_DFS_BSS; ENTER(); @@ -1488,6 +1683,8 @@ mlan_status woal_update_drv_tbl(moal_handle *handle, int drv_mode_local) #endif /* WIFI_DIRECT_SUPPORT */ + if (drv_mode_local & DRV_MODE_DFS) + intf_num += max_dfs_bss; /* Create BSS attribute table */ if ((intf_num == 0) || (intf_num > MLAN_MAX_BSS_NUM)) { PRINTM(MERROR, "Unsupported number of BSS %d\n", intf_num); @@ -1556,6 +1753,20 @@ mlan_status woal_update_drv_tbl(moal_handle *handle, int drv_mode_local) } #endif /* WIFI_DIRECT_SUPPORT */ + if (drv_mode_local & DRV_MODE_DFS) { + for (j = 0; j < max_dfs_bss; j++) { + if (i >= (int)intf_num) + break; + bss_tbl[i].bss_type = MLAN_BSS_TYPE_DFS; + bss_tbl[i].frame_type = MLAN_DATA_FRAME_TYPE_ETH_II; + bss_tbl[i].active = MTRUE; + bss_tbl[i].bss_priority = 0; + bss_tbl[i].bss_num = j; + bss_tbl[i].bss_virtual = MFALSE; + i++; + } + } + #ifdef WIFI_DIRECT_SUPPORT #if defined(STA_CFG80211) && defined(UAP_CFG80211) /** append virtual interface at the end of table */ @@ -1720,6 +1931,9 @@ mlan_status woal_init_sw(moal_handle *handle) handle->cac_bss_index = 0xff; #endif #endif +#if defined(STA_CFG80211) && defined(UAP_CFG80211) + handle->mon_if = NULL; +#endif #ifdef REASSOCIATION MOAL_INIT_SEMAPHORE(&handle->reassoc_sem); @@ -1901,9 +2115,7 @@ void woal_free_moal_handle(moal_handle *handle) /* Unregister wiphy device and free */ if (handle->wiphy) { wiphy_unregister(handle->wiphy); -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) - woal_cfg80211_free_iftype_data(handle->wiphy); -#endif + woal_cfg80211_free_bands(handle->wiphy); wiphy_free(handle->wiphy); handle->wiphy = NULL; } @@ -2129,6 +2341,7 @@ static t_u32 woal_set_sdio_slew_rate(moal_handle *handle) mlan_status ret = MLAN_STATUS_SUCCESS; moal_private *priv = NULL; t_u32 new_value = 0; + t_u32 reg_type = MLAN_REG_MAC; priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY); if (!priv) @@ -2137,8 +2350,13 @@ static t_u32 woal_set_sdio_slew_rate(moal_handle *handle) if ((handle->card_info->slew_rate_reg != 0) && (handle->params.slew_rate > 3 || handle->params.slew_rate < 0)) return MLAN_STATUS_FAILURE; +#if defined(SD9098) || defined(SD9097) || defined(SDNW62X) || defined(SD9177) + if (IS_SD9098(handle->card_type) || IS_SD9097(handle->card_type) || + IS_SDNW62X(handle->card_type) || IS_SD9177(handle->card_type)) + reg_type = MLAN_REG_CIU; +#endif - ret = woal_getset_regrdwr(priv, MLAN_ACT_GET, MLAN_REG_MAC, + ret = woal_getset_regrdwr(priv, MLAN_ACT_GET, reg_type, handle->card_info->slew_rate_reg, &value); if (ret < 0) { PRINTM(MERROR, "woal_getset_regrdwr get REG_MAC failed\n"); @@ -2153,7 +2371,7 @@ static t_u32 woal_set_sdio_slew_rate(moal_handle *handle) PRINTM(MMSG, "Set REG 0x%8x: 0x%x slew_rate=%d\n", handle->card_info->slew_rate_reg, new_value, handle->params.slew_rate); - ret = woal_getset_regrdwr(priv, MLAN_ACT_SET, MLAN_REG_MAC, + ret = woal_getset_regrdwr(priv, MLAN_ACT_SET, reg_type, handle->card_info->slew_rate_reg, &new_value); if (ret < 0) { @@ -2318,8 +2536,7 @@ static t_u32 woal_process_init_cfg(moal_handle *handle, t_u8 *data, t_size size) } #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) eth_hw_addr_set( - handle->priv[i] - ->netdev, + handle->priv[i]->netdev, handle->priv[i] ->current_addr); #else @@ -3197,6 +3414,9 @@ static mlan_status woal_add_card_dpc(moal_handle *handle) PRINTM(MERROR, "Unable to set Low Power Mode\n"); } + /* Add channel tracking check */ + woal_set_chan_track_mode(handle, MOAL_IOCTL_WAIT); + #if defined(SDIO) if (IS_SD(handle->card_type)) woal_set_sdio_slew_rate(handle); @@ -3596,6 +3816,7 @@ static mlan_status woal_init_fw_dpc(moal_handle *handle) if (!IS_USB8997(handle->card_type) && !IS_USB9098(handle->card_type) && !IS_USB9097(handle->card_type) && + !IS_USBNW62X(handle->card_type) && !IS_USB8978(handle->card_type)) ret = woal_reset_usb_dev(handle); goto done; @@ -3938,6 +4159,21 @@ void woal_fill_mlan_buffer(moal_private *priv, mlan_buffer *pmbuf, } PRINTM(MDAT_D, "packet %04x prio=%#x\n", eth->h_proto, skb->priority); + if (priv->enable_mc_aggr && priv->num_mcast_addr) { + if (woal_find_mcast_node_tx(priv, skb)) { + mc_txcontrol *tx_ctrl = + (mc_txcontrol *)(skb->data + skb->len - + sizeof(mc_txcontrol)); + moal_memcpy_ext(priv->phandle, + (t_u8 *)&pmbuf->u.mc_tx_info, + (t_u8 *)tx_ctrl, sizeof(mc_txcontrol), + sizeof(mc_txcontrol)); + pmbuf->flags |= MLAN_BUF_FLAG_MC_AGGR_PKT; + // use AC_VO + skb->priority = 6; + } + } + /* Record the current time the packet was queued; used to determine * the amount of time the packet was queued in the driver before it * was sent to the firmware. The delay is then sent along with the @@ -3965,6 +4201,296 @@ void woal_fill_mlan_buffer(moal_private *priv, mlan_buffer *pmbuf, return; } +#if defined(STA_CFG80211) && defined(UAP_CFG80211) +/** + * @brief This function opens the network device for monitor interface + * + * @param dev A pointer to net_device structure + * + * @return 0 -- success, otherwise fail + */ +static int woal_mon_open(struct net_device *ndev) +{ + ENTER(); + LEAVE(); + return 0; +} + +/** + * @brief This function closes the network device for monitor interface + * + * @param dev A pointer to net_device structure + * + * @return 0 -- success, otherwise fail + */ +static int woal_mon_close(struct net_device *ndev) +{ + ENTER(); + LEAVE(); + return 0; +} + +/** + * @brief This function sets the MAC address to firmware for monitor interface + * + * @param dev A pointer to net_device structure + * @param addr MAC address to set + * + * @return 0 -- success, otherwise fail + */ +static int woal_mon_set_mac_address(struct net_device *ndev, void *addr) +{ + ENTER(); + LEAVE(); + return 0; +} + +/** + * @brief This function sets multicast address to firmware for monitor interface + * + * @param dev A pointer to net_device structure + * + * @return 0 -- success, otherwise fail + */ +static void woal_mon_set_multicast_list(struct net_device *ndev) +{ + ENTER(); + LEAVE(); +} + +/** + * @brief This function handles packet transmission for monitor interface + * + * @param skb A pointer to sk_buff structure + * @param dev A pointer to net_device structure + * + * @return 0 -- success, otherwise fail + */ +static netdev_tx_t woal_mon_hard_start_xmit(struct sk_buff *skb, + struct net_device *ndev) +{ + int len_rthdr; + int qos_len = 0; + int dot11_hdr_len = 24; + int snap_len = 6; + unsigned char *pdata; + unsigned short fc; + unsigned char src_mac_addr[6]; + unsigned char dst_mac_addr[6]; + struct ieee80211_hdr *dot11_hdr; + struct ieee80211_radiotap_header *prthdr = + (struct ieee80211_radiotap_header *)skb->data; + monitor_iface *mon_if = netdev_priv(ndev); + + ENTER(); + + if (mon_if == NULL || mon_if->base_ndev == NULL) { + goto fail; + } + + /* check for not even having the fixed radiotap header part */ + if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header))) { + PRINTM(MERROR, + "Invalid radiotap hdr length," + "skb->len: %d\n", + skb->len); + goto fail; /* too short to be possibly valid */ + } + + /* is it a header version we can trust to find length from? */ + if (unlikely(prthdr->it_version)) + goto fail; /* only version 0 is supported */ + + /* then there must be a radiotap header with a length we can use */ + len_rthdr = ieee80211_get_radiotap_len(skb->data); + + /* does the skb contain enough to deliver on the alleged length? */ + if (unlikely((int)skb->len < len_rthdr)) { + PRINTM(MERROR, + "Invalid data length," + "skb->len: %d\n", + skb->len); + goto fail; /* skb too short for claimed rt header extent */ + } + + /* Skip the ratiotap header */ + skb_pull(skb, len_rthdr); + + dot11_hdr = (struct ieee80211_hdr *)skb->data; + fc = le16_to_cpu(dot11_hdr->frame_control); + if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) { + /* Check if this ia a Wireless Distribution System (WDS) frame + * which has 4 MAC addresses + */ + if (dot11_hdr->frame_control & (__force __le16)0x0080) + qos_len = 2; + if ((dot11_hdr->frame_control & (__force __le16)0x0300) == + (__force __le16)0x0300) + dot11_hdr_len += 6; + + moal_memcpy_ext(NULL, dst_mac_addr, dot11_hdr->addr1, + sizeof(dst_mac_addr), sizeof(dst_mac_addr)); + moal_memcpy_ext(NULL, src_mac_addr, dot11_hdr->addr2, + sizeof(src_mac_addr), sizeof(src_mac_addr)); + + /* Skip the 802.11 header, QoS (if any) and SNAP, but leave + * spaces for for two MAC addresses + */ + skb_pull(skb, dot11_hdr_len + qos_len + snap_len - + sizeof(src_mac_addr) * 2); + pdata = (unsigned char *)skb->data; + moal_memcpy_ext(NULL, pdata, dst_mac_addr, sizeof(dst_mac_addr), + (t_u32)skb->len); + moal_memcpy_ext(NULL, pdata + sizeof(dst_mac_addr), + src_mac_addr, sizeof(src_mac_addr), + (t_u32)skb->len - sizeof(dst_mac_addr)); + + LEAVE(); + return woal_hard_start_xmit(skb, mon_if->base_ndev); + } + +fail: + dev_kfree_skb(skb); + LEAVE(); + return NETDEV_TX_OK; +} + +/** + * @brief This function returns the network statistics + * + * @param dev A pointer to net_device structure + * + * @return A pointer to net_device_stats structure + */ +static struct net_device_stats *woal_mon_get_stats(struct net_device *dev) +{ + monitor_iface *mon_if = (monitor_iface *)netdev_priv(dev); + return &mon_if->stats; +} + +static const struct net_device_ops woal_cfg80211_mon_if_ops = { + .ndo_open = woal_mon_open, + .ndo_start_xmit = woal_mon_hard_start_xmit, + .ndo_stop = woal_mon_close, + .ndo_get_stats = woal_mon_get_stats, + .ndo_set_mac_address = woal_mon_set_mac_address, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) + .ndo_set_rx_mode = woal_mon_set_multicast_list, +#else + .ndo_set_multicast_list = woal_mon_set_multicast_list, +#endif +}; + +/** + * @brief This function setup monitor interface + * + * @param dev A pointer to net_device structure + * + * @return 0 -- success, otherwise fail + */ +static void woal_mon_if_setup(struct net_device *dev) +{ + ENTER(); + ether_setup(dev); + dev->netdev_ops = &woal_cfg80211_mon_if_ops; +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 11, 9) + dev->needs_free_netdev = true; +#else + dev->destructor = free_netdev; +#endif + LEAVE(); +} + +/** + * @brief Request the driver to add a monitor interface + * + * @param priv A pointer to moal_private + * @param name Virtual interface name + * @param name_assign_type Interface name assignment type + * @param sniffer_mode Sniffer mode + * + * @return A pointer to monitor_iface + */ +monitor_iface *woal_prepare_mon_if(moal_private *priv, const char *name, + unsigned char name_assign_type, + int sniffer_mode) +{ + int ret = 0; + moal_handle *handle = priv->phandle; + struct net_device *ndev = NULL; + monitor_iface *mon_if = NULL; + + ENTER(); + + if (sniffer_mode != CHANNEL_SPEC_SNIFFER_MODE) { + PRINTM(MERROR, "Sniffer mode is not valid\n"); + ret = -EFAULT; + goto fail; + } + if ((sniffer_mode == CHANNEL_SPEC_SNIFFER_MODE) && + woal_is_any_interface_active(handle)) { + PRINTM(MERROR, + "Cannot start channel specified net monitor when Interface Active\n"); + ret = -EFAULT; + goto fail; + } + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) + ndev = alloc_netdev_mq(sizeof(*mon_if), name, name_assign_type, + woal_mon_if_setup, 1); +#else + ndev = alloc_netdev_mq(sizeof(*mon_if), name, NET_NAME_UNKNOWN, + woal_mon_if_setup, 1); +#endif +#else + ndev = alloc_netdev_mq(sizeof(*mon_if), name, woal_mon_if_setup, 1); +#endif +#else + ndev = alloc_netdev_mq(sizeof(*mon_if), name, woal_mon_if_setup); +#endif + if (!ndev) { + PRINTM(MFATAL, "Init virtual ethernet device failed\n"); + ret = -EFAULT; + goto fail; + } + + ret = dev_alloc_name(ndev, ndev->name); + if (ret < 0) { + PRINTM(MFATAL, "Net device alloc name fail.\n"); + ret = -EFAULT; + goto fail; + } + + //?memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); + + mon_if = netdev_priv(ndev); + moal_memcpy_ext(handle, mon_if->ifname, ndev->name, IFNAMSIZ, IFNAMSIZ); + + ndev->type = ARPHRD_IEEE80211_RADIOTAP; + ndev->netdev_ops = &woal_cfg80211_mon_if_ops; + + mon_if->priv = priv; + mon_if->mon_ndev = ndev; + mon_if->base_ndev = priv->netdev; + mon_if->sniffer_mode = sniffer_mode; + mon_if->radiotap_enabled = 1; + mon_if->flag = 1; + +fail: + if (ret) { + if (ndev) + free_netdev(ndev); + LEAVE(); + return NULL; + } + + LEAVE(); + return mon_if; +} +#endif + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33) static struct device_type wlan_type = { .name = "wlan", @@ -3984,6 +4510,7 @@ const struct net_device_ops woal_netdev_ops = { .ndo_do_ioctl = woal_do_ioctl, #endif .ndo_set_mac_address = woal_set_mac_address, + .ndo_change_mtu = woal_change_mtu, .ndo_tx_timeout = woal_tx_timeout, .ndo_get_stats = woal_get_stats, #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) @@ -4076,6 +4603,7 @@ const struct net_device_ops woal_uap_netdev_ops = { .ndo_do_ioctl = woal_uap_do_ioctl, #endif .ndo_set_mac_address = woal_set_mac_address, + .ndo_change_mtu = woal_change_mtu, .ndo_tx_timeout = woal_tx_timeout, .ndo_get_stats = woal_get_stats, #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) @@ -4136,6 +4664,11 @@ mlan_status woal_init_uap_dev(struct net_device *dev, moal_private *priv) dev->hard_header_len += MLAN_MIN_DATA_HEADER_LEN + sizeof(mlan_buffer) + priv->extra_tx_head_len; #endif + /** don't need register to wext */ + if (priv->bss_type == MLAN_BSS_TYPE_DFS) { + LEAVE(); + return status; + } #ifdef UAP_WEXT if (IS_UAP_WEXT(priv->phandle->params.cfg80211_wext)) { #if WIRELESS_EXT < 21 @@ -4234,6 +4767,16 @@ moal_private *woal_add_interface(moal_handle *handle, t_u8 bss_index, goto error; } #endif + memset(name, 0, sizeof(name)); + if (handle->second_mac) + snprintf(name, sizeof(name), "m%s", default_dfs_name); + else + snprintf(name, sizeof(name), "%s", default_dfs_name); + if ((bss_type == MLAN_BSS_TYPE_DFS) && + (dev_alloc_name(dev, name) < 0)) { + PRINTM(MERROR, "Could not allocate DFS device name\n"); + goto error; + } priv = (moal_private *)netdev_priv(dev); /* Save the priv to handle */ handle->priv[bss_index] = priv; @@ -4253,6 +4796,8 @@ moal_private *woal_add_interface(moal_handle *handle, t_u8 bss_index, else if (bss_type == MLAN_BSS_TYPE_WIFIDIRECT) priv->bss_role = MLAN_BSS_ROLE_STA; #endif + else if (bss_type == MLAN_BSS_TYPE_DFS) + priv->bss_role = MLAN_BSS_ROLE_UAP; INIT_LIST_HEAD(&priv->tcp_sess_queue); spin_lock_init(&priv->tcp_sess_lock); @@ -4263,6 +4808,8 @@ moal_private *woal_add_interface(moal_handle *handle, t_u8 bss_index, INIT_LIST_HEAD(&priv->tx_stat_queue); spin_lock_init(&priv->tx_stat_lock); + INIT_LIST_HEAD(&priv->mcast_list); + spin_lock_init(&priv->mcast_lock); #ifdef STA_CFG80211 #ifdef STA_SUPPORT @@ -4294,7 +4841,7 @@ moal_private *woal_add_interface(moal_handle *handle, t_u8 bss_index, woal_init_sta_dev(dev, priv); #endif #ifdef UAP_SUPPORT - if (bss_type == MLAN_BSS_TYPE_UAP) { + if (bss_type == MLAN_BSS_TYPE_UAP || bss_type == MLAN_BSS_TYPE_DFS) { if (MLAN_STATUS_SUCCESS != woal_init_uap_dev(dev, priv)) goto error; } @@ -4385,7 +4932,8 @@ moal_private *woal_add_interface(moal_handle *handle, t_u8 bss_index, #ifdef UAP_CFG80211 #ifdef UAP_SUPPORT if ((priv->bss_role == MLAN_BSS_ROLE_UAP) && - IS_UAP_CFG80211(handle->params.cfg80211_wext)) { + IS_UAP_CFG80211(handle->params.cfg80211_wext) && + bss_type != MLAN_BSS_TYPE_DFS) { /* Register cfg80211 for UAP */ if (woal_register_uap_cfg80211(dev, bss_type)) { PRINTM(MERROR, "Cannot register UAP with cfg80211\n"); @@ -4548,6 +5096,7 @@ void woal_remove_interface(moal_handle *handle, t_u8 bss_index) if (priv->media_connected == MTRUE) { priv->media_connected = MFALSE; + moal_connection_status_check_pmqos(handle); #if defined(STA_WEXT) || defined(UAP_WEXT) if (IS_STA_OR_UAP_WEXT(handle->params.cfg80211_wext) && GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) { @@ -4566,6 +5115,7 @@ void woal_remove_interface(moal_handle *handle, t_u8 bss_index) if (priv->bss_type == MLAN_BSS_TYPE_STA) woal_flush_tdls_list(priv); #endif + woal_flush_mcast_list(priv); #ifdef STA_CFG80211 if (priv->bss_type == MLAN_BSS_TYPE_STA && @@ -4809,6 +5359,53 @@ done: return status; } +/** + * @brief Configure MLAN for channel tracking mode + * + * @param priv A pointer to moal_private structure + * @param wait_option Wait option + * + * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING -- success, + * otherwise fail + */ +mlan_status woal_set_chan_track_mode(moal_handle *handle, t_u8 wait_option) +{ + moal_private *priv = NULL; + mlan_ioctl_req *req = NULL; + mlan_ds_snmp_mib *mib = NULL; + mlan_status status; + + ENTER(); + + priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY); + if (!priv) { + LEAVE(); + return MLAN_STATUS_FAILURE; + } + + /* Allocate an IOCTL request buffer */ + req = (mlan_ioctl_req *)woal_alloc_mlan_ioctl_req( + sizeof(mlan_ds_snmp_mib)); + if (req == NULL) { + status = MLAN_STATUS_FAILURE; + goto done; + } + + /* Fill request buffer */ + mib = (mlan_ds_snmp_mib *)req->pbuf; + mib->sub_command = MLAN_OID_SNMP_MIB_CHAN_TRACK; + mib->param.chan_track = moal_extflg_isset(handle, EXT_CHAN_TRACK); + req->req_id = MLAN_IOCTL_SNMP_MIB; + req->action = MLAN_ACT_SET; + + /* Send IOCTL request to MLAN */ + status = woal_request_ioctl(priv, req, wait_option); +done: + kfree(req); + LEAVE(); + return status; +} + /** * @brief Send FW shutdown command to MLAN * @@ -5137,6 +5734,54 @@ int woal_close(struct net_device *dev) return 0; } +#define DEF_MTU_SIZE 1500 +/** + * @brief This function disable the ampdu + * + * @param priv A pointer to mlan_private structure + * @param new_mtu new mtu size + * + * @return 0 --success, otherwise fail + */ +void woal_disable_ampdu(moal_private *priv) +{ + mlan_ds_11n_aggr_prio_tbl aggr_prio_tbl; + int i; + memset(&aggr_prio_tbl, 0, sizeof(aggr_prio_tbl)); + if (MLAN_STATUS_SUCCESS != + woal_ioctl_aggr_prio_tbl(priv, MLAN_ACT_GET, &aggr_prio_tbl)) { + goto done; + } + for (i = 0; i < MAX_NUM_TID; i++) + aggr_prio_tbl.ampdu[i] = 0xff; + if (MLAN_STATUS_SUCCESS != + woal_ioctl_aggr_prio_tbl(priv, MLAN_ACT_SET, &aggr_prio_tbl)) { + goto done; + } +done: + return; +} + +/** + * @brief This function change the MTU size + * + * @param dev A pointer to mlan_private structure + * @param new_mtu new mtu size + * + * @return 0 --success, otherwise fail + */ +int woal_change_mtu(struct net_device *dev, int new_mtu) +{ + moal_private *priv = (moal_private *)netdev_priv(dev); + dev->mtu = new_mtu; + // disable AMPDU with mtu size > 1500 + if (new_mtu > DEF_MTU_SIZE) + woal_disable_ampdu(priv); + PRINTM(MCMND, "wlan: change_mtu to %d\n", new_mtu); + + return 0; +} + /** * @brief This function sets the MAC address to firmware. * @@ -5552,6 +6197,73 @@ struct net_device_stats *woal_get_stats(struct net_device *dev) return &priv->stats; } +/** + * @brief This function determine the 802.1p/1d tag to use + * + * @param skb + * + * @return tid + */ +unsigned int woal_classify8021d(struct sk_buff *skb) +{ + unsigned int dscp; + unsigned char vlan_priority; + unsigned int tid; + + /* skb->priority values from 256->263 are magic values to + * directly indicate a specific 802.1d priority. This is used + * to allow 802.1d priority to be passed directly in from VLAN + * tags, etc. + */ + if (skb->priority >= 256 && skb->priority <= 263) { + tid = skb->priority - 256; + goto out; + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) + if (skb_vlan_tag_present(skb)) { + vlan_priority = (skb_vlan_tag_get(skb) & VLAN_PRIO_MASK) >> + VLAN_PRIO_SHIFT; + if (vlan_priority > 0) { + tid = vlan_priority; + goto out; + } + } +#endif + switch (skb->protocol) { + case htons(ETH_P_IP): + dscp = ipv4_get_dsfield(ip_hdr(skb)) & 0xfc; + break; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0) + case htons(ETH_P_IPV6): + dscp = ipv6_get_dsfield(ipv6_hdr(skb)) & 0xfc; + break; +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0) + case htons(ETH_P_MPLS_UC): + case htons(ETH_P_MPLS_MC): { + struct mpls_label mpls_tmp, *mpls; + + mpls = skb_header_pointer(skb, sizeof(struct ethhdr), + sizeof(*mpls), &mpls_tmp); + if (!mpls) + return 0; + + tid = (ntohl(mpls->entry) & MPLS_LS_TC_MASK) >> + MPLS_LS_TC_SHIFT; + goto out; + } + case htons(ETH_P_80221): + /* 802.21 is always network control traffic */ + return 7; +#endif + default: + return 0; + } + tid = dscp >> 5; +out: + return tid; +} + #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29) /** * @brief This function handles wmm queue select @@ -5587,7 +6299,11 @@ u16 woal_select_queue(struct net_device *dev, struct sk_buff *skb LEAVE(); return index; } +#if defined(STA_CFG80211) || defined(UAP_CFG80211) tid = skb->priority = cfg80211_classify8021d(skb, NULL); +#else + tid = skb->priority = woal_classify8021d(skb); +#endif index = mlan_select_wmm_queue(priv->phandle->pmlan_adapter, priv->bss_index, tid); PRINTM(MDATA, "select queue: tid=%d, index=%d\n", tid, index); @@ -5692,6 +6408,123 @@ void woal_remove_tx_info(moal_private *priv, t_u8 tx_seq_num) LEAVE(); } +/** + * @brief This function flush mcast list + * + * @param priv A pointer to moal_private structure + * + * @return N/A + */ +void woal_flush_mcast_list(moal_private *priv) +{ + struct mcast_node *node = NULL, *tmp_node; + unsigned long flags; + spin_lock_irqsave(&priv->mcast_lock, flags); + list_for_each_entry_safe (node, tmp_node, &priv->mcast_list, link) { + list_del(&node->link); + kfree(node); + } + INIT_LIST_HEAD(&priv->mcast_list); + priv->num_mcast_addr = 0; + spin_unlock_irqrestore(&priv->mcast_lock, flags); +} + +/** + * @brief find mcast node from tx packet + * + * @param priv A pointer to moal_private structure + * @param skb A pointer to skb buffer. + * + * @return N/A + */ +t_u8 woal_find_mcast_node_tx(moal_private *priv, struct sk_buff *skb) +{ + struct mcast_node *node = NULL; + unsigned long flags; + t_u8 ret = MFALSE; + t_u8 ra[MLAN_MAC_ADDR_LENGTH]; + ENTER(); + moal_memcpy_ext(priv->phandle, ra, skb->data, MLAN_MAC_ADDR_LENGTH, + sizeof(ra)); + if (ra[0] & 0x01) { + spin_lock_irqsave(&priv->mcast_lock, flags); + list_for_each_entry (node, &priv->mcast_list, link) { + if (!memcmp(node->mcast_addr, ra, ETH_ALEN)) { + ret = MTRUE; + break; + } + } + spin_unlock_irqrestore(&priv->mcast_lock, flags); + } + LEAVE(); + return ret; +} + +/** + * @brief add mcast node + * + * @param priv A pointer to moal_private structure + * @param peer A point to peer address + * + * @return N/A + */ +t_void woal_add_mcast_node(moal_private *priv, t_u8 *mcast_addr) +{ + struct mcast_node *node = NULL; + unsigned long flags; + t_u8 find_node = MFALSE; + if (priv) { + spin_lock_irqsave(&priv->mcast_lock, flags); + list_for_each_entry (node, &priv->mcast_list, link) { + if (!memcmp(node->mcast_addr, mcast_addr, ETH_ALEN)) { + find_node = MTRUE; + break; + } + } + if (!find_node) { + /* create new mcast node */ + node = kzalloc(sizeof(struct mcast_node), GFP_ATOMIC); + if (node) { + moal_memcpy_ext(priv->phandle, node->mcast_addr, + mcast_addr, ETH_ALEN, ETH_ALEN); + INIT_LIST_HEAD(&node->link); + list_add_tail(&node->link, &priv->mcast_list); + PRINTM(MCMND, + "Add to mcast list: node=" MACSTR "\n", + MAC2STR(mcast_addr)); + } + } + spin_unlock_irqrestore(&priv->mcast_lock, flags); + } +} + +/** + * @brief This function remove mcast node + * + * @param priv A pointer to moal_private structure + * @param mcast_addr mcast address + * + * @return N/A + */ +void woal_remove_mcast_node(moal_private *priv, t_u8 *mcast_addr) +{ + struct mcast_node *node, *tmp = NULL; + unsigned long flags; + ENTER(); + + spin_lock_irqsave(&priv->mcast_lock, flags); + list_for_each_entry_safe (node, tmp, &priv->mcast_list, link) { + if (!memcmp(node->mcast_addr, mcast_addr, ETH_ALEN)) { + list_del(&node->link); + kfree(node); + break; + } + } + spin_unlock_irqrestore(&priv->mcast_lock, flags); + + LEAVE(); +} + #ifdef STA_CFG80211 /** * @brief This function flush tcp session queue @@ -5823,6 +6656,37 @@ static inline struct tcp_sess *woal_get_tcp_sess(moal_private *priv, return NULL; } +#define TCP_SESS_AGEOUT 300 +/** + * @brief This function flush tcp session queue + * + * @param priv A pointer to moal_private structure + * + * @return N/A + */ +static void woal_ageout_tcp_sess_queue(moal_private *priv) +{ + struct tcp_sess *tcp_sess = NULL, *tmp_node; + wifi_timeval t; + struct sk_buff *skb; + woal_get_monotonic_time(&t); + list_for_each_entry_safe (tcp_sess, tmp_node, &priv->tcp_sess_queue, + link) { + if (t.time_sec > + (tcp_sess->update_time.time_sec + TCP_SESS_AGEOUT)) { + PRINTM(MDATA, "wlan: ageout TCP seesion %p\n", + tcp_sess); + list_del(&tcp_sess->link); + if (tcp_sess->is_timer_set) + woal_cancel_timer(&tcp_sess->ack_timer); + skb = (struct sk_buff *)tcp_sess->ack_skb; + if (skb) + dev_kfree_skb_any(skb); + kfree(tcp_sess); + } + } +} + /** * @brief This function send the holding tcp ack packet * re-assoc thread. @@ -6004,6 +6868,9 @@ static int woal_process_tcp_ack(moal_private *priv, mlan_buffer *pmbuf) (__force t_u32)iph->daddr, (__force t_u16)tcph->dest); if (!tcp_session) { + /* check any aging out sessions can be removed */ + woal_ageout_tcp_sess_queue(priv); + tcp_session = kmalloc(sizeof(struct tcp_sess), GFP_ATOMIC); if (!tcp_session) { @@ -6012,6 +6879,10 @@ static int woal_process_tcp_ack(moal_private *priv, mlan_buffer *pmbuf) flags); goto done; } + woal_get_monotonic_time(&tcp_session->update_time); + PRINTM(MDATA, "wlan: create TCP seesion %p\n", + tcp_session); + tcp_session->ack_skb = pmbuf->pdesc; tcp_session->pmbuf = pmbuf; pmbuf->flags |= MLAN_BUF_FLAG_TCP_ACK; @@ -6036,6 +6907,7 @@ static int woal_process_tcp_ack(moal_private *priv, mlan_buffer *pmbuf) LEAVE(); return ret; } else if (!tcp_session->ack_skb) { + woal_get_monotonic_time(&tcp_session->update_time); tcp_session->ack_skb = pmbuf->pdesc; tcp_session->pmbuf = pmbuf; pmbuf->flags |= MLAN_BUF_FLAG_TCP_ACK; @@ -6050,6 +6922,7 @@ static int woal_process_tcp_ack(moal_private *priv, mlan_buffer *pmbuf) LEAVE(); return ret; } + woal_get_monotonic_time(&tcp_session->update_time); ack_seq = ntohl(tcph->ack_seq); skb = (struct sk_buff *)tcp_session->ack_skb; if (likely(ack_seq > tcp_session->ack_seq) && @@ -6072,7 +6945,27 @@ static int woal_process_tcp_ack(moal_private *priv, mlan_buffer *pmbuf) LEAVE(); return ret; } + } else if ((*((t_u8 *)tcph + 13) & 0x11) == 0x11) { + /* TCP ACK + Fin */ + spin_lock_irqsave(&priv->tcp_sess_lock, flags); + tcp_session = woal_get_tcp_sess(priv, (__force t_u32)iph->saddr, + (__force t_u16)tcph->source, + (__force t_u32)iph->daddr, + (__force t_u16)tcph->dest); + if (tcp_session) { + PRINTM(MDATA, "wlan: delete TCP seesion %p\n", + tcp_session); + list_del(&tcp_session->link); + if (tcp_session->is_timer_set) + woal_cancel_timer(&tcp_session->ack_timer); + skb = (struct sk_buff *)tcp_session->ack_skb; + if (skb) + dev_kfree_skb_any(skb); + kfree(tcp_session); + } + spin_unlock_irqrestore(&priv->tcp_sess_lock, flags); } + done: LEAVE(); return ret; @@ -6547,6 +7440,10 @@ void woal_init_priv(moal_private *priv, t_u8 wait_option) priv->cfg_connect = MFALSE; #endif #ifdef STA_SUPPORT +#ifdef STA_CFG80211 + priv->pmk_saved = MFALSE; + memset(&priv->pmk, 0, sizeof(mlan_pmk_t)); +#endif #endif priv->enable_tcp_ack_enh = MTRUE; @@ -6564,7 +7461,8 @@ void woal_init_priv(moal_private *priv, t_u8 wait_option) woal_request_get_fw_info(priv, wait_option, NULL); /* Set MAC address from the insmod command line */ - if (priv->phandle->set_mac_addr) { + if (priv->phandle->set_mac_addr && + priv->bss_type != MLAN_BSS_TYPE_DFS) { memset(priv->current_addr, 0, ETH_ALEN); moal_memcpy_ext(priv->phandle, priv->current_addr, priv->phandle->mac_addr, ETH_ALEN, ETH_ALEN); @@ -6614,7 +7512,9 @@ void woal_init_priv(moal_private *priv, t_u8 wait_option) priv->netdev->name, MAC2STR(priv->current_addr)); } - woal_request_set_mac_address(priv, MOAL_IOCTL_WAIT); + /* ZeroDFS interface doesn't need to set mac address to fw */ + if (priv->bss_type != MLAN_BSS_TYPE_DFS) + woal_request_set_mac_address(priv, MOAL_IOCTL_WAIT); #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) eth_hw_addr_set(priv->netdev, priv->current_addr); #else @@ -6628,7 +7528,8 @@ void woal_init_priv(moal_private *priv, t_u8 wait_option) #endif #ifdef UAP_SUPPORT - priv->trans_chan = 0; + priv->target_chan = 0; + priv->backup_chan = 0; priv->user_cac_period_msec = 0; priv->chan_under_nop = MFALSE; #endif @@ -6661,8 +7562,23 @@ int woal_reset_intf(moal_private *priv, t_u8 wait_option, int all_intf) } handle = priv->phandle; +#if defined(STA_CFG80211) && defined(UAP_CFG80211) + /* Unregister and detach connected radiotap net device */ + if (handle->mon_if) { +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + woal_set_net_monitor(handle->mon_if->priv, wait_option, MFALSE, + 0, NULL); +#endif + netif_device_detach(handle->mon_if->mon_ndev); + if (handle->mon_if->mon_ndev->reg_state == NETREG_REGISTERED) + unregister_netdev(handle->mon_if->mon_ndev); + handle->mon_if = NULL; + } +#endif if (handle->rf_test_mode) woal_process_rf_test_mode(handle, MFG_CMD_UNSET_TEST_MODE); +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) +#endif #ifdef STA_SUPPORT woal_cancel_scan(priv, wait_option); #endif @@ -6952,6 +7868,11 @@ static int woal_get_card_info(moal_handle *phandle) phandle->card_info = &card_info_SD9097; break; #endif +#ifdef SDNW62X + case CARD_TYPE_SDNW62X: + phandle->card_info = &card_info_SDNW62X; + break; +#endif #ifdef SD9177 case CARD_TYPE_SD9177: phandle->card_info = &card_info_SD9177; @@ -6968,6 +7889,11 @@ static int woal_get_card_info(moal_handle *phandle) phandle->card_info = &card_info_PCIE9097; break; #endif +#ifdef PCIENW62X + case CARD_TYPE_PCIENW62X: + phandle->card_info = &card_info_PCIENW62X; + break; +#endif #ifdef PCIE9098 case CARD_TYPE_PCIE9098: phandle->card_info = &card_info_PCIE9098; @@ -6999,6 +7925,11 @@ static int woal_get_card_info(moal_handle *phandle) phandle->card_info = &card_info_USB9097; break; #endif +#ifdef USBNW62X + case CARD_TYPE_USBNW62X: + phandle->card_info = &card_info_USBNW62X; + break; +#endif #ifdef SD8987 case CARD_TYPE_SD8987: phandle->card_info = &card_info_SD8987; @@ -7673,6 +8604,7 @@ t_void woal_send_disconnect_to_system(moal_private *priv, if (priv->bss_type == MLAN_BSS_TYPE_STA) woal_flush_tdls_list(priv); #endif + woal_flush_mcast_list(priv); #ifdef STA_CFG80211 if (priv->bss_type == MLAN_BSS_TYPE_STA && IS_STA_CFG80211(cfg80211_wext)) { @@ -8868,6 +9800,18 @@ t_void woal_evt_work_queue(struct work_struct *work) break; #endif #endif + case WOAL_EVENT_CHAN_RPT: + woal_process_chan_event((moal_private *)evt->priv, + WOAL_EVENT_CHAN_RPT, + evt->radar_info.channel, + evt->radar_info.radar); + break; + case WOAL_EVENT_RADAR: + woal_process_chan_event((moal_private *)evt->priv, + WOAL_EVENT_RADAR, + evt->radar_info.channel, + evt->radar_info.radar); + break; #ifdef UAP_CFG80211 #if KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE case WOAL_EVENT_CANCEL_CHANRPT: @@ -9255,6 +10199,10 @@ moal_handle *woal_add_card(void *card, struct device *dev, moal_if_ops *if_ops, #endif #endif +#ifdef DEBUG_LEVEL1 + drvdbg = handle->params.drvdbg; +#endif + if (handle->params.mac_addr #ifdef MFG_CMD_SUPPORT && handle->params.mfg_mode != MLAN_INIT_PARA_ENABLED @@ -9455,10 +10403,12 @@ moal_handle *woal_add_card(void *card, struct device *dev, moal_if_ops *if_ops, goto err_registerdev; } woal_update_firmware_name(handle); +#ifdef ANDROID_KERNEL #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) wakeup_source_init(&handle->ws, "mwlan"); #else wake_lock_init(&handle->wake_lock, WAKE_LOCK_SUSPEND, "mwlan"); +#endif #endif /* Init FW and HW */ @@ -9494,10 +10444,12 @@ err_init_fw: wait_event_interruptible(handle->init_wait_q, handle->init_wait_q_woken); } +#ifdef ANDROID_KERNEL #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) wakeup_source_trash(&handle->ws); #else wake_lock_destroy(&handle->wake_lock); +#endif #endif /* Unregister device */ PRINTM(MINFO, "unregister device\n"); @@ -9653,6 +10605,16 @@ mlan_status woal_remove_card(void *card) for (i = 0; i < MIN(MLAN_MAX_BSS_NUM, handle->priv_num); i++) woal_remove_interface(handle, i); +#if defined(STA_CFG80211) && defined(UAP_CFG80211) + /* Unregister and detach connected radiotap net device */ + if (handle->mon_if) { + netif_device_detach(handle->mon_if->mon_ndev); + if (handle->mon_if->mon_ndev->reg_state == NETREG_REGISTERED) + unregister_netdev(handle->mon_if->mon_ndev); + handle->mon_if = NULL; + } +#endif + woal_terminate_workqueue(handle); #ifdef UAP_CFG80211 @@ -9689,10 +10651,12 @@ mlan_status woal_remove_card(void *card) /* Unregister device */ PRINTM(MINFO, "unregister device\n"); handle->ops.unregister_dev(handle); +#ifdef ANDROID_KERNEL #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) wakeup_source_trash(&handle->ws); #else wake_lock_destroy(&handle->wake_lock); +#endif #endif /* Free adapter structure */ PRINTM(MINFO, "Free Adapter\n"); @@ -9847,7 +10811,7 @@ static int woal_reset_and_reload_fw(moal_handle *handle, t_u8 mode) goto reload_fw; } if (!IS_SD9098(handle->card_type) && !IS_SD9097(handle->card_type) && - !IS_SD9177(handle->card_type)) { + !IS_SDNW62X(handle->card_type) && !IS_SD9177(handle->card_type)) { mlan_pm_wakeup_card(handle->pmlan_adapter, MTRUE); /** wait SOC fully wake up */ for (tries = 0; tries < FW_POLL_TRIES; ++tries) { @@ -9869,9 +10833,9 @@ static int woal_reset_and_reload_fw(moal_handle *handle, t_u8 mode) ret = -EFAULT; goto done; } -#if defined(SD9098) || defined(SD9097) || defined(SD9177) +#if defined(SD9098) || defined(SD9097) || defined(SDNW62X) || defined(SD9177) if (IS_SD9098(handle->card_type) || IS_SD9097(handle->card_type) || - IS_SD9177(handle->card_type)) + IS_SDNW62X(handle->card_type) || IS_SD9177(handle->card_type)) handle->ops.write_reg(handle, 0x00, 0x10); #endif /* Poll register around 100 ms */ @@ -9890,7 +10854,7 @@ static int woal_reset_and_reload_fw(moal_handle *handle, t_u8 mode) goto done; } if (!IS_SD9098(handle->card_type) && !IS_SD9097(handle->card_type) && - !IS_SD9177(handle->card_type)) + !IS_SDNW62X(handle->card_type) && !IS_SD9177(handle->card_type)) mlan_pm_wakeup_card(handle->pmlan_adapter, MFALSE); reload_fw: /* Download FW */ @@ -10307,22 +11271,28 @@ static int woal_init_module(void) #endif MLAN_INIT_WORK(&hang_work, woal_hang_work_queue); - /* Create workqueue for hang process */ + if (reg_work) { + /* Create workqueue for hang process */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) - /* For kernel less than 2.6.14 name can not be greater than 10 - characters */ - register_workqueue = create_workqueue("MOAL_REGISTER_WORKQ"); + /* For kernel less than 2.6.14 name can not be greater than 10 + characters */ + register_workqueue = create_workqueue("MOAL_REGISTER_WORKQ"); #else #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) - register_workqueue = - alloc_workqueue("MOAL_REGISTER_WORK_QUEUE", - WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND, 1); + register_workqueue = alloc_workqueue( + "MOAL_REGISTER_WORK_QUEUE", + WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND, 1); #else - register_workqueue = create_workqueue("MOAL_REGISTER_WORK_QUEUE"); + register_workqueue = + create_workqueue("MOAL_REGISTER_WORK_QUEUE"); #endif #endif - MLAN_INIT_WORK(®ister_work, woal_bus_register); - queue_work(register_workqueue, ®ister_work); + + MLAN_INIT_WORK(®ister_work, woal_bus_register); + queue_work(register_workqueue, ®ister_work); + } else { + woal_bus_register(NULL); + } PRINTM(MMSG, "wlan: Driver loaded successfully\n"); LEAVE(); return ret; @@ -10380,8 +11350,33 @@ static void woal_cleanup_module(void) if (handle->rf_test_mode) woal_process_rf_test_mode(handle, MFG_CMD_UNSET_TEST_MODE); +#if defined(STA_CFG80211) && defined(UAP_CFG80211) + /* Unregister all connected radiotap net devices */ + if (handle->mon_if) { +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + woal_set_net_monitor(handle->mon_if->priv, + MOAL_IOCTL_WAIT, MFALSE, 0, NULL); + if (handle->ioctl_timeout) { + woal_ioctl_timeout(handle); + goto exit; + } +#endif + netif_device_detach(handle->mon_if->mon_ndev); + if (handle->mon_if->mon_ndev->reg_state == + NETREG_REGISTERED) + unregister_netdev(handle->mon_if->mon_ndev); + handle->mon_if = NULL; + } +#endif for (i = 0; i < handle->priv_num; i++) { + /** cancel dfs monitor on deinit */ + if (handle->priv[i] && + handle->priv[i]->bss_type == MLAN_BSS_TYPE_DFS) { + woal_11h_cancel_chan_report_ioctl( + handle->priv[i], MOAL_IOCTL_WAIT); + continue; + } #ifdef STA_SUPPORT if (GET_BSS_ROLE(handle->priv[i]) == MLAN_BSS_ROLE_STA) { @@ -10505,7 +11500,7 @@ exit_sem_err: destroy_workqueue(hang_workqueue); hang_workqueue = NULL; } - if (register_workqueue) { + if (reg_work && register_workqueue) { flush_workqueue(register_workqueue); destroy_workqueue(register_workqueue); register_workqueue = NULL; @@ -10540,6 +11535,11 @@ __setup("mfg_mode=", mfg_mode_setup); module_init(woal_init_module); module_exit(woal_cleanup_module); +module_param(reg_work, int, 0); +MODULE_PARM_DESC( + reg_work, + "0: disable register work_queue; 1: enable register work_queue"); + MODULE_DESCRIPTION("M-WLAN Driver"); MODULE_AUTHOR("NXP"); MODULE_VERSION(MLAN_RELEASE_VERSION); diff --git a/mxm_wifiex/wlan_src/mlinux/moal_main.h b/mxm_wifiex/wlan_src/mlinux/moal_main.h index ad6eb2d..08a5839 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_main.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_main.h @@ -3,7 +3,7 @@ * @brief This file contains wlan driver specific defines etc. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -104,12 +104,16 @@ Change log: #include +#ifdef ANDROID_KERNEL #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) #include #include #else #include #endif +#endif + +#include #include "mlan.h" #include "moal_shim.h" @@ -217,6 +221,7 @@ Change log: #define default_nan_name "nan%d" #define default_mpl_name "mpl%d" #define default_11p_name "ocb%d" +#define default_dfs_name "dfs%d" #define mwiphy_name "mwiphy%d" /** country txpower mode */ @@ -315,6 +320,8 @@ typedef enum _MOAL_HARDWARE_STATUS { /** fw cap info 11p */ #define FW_CAPINFO_80211P MBIT(24) +/** fw cap info bit26 for 0-DFS support */ +#define FW_CAPINFO_ZERO_DFS MBIT(31) /** fw cap info disable nan */ #define FW_CAPINFO_DISABLE_NAN MBIT(29) /** fw cap info BGA */ @@ -704,10 +711,12 @@ out: /* IOCTL Timeout */ #define MOAL_IOCTL_TIMEOUT (20 * HZ) +#ifdef ANDROID_KERNEL /** Wake lock timeout in msec */ #define WAKE_LOCK_TIMEOUT 3000 /** Roaming Wake lock timeout in msec */ #define ROAMING_WAKE_LOCK_TIMEOUT 10000 +#endif /** Threshold value of number of times the Tx timeout happened */ /* WAR For EDMAC Test */ @@ -796,6 +805,15 @@ typedef enum { RESERVED // Others: reserved } HSWakeupReason_t; +/** Custom event : Radar Detected */ +#define CUS_EVT_RADAR_DETECTED "EVENT=RADAR_DETECTED" +/** Custom event : CAC finished */ +#define CUS_EVT_CAC_FINISHED "EVENT=CAC_FINISHED" +void woal_move_to_next_channel(moal_private *priv); +void woal_chan_event(moal_private *priv, t_u8 type, t_u8 channel, t_u8 radar); +void woal_process_chan_event(moal_private *priv, t_u8 type, t_u8 channel, + t_u8 radar); + /** Custom event : WEP ICV error */ #define CUS_EVT_WEP_ICV_ERR "EVENT=WEP_ICV_ERR" @@ -815,6 +833,8 @@ typedef enum { #endif #define FW_DEBUG_INFO "EVENT=FW_DEBUG_INFO" +#define CUS_EVT_CSI "EVENT=MLAN_CSI" + /** 10 seconds */ #define MOAL_TIMER_10S 10000 /** 5 seconds */ @@ -960,6 +980,13 @@ typedef struct _wait_queue { #endif #endif /* WIFI_DIRECT_SUPPORT */ +/**Driver mode 0DFS bit**/ +#define DRV_MODE_DFS MBIT(7) +/**Maxinmum DFS BSS**/ +#define MAX_DFS_BSS 1 +/**Default DFS BSS**/ +#define DEF_DFS_BSS 1 + #define DRV_MODE_WLAN (MBIT(0) | MBIT(1) | MBIT(2) | MBIT(3) | MBIT(4)) /** @@ -1046,6 +1073,8 @@ struct tcp_sess { moal_drv_timer ack_timer __ATTRIB_ALIGN__; /** timer is set */ BOOLEAN is_timer_set; + /** last update time*/ + wifi_timeval update_time; }; struct tx_status_info { @@ -1071,6 +1100,8 @@ enum woal_event_type { WOAL_EVENT_ASSOC_RESP, #endif #endif + WOAL_EVENT_CHAN_RPT, + WOAL_EVENT_RADAR, #ifdef UAP_CFG80211 #if KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE WOAL_EVENT_CANCEL_CHANRPT, @@ -1078,6 +1109,14 @@ enum woal_event_type { #endif }; +/** chan_rpt_info */ +typedef struct _chan_radar_info { + /** channel */ + t_u8 channel; + /** radar */ + t_u8 radar; +} chan_radar_info; + typedef struct _woal_evt_buf { /** Event len */ t_u16 event_len; @@ -1098,6 +1137,7 @@ struct woal_event { woal_evt_buf evt; mlan_ds_assoc_info assoc_info; int reason_code; + chan_radar_info radar_info; }; }; @@ -1184,6 +1224,13 @@ struct tdls_peer { t_u8 num_failure; }; +/** mcast node */ +struct mcast_node { + struct list_head link; + /** mcast address information */ + t_u8 mcast_addr[ETH_ALEN]; +}; + struct rf_test_mode_data { /* tx antenna num */ t_u32 tx_antenna; @@ -1256,6 +1303,30 @@ enum ring_id { RING_ID_MAX, }; +#define AUTO_DFS_ENABLE 0x1 +#define AUTO_DFS_DISABLE 0x0 +#define MAX_DFS_CHAN_LIST 16 + +/** Auto Zero DFS config structure */ +typedef struct _auto_zero_dfs_cfg { + /** 1: start 0: stop */ + t_u8 start_auto_zero_dfs; + /** start channel for ZeroDFS */ + t_u8 cac_start_chan; + /** cac timer */ + t_u32 cac_timer; + /** bw: 0: 20MHz 1: 40Mz above 3: 40MHz below 4: Bandwidth 80MHz */ + t_u8 bw; + /** enable uap chan switch after first CAC finished*/ + t_u8 uap_chan_switch; + /** enable auto zero dfs */ + t_u8 multi_chan_dfs; + /** num of chan */ + t_u8 num_of_chan; + /** dfs channel list */ + t_u8 dfs_chan_list[MAX_DFS_CHAN_LIST]; +} __ATTRIB_PACK__ auto_zero_dfs_cfg; + /** Private structure for MOAL */ struct _moal_private { /** Handle structure */ @@ -1291,8 +1362,10 @@ struct _moal_private { BOOLEAN bss_started; /** host based uap flag */ BOOLEAN uap_host_based; - /** transition channel */ - t_u8 trans_chan; + /** target channel */ + t_u8 target_chan; + /** backup channel */ + t_u8 backup_chan; /** uAP skip CAC*/ BOOLEAN skip_cac; /** tx block flag */ @@ -1301,6 +1374,14 @@ struct _moal_private { t_u32 user_cac_period_msec; /** channel under nop */ BOOLEAN chan_under_nop; + /** chan_rpt_req on Zero DFS interface */ + mlan_ds_11h_chan_rep_req chan_rpt_req; + /** chan_rpt pending */ + t_u8 chan_rpt_pending; + /** auto dfs cfg */ + auto_zero_dfs_cfg auto_dfs_cfg; + /** index of cac */ + int curr_cac_idx; #ifdef UAP_CFG80211 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) /** current working channel */ @@ -1396,6 +1477,10 @@ struct _moal_private { /** cipher */ t_u32 cipher; #endif + /** pmk saved flag */ + t_u8 pmk_saved; + /** pmk */ + mlan_pmk_t pmk; /** beacon ie index */ t_u16 beacon_index; /** proberesp ie index */ @@ -1544,6 +1629,14 @@ struct _moal_private { t_u8 tcp_ack_max_hold; /** TCP session spin lock */ spinlock_t tcp_sess_lock; + /** mcast spin lock */ + spinlock_t mcast_lock; + /** mcast list */ + struct list_head mcast_list; + /** num_mcast_addr */ + t_u32 num_mcast_addr; + /** enable mc_aggr */ + t_u8 enable_mc_aggr; /** tcp list */ struct list_head tdls_list; /** tdls spin lock */ @@ -1572,6 +1665,17 @@ struct _moal_private { mlan_ds_misc_gtk_rekey_data gtk_rekey_data; dot11_protocol tx_protocols; dot11_protocol rx_protocols; + t_u16 csi_seq; + /** 0-disable, 1-enable */ + t_u16 csi_enable; + /** default-ASCII, 1-binary */ + t_u8 csi_dump_format; + /** total length of csi dump */ + t_u32 csi_dump_len; + /** path name of csi dump */ + char csi_dump_path[64]; + /** CSI config */ + mlan_ds_csi_params csi_config; #if defined(DRV_EMBEDDED_AUTHENTICATOR) || defined(DRV_EMBEDDED_SUPPLICANT) /** hostcmd_wait_q */ wait_queue_head_t hostcmd_wait_q __ATTRIB_ALIGN__; @@ -1648,13 +1752,240 @@ typedef struct _card_info { t_u32 slew_rate_reg; t_u8 slew_rate_bit_offset; #endif + t_u8 sniffer_support; t_u8 per_pkt_cfg_support; } card_info; +/** channel_field.flags */ +#define CHANNEL_FLAGS_TURBO 0x0010 +#define CHANNEL_FLAGS_CCK 0x0020 +#define CHANNEL_FLAGS_OFDM 0x0040 +#define CHANNEL_FLAGS_2GHZ 0x0080 +#define CHANNEL_FLAGS_5GHZ 0x0100 +#define CHANNEL_FLAGS_ONLY_PASSIVSCAN_ALLOW 0x0200 +#define CHANNEL_FLAGS_DYNAMIC_CCK_OFDM 0x0400 +#define CHANNEL_FLAGS_GFSK 0x0800 +struct channel_field { + /** frequency */ + t_u16 frequency; + /** flags */ + t_u16 flags; +} __packed; + +/** mcs_field.known */ +#define MCS_KNOWN_BANDWIDTH 0x01 +#define MCS_KNOWN_MCS_INDEX_KNOWN 0x02 +#define MCS_KNOWN_GUARD_INTERVAL 0x04 +#define MCS_KNOWN_HT_FORMAT 0x08 +#define MCS_KNOWN_FEC_TYPE 0x10 +#define MCS_KNOWN_STBC_KNOWN 0x20 +#define MCS_KNOWN_NESS_KNOWN 0x40 +#define MCS_KNOWN_NESS_DATA 0x80 +/** bandwidth */ +#define RX_BW_20 0 +#define RX_BW_40 1 +#define RX_BW_20L 2 +#define RX_BW_20U 3 +#define RX_BW_80 4 +/** mcs_field.flags +The flags field is any combination of the following: +0x03 bandwidth - 0: 20, 1: 40, 2: 20L, 3: 20U +0x04 guard interval - 0: long GI, 1: short GI +0x08 HT format - 0: mixed, 1: greenfield +0x10 FEC type - 0: BCC, 1: LDPC +0x60 Number of STBC streams +0x80 Ness - bit 0 (LSB) of Number of extension spatial streams */ +struct mcs_field { + /** known */ + t_u8 known; + /** flags */ + t_u8 flags; + /** mcs */ + t_u8 mcs; +} __packed; + +/** vht_field.known */ +#define VHT_KNOWN_STBC 0x0001 +#define VHT_KNOWN_TXOP_PS_NA 0x0002 +#define VHT_KNOWN_GI 0x0004 +#define VHT_KNOWN_SGI_NSYM_DIS 0x0008 +#define VHT_KNOWN_LDPC_EXTRA_OFDM_SYM 0x0010 +#define VHT_KNOWN_BEAMFORMED 0x0020 +#define VHT_KNOWN_BANDWIDTH 0x0040 +#define VHT_KNOWN_GROUP_ID 0x0080 +#define VHT_KNOWN_PARTIAL_AID 0x0100 + +/** vht_field.flags */ +#define VHT_FLAG_STBC 0x01 +#define VHT_FLAG_TXOP_PS_NA 0x02 +#define VHT_FLAG_SGI 0x04 +#define VHT_FLAG_SGI_NSYM_M10_9 0x08 +#define VHT_FLAG_LDPC_EXTRA_OFDM_SYM 0x10 +#define VHT_FLAG_BEAMFORMED 0x20 + +/** vht_field.coding */ +#define VHT_CODING_LDPC_USER0 0x01 +#define VHT_CODING_LDPC_USER1 0x02 +#define VHT_CODING_LDPC_USER2 0x04 +#define VHT_CODING_LDPC_USER3 0x08 + +/** vht_field */ +struct vht_field { + /** pad: for vht field require 2 bytes alignment */ + t_u8 pad; + /** known */ + t_u16 known; + /** flags */ + t_u8 flags; + /** bandwidth */ + t_u8 bandwidth; + /** mcs_nss for up to 4 users */ + t_u8 mcs_nss[4]; + /** coding for up to 4 users */ + t_u8 coding; + /** group_id */ + t_u8 group_id; + /** partial_aid */ + t_u16 partial_aid; +} __packed; + +/** radiotap_body.flags */ +#define RADIOTAP_FLAGS_DURING_CFG 0x01 +#define RADIOTAP_FLAGS_SHORT_PREAMBLE 0x02 +#define RADIOTAP_FLAGS_WEP_ENCRYPTION 0x04 +#define RADIOTAP_FLAGS_WITH_FRAGMENT 0x08 +#define RADIOTAP_FLAGS_INCLUDE_FCS 0x10 +#define RADIOTAP_FLAGS_PAD_BTW_HEADER_PAYLOAD 0x20 +#define RADIOTAP_FLAGS_FAILED_FCS_CHECK 0x40 +#define RADIOTAP_FLAGS_USE_SGI_HT 0x80 +struct radiotap_body { + /** timestamp */ + t_u64 timestamp; + /** flags */ + t_u8 flags; + /** rate for LG pkt, RATE flag will be present, it shows datarate in + * 500Kbps. For HT/VHT pkt, RATE flag will not be present, it is not + * used. */ + t_u8 rate; + /** channel */ + struct channel_field channel; + /** antenna_signal */ + t_s8 antenna_signal; + /** antenna_noise */ + t_s8 antenna_noise; + /** antenna */ + t_u8 antenna; + /** union for HT/VHT pkt */ + union { + /** mcs field */ + struct mcs_field mcs; + /** vht field */ + struct vht_field vht; + } u; +} __packed; + +struct radiotap_header { + struct ieee80211_radiotap_header hdr; + struct radiotap_body body; +} __packed; + +/** Roam offload config parameters */ +typedef struct woal_priv_fw_roam_offload_cfg { + /* User set passphrase*/ + t_u8 userset_passphrase; + /* BSSID for fw roaming/auto_reconnect*/ + t_u8 bssid[MLAN_MAC_ADDR_LENGTH]; + /* Retry_count for fw roaming/auto_reconnect*/ + t_u8 retry_count; + /* Condition to trigger roaming + * Bit0 : RSSI low trigger + * Bit1 : Pre-beacon lost trigger + * Bit2 : Link Lost trigger + * Bit3 : Deauth by ext-AP trigger + * Bit4 ~ Bit15 : Reserved + * value 0 : no trigger + * value 0xff : invalid + */ + t_u16 trigger_condition; + /* SSID List(White list)*/ + mlan_ds_misc_ssid_list ssid_list; + /* Black list(BSSID list)*/ + mlan_ds_misc_roam_offload_aplist black_list; + + /* RSSI paramters set flag*/ + t_u8 rssi_param_set_flag; + /* MAX_RSSI for fw roaming*/ + t_u8 max_rssi; + /* MIN_RSSI for fw roaming*/ + t_u8 min_rssi; + /* Step_RSSI for fw roaming*/ + t_u8 step_rssi; + + /* BAND and RSSI_HYSTERESIS set flag*/ + t_u8 band_rssi_flag; + mlan_ds_misc_band_rssi band_rssi; + + /* BGSCAN params set flag*/ + t_u8 bgscan_set_flag; + mlan_ds_misc_bgscan_cfg bgscan_cfg; + + /* EES mode params set flag*/ + t_u8 ees_param_set_flag; + mlan_ds_misc_ees_cfg ees_cfg; + + /* Beacon miss threshold*/ + t_u8 bcn_miss_threshold; + + /* Beacon miss threshold*/ + t_u8 pre_bcn_miss_threshold; + + /* scan repeat count*/ + t_u16 repeat_count; +} woal_roam_offload_cfg; +#ifdef STA_CFG80211 +int woal_set_clear_pmk(moal_private *priv, t_u8 action); +#endif +mlan_status woal_config_fw_roaming(moal_private *priv, t_u8 cfg_mode, + woal_roam_offload_cfg *roam_offload_cfg); +int woal_enable_fw_roaming(moal_private *priv, int data); + #define GTK_REKEY_OFFLOAD_DISABLE 0 #define GTK_REKEY_OFFLOAD_ENABLE 1 #define GTK_REKEY_OFFLOAD_SUSPEND 2 +/** Monitor Band Channel Config */ +typedef struct _netmon_band_chan_cfg { + t_u32 band; + t_u32 channel; + t_u32 chan_bandwidth; +} netmon_band_chan_cfg; + +#if defined(STA_CFG80211) && defined(UAP_CFG80211) +typedef struct _monitor_iface { + /* The priv data of interface on which the monitor iface is based */ + moal_private *priv; + struct wireless_dev wdev; + /** 0 - Disabled + * 1 - Channel Specified sniffer mode + * 2 - In-Channel sniffer mode + */ + int sniffer_mode; + int radiotap_enabled; + /* The net_device on which the monitor iface is based. */ + struct net_device *base_ndev; + struct net_device *mon_ndev; + char ifname[IFNAMSIZ]; + int flag; +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + struct cfg80211_chan_def chandef; +#endif + /** Netmon Band Channel Config */ + netmon_band_chan_cfg band_chan_cfg; + /** Monitor device statistics structure */ + struct net_device_stats stats; +} monitor_iface; +#endif + #define MAX_KEEP_ALIVE_ID 4 /** Operation data structure for MOAL bus interfaces */ @@ -1712,6 +2043,7 @@ enum ext_mod_params { EXT_COUNTRY_IE_IGNORE, EXT_BEACON_HINTS, #endif + EXT_ROAMOFFLOAD_IN_HS, #ifdef STA_CFG80211 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) EXT_HOST_MLME, @@ -1721,6 +2053,7 @@ enum ext_mod_params { EXT_RPS, EXT_TX_SKB_CLONE, EXT_PMQOS, + EXT_CHAN_TRACK, EXT_MAX_PARAM, }; @@ -1794,15 +2127,11 @@ typedef struct _moal_mod_para { int pcie_int_mode; int ring_size; #endif /* PCIE */ +#ifdef ANDROID_KERNEL int wakelock_timeout; - unsigned int dev_cap_mask; -#if defined(SD8997) || defined(PCIE8997) || defined(USB8997) || \ - defined(SD8977) || defined(SD8987) || defined(SD9098) || \ - defined(USB9098) || defined(PCIE9098) || defined(SD9097) || \ - defined(USB9097) || defined(PCIE9097) || defined(SD8978) || \ - defined(SD9177) - int pmic; #endif + unsigned int dev_cap_mask; + int pmic; int antcfg; unsigned int uap_oper_ctrl; int hs_wake_interval; @@ -1898,6 +2227,11 @@ struct _moal_handle { /** Bss attr */ moal_drv_mode drv_mode; +#if defined(STA_CFG80211) && defined(UAP_CFG80211) + /** Monitor interface */ + monitor_iface *mon_if; +#endif + /** set mac address flag */ t_u8 set_mac_addr; /** MAC address */ @@ -1939,8 +2273,25 @@ struct _moal_handle { t_u32 fw_release_number; /** Firmware Hotfix version */ t_u8 fw_hotfix_version; + /** Firmware support bands */ + t_u16 fw_bands; /** ECSA support */ t_u8 fw_ecsa_enable; + /** FW ROAMING support */ + t_u8 fw_roam_enable; + /** FW ROAMING capability in fw */ + t_u8 fw_roaming_support; + /** Retry count for auto reconnect based on FW ROAMING*/ + t_u16 auto_reconnect_retry_count; + /** The SSID for auto reconnect FW ROAMING*/ + mlan_802_11_ssid auto_reconnect_ssid; + /** The BSSID for auto reconnect FW ROAMING*/ + mlan_802_11_mac_addr auto_reconnect_bssid; + /** The parameters for FW ROAMING*/ + woal_roam_offload_cfg fw_roam_params; + /** The keys for FW ROAMING*/ + mlan_ds_passphrase ssid_passphrase[MAX_SEC_SSID_NUM]; + /** Getlog support */ t_u8 fw_getlog_enable; /** Init wait queue token */ @@ -2045,6 +2396,8 @@ struct _moal_handle { struct wiphy *wiphy; /** Country code for regulatory domain */ t_u8 country_code[COUNTRY_CODE_LEN]; + /** dfs_region */ + t_u8 dfs_region; #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) /** regulatory work */ struct work_struct regulatory_work; @@ -2215,10 +2568,12 @@ struct _moal_handle { /** Card specific driver version */ t_s8 driver_version[MLAN_MAX_VER_STR_LEN]; char *fwdump_fname; +#ifdef ANDROID_KERNEL #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) struct wakeup_source ws; #else struct wake_lock wake_lock; +#endif #endif t_u16 dfs_repeater_mode; /* feature_control */ @@ -2270,11 +2625,7 @@ struct _moal_handle { t_u8 request_pm; #ifdef IMX_SUPPORT -#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 6, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) - struct dev_pm_qos_request woal_pm_qos_req; -#endif -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) struct pm_qos_request woal_pm_qos_req; #endif #endif @@ -2632,20 +2983,6 @@ static inline void hexdump(t_u32 level, char *prompt, t_u8 *buf, int len) } while (0) #endif -#ifdef BIG_ENDIAN_SUPPORT -/** Convert from 16 bit little endian format to CPU format */ -#define woal_le16_to_cpu(x) le16_to_cpu(x) -/** Convert from 32 bit little endian format to CPU format */ -#define woal_le32_to_cpu(x) le32_to_cpu(x) -/** Convert from 64 bit little endian format to CPU format */ -#define woal_le64_to_cpu(x) le64_to_cpu(x) -/** Convert to 16 bit little endian format from CPU format */ -#define woal_cpu_to_le16(x) cpu_to_le16(x) -/** Convert to 32 bit little endian format from CPU format */ -#define woal_cpu_to_le32(x) cpu_to_le32(x) -/** Convert to 64 bit little endian format from CPU format */ -#define woal_cpu_to_le64(x) cpu_to_le64(x) -#else /** Do nothing */ #define woal_le16_to_cpu(x) x /** Do nothing */ @@ -2658,7 +2995,6 @@ static inline void hexdump(t_u32 level, char *prompt, t_u8 *buf, int len) #define woal_cpu_to_le32(x) x /** Do nothing */ #define woal_cpu_to_le64(x) x -#endif /** * @brief This function returns first available priv @@ -2724,6 +3060,18 @@ static inline moal_private *woal_get_vir_priv_bss_type(moal_handle *handle, } #if defined(STA_CFG80211) || defined(UAP_CFG80211) +/** get any cfg80211 priv */ +static inline moal_private *woal_get_priv_with_wdev(moal_handle *handle) +{ + int i; + for (i = 0; i < MIN(handle->priv_num, MLAN_MAX_BSS_NUM); i++) { + if (handle->priv[i]) { + if (handle->priv[i]->wdev) + return handle->priv[i]; + } + } + return NULL; +} #endif static inline void woal_get_monotonic_time(wifi_timeval *tv) @@ -2884,6 +3232,7 @@ void woal_free_moal_handle(moal_handle *handle); /** shutdown fw */ mlan_status woal_shutdown_fw(moal_private *priv, t_u8 wait_option); /* Functions in interface module */ +#ifdef ANDROID_KERNEL #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) static inline void wakeup_source_init(struct wakeup_source *ws, const char *name) @@ -2913,6 +3262,7 @@ static inline void wakeup_source_trash(struct wakeup_source *ws) LEAVE(); } #endif +#endif /** Add card */ moal_handle *woal_add_card(void *card, struct device *dev, moal_if_ops *if_ops, t_u16 card_type); @@ -3283,6 +3633,9 @@ moal_private *woal_add_interface(moal_handle *handle, t_u8 bss_num, void woal_remove_interface(moal_handle *handle, t_u8 bss_index); void woal_set_multicast_list(struct net_device *dev); mlan_status woal_request_fw(moal_handle *handle); +mlan_status woal_ioctl_aggr_prio_tbl(moal_private *priv, t_u32 action, + mlan_ds_11n_aggr_prio_tbl *aggr_prio_tbl); + int woal_11h_channel_check_ioctl(moal_private *priv, t_u8 wait_option); void woal_cancel_cac_block(moal_private *priv); void woal_moal_debug_info(moal_private *priv, moal_handle *handle, u8 flag); @@ -3354,12 +3707,18 @@ void woal_flush_tx_stat_queue(moal_private *priv); struct tx_status_info *woal_get_tx_info(moal_private *priv, t_u8 tx_seq_num); void woal_remove_tx_info(moal_private *priv, t_u8 tx_seq_num); +void woal_flush_mcast_list(moal_private *priv); +t_void woal_add_mcast_node(moal_private *priv, t_u8 *mcast_addr); +void woal_remove_mcast_node(moal_private *priv, t_u8 *mcast_addr); +t_u8 woal_find_mcast_node_tx(moal_private *priv, struct sk_buff *skb); + mlan_status woal_request_country_power_table(moal_private *priv, char *region); #ifdef RX_PACKET_COALESCE mlan_status woal_rx_pkt_coalesce_cfg(moal_private *priv, t_u16 *enable, t_u8 wait_option, t_u8 action); #endif mlan_status woal_set_low_pwr_mode(moal_handle *handle, t_u8 wait_option); +mlan_status woal_set_chan_track_mode(moal_handle *handle, t_u8 wait_option); int woal_hexval(char chr); mlan_status woal_pmic_configure(moal_handle *handle, t_u8 wait_option); mlan_status woal_set_user_antcfg(moal_handle *handle, t_u8 wait_option); @@ -3375,6 +3734,11 @@ mlan_status woal_set_get_wowlan_config(moal_private *priv, t_u16 action, t_u8 wait_option, mlan_ds_misc_mef_flt_cfg *mefcfg); mlan_status woal_set_auto_arp_ext(moal_handle *handle, t_u8 enable); +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) +mlan_status woal_set_net_monitor(moal_private *priv, t_u8 wait_option, + t_u8 enable, t_u8 filter, + netmon_band_chan_cfg *band_chan_cfg); +#endif mlan_status woal_delba_all(moal_private *priv, t_u8 wait_option); #ifdef STA_CFG80211 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) @@ -3397,6 +3761,12 @@ mlan_status woal_set_wacp_mode(moal_private *priv, t_u8 wait_option); #endif mlan_status woal_init_aggr_ctrl(moal_handle *handle, t_u8 wait_option); +#if defined(STA_CFG80211) && defined(UAP_CFG80211) +monitor_iface *woal_prepare_mon_if(moal_private *priv, const char *name, + unsigned char name_assign_type, + int sniffer_mode); +#endif + #if defined(STA_CFG80211) || defined(UAP_CFG80211) void woal_cfg80211_vendor_event_fw_dump(moal_private *priv); #endif diff --git a/mxm_wifiex/wlan_src/mlinux/moal_pcie.c b/mxm_wifiex/wlan_src/mlinux/moal_pcie.c index 0c29b21..23e98b1 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_pcie.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_pcie.c @@ -4,7 +4,7 @@ * related functions. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -56,8 +56,8 @@ static mlan_status woal_pcie_init(pcie_service_card *card); static const struct pci_device_id wlan_ids[] = { #ifdef PCIE8897 { - PCIE_VENDOR_ID_NXP, - PCIE_DEVICE_ID_NXP_88W8897P, + PCIE_VENDOR_ID_MRVL, + PCIE_DEVICE_ID_88W8897P, PCI_ANY_ID, PCI_ANY_ID, 0, @@ -66,16 +66,16 @@ static const struct pci_device_id wlan_ids[] = { #endif #ifdef PCIE8997 { - PCIE_VENDOR_ID_NXP, - PCIE_DEVICE_ID_NXP_88W8997P, + PCIE_VENDOR_ID_MRVL, + PCIE_DEVICE_ID_88W8997P, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, { - PCIE_VENDOR_ID_V2_NXP, - PCIE_DEVICE_ID_NXP_88W8997P, + PCIE_VENDOR_ID_V2_MRVL, + PCIE_DEVICE_ID_88W8997P, PCI_ANY_ID, PCI_ANY_ID, 0, @@ -84,8 +84,8 @@ static const struct pci_device_id wlan_ids[] = { #endif #ifdef PCIE9097 { - PCIE_VENDOR_ID_V2_NXP, - PCIE_DEVICE_ID_NXP_88W9097, + PCIE_VENDOR_ID_V2_MRVL, + PCIE_DEVICE_ID_88W9097, PCI_ANY_ID, PCI_ANY_ID, 0, @@ -94,22 +94,33 @@ static const struct pci_device_id wlan_ids[] = { #endif #ifdef PCIE9098 { - PCIE_VENDOR_ID_V2_NXP, - PCIE_DEVICE_ID_NXP_88W9098P_FN0, + PCIE_VENDOR_ID_V2_MRVL, + PCIE_DEVICE_ID_88W9098P_FN0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, { - PCIE_VENDOR_ID_V2_NXP, - PCIE_DEVICE_ID_NXP_88W9098P_FN1, + PCIE_VENDOR_ID_V2_MRVL, + PCIE_DEVICE_ID_88W9098P_FN1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, #endif +#ifdef PCIENW62X + { + PCIE_VENDOR_ID_NXP, + PCIE_DEVICE_ID_88WNW62X, + PCI_ANY_ID, + PCI_ANY_ID, + 0, + 0, + }, +#endif + {}, }; /* moal interface ops */ @@ -139,7 +150,7 @@ static t_u16 woal_update_card_type(t_void *card) /* Update card type */ #ifdef PCIE8897 - if (cardp_pcie->dev->device == PCIE_DEVICE_ID_NXP_88W8897P) { + if (cardp_pcie->dev->device == PCIE_DEVICE_ID_88W8897P) { card_type = CARD_TYPE_PCIE8897; moal_memcpy_ext(NULL, driver_version, CARD_PCIE8897, strlen(CARD_PCIE8897), strlen(driver_version)); @@ -152,7 +163,7 @@ static t_u16 woal_update_card_type(t_void *card) } #endif #ifdef PCIE8997 - if (cardp_pcie->dev->device == PCIE_DEVICE_ID_NXP_88W8997P) { + if (cardp_pcie->dev->device == PCIE_DEVICE_ID_88W8997P) { card_type = CARD_TYPE_PCIE8997; moal_memcpy_ext(NULL, driver_version, CARD_PCIE8997, strlen(CARD_PCIE8997), strlen(driver_version)); @@ -165,10 +176,10 @@ static t_u16 woal_update_card_type(t_void *card) } #endif #ifdef PCIE9097 - if (cardp_pcie->dev->device == PCIE_DEVICE_ID_NXP_88W9097) { + if (cardp_pcie->dev->device == PCIE_DEVICE_ID_88W9097) { card_type = CARD_TYPE_PCIE9097; - moal_memcpy_ext(NULL, driver_version, CARD_PCIEIW620, - strlen(CARD_PCIEIW620), strlen(driver_version)); + moal_memcpy_ext(NULL, driver_version, CARD_PCIE9097, + strlen(CARD_PCIE9097), strlen(driver_version)); moal_memcpy_ext(NULL, driver_version + strlen(INTF_CARDTYPE) + strlen(KERN_VERSION), @@ -178,8 +189,8 @@ static t_u16 woal_update_card_type(t_void *card) } #endif #ifdef PCIE9098 - if (cardp_pcie->dev->device == PCIE_DEVICE_ID_NXP_88W9098P_FN0 || - cardp_pcie->dev->device == PCIE_DEVICE_ID_NXP_88W9098P_FN1) { + if (cardp_pcie->dev->device == PCIE_DEVICE_ID_88W9098P_FN0 || + cardp_pcie->dev->device == PCIE_DEVICE_ID_88W9098P_FN1) { card_type = CARD_TYPE_PCIE9098; moal_memcpy_ext(NULL, driver_version, CARD_PCIE9098, strlen(CARD_PCIE9098), strlen(driver_version)); @@ -191,6 +202,20 @@ static t_u16 woal_update_card_type(t_void *card) strlen(KERN_VERSION)); } #endif +#ifdef PCIENW62X + if (cardp_pcie->dev->device == PCIE_DEVICE_ID_88WNW62X) { + card_type = CARD_TYPE_PCIENW62X; + moal_memcpy_ext(NULL, driver_version, CARD_PCIENW62X, + strlen(CARD_PCIENW62X), strlen(driver_version)); + moal_memcpy_ext(NULL, + driver_version + strlen(INTF_CARDTYPE) + + strlen(KERN_VERSION), + V17, strlen(V17), + strlen(driver_version) - strlen(INTF_CARDTYPE) - + strlen(KERN_VERSION)); + } +#endif + return card_type; } @@ -237,6 +262,7 @@ static mlan_status woal_do_flr(moal_handle *handle, bool prepare, bool flr_flag) if (!IS_PCIE8997(handle->card_type) && !IS_PCIE9097(handle->card_type) && + !IS_PCIENW62X(handle->card_type) && !IS_PCIE9098(handle->card_type)) { LEAVE(); return status; @@ -312,7 +338,7 @@ perform_init: } #ifdef PCIE9098 - if (card->dev->device == PCIE_DEVICE_ID_NXP_88W9098P_FN1) + if (card->dev->device == PCIE_DEVICE_ID_88W9098P_FN1) mlan_set_int_mode(handle->pmlan_adapter, pcie_int_mode, 1); else #endif @@ -355,11 +381,13 @@ err_init_fw: wait_event_interruptible(handle->init_wait_q, handle->init_wait_q_woken); } +#ifdef ANDROID_KERNEL #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) wakeup_source_trash(&handle->ws); #else wake_lock_destroy(&handle->wake_lock); #endif +#endif #ifdef CONFIG_PROC_FS woal_proc_exit(handle); #endif @@ -593,7 +621,9 @@ static int woal_pcie_suspend(struct pci_dev *pdev, pm_message_t state) } woal_flush_workqueue(handle); if (!keep_power) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0) woal_do_flr(handle, true, false); +#endif handle->surprise_removed = MTRUE; handle->is_suspended = MTRUE; } @@ -659,7 +689,9 @@ static int woal_pcie_resume(struct pci_dev *pdev) pci_enable_wake(pdev, PCI_D0, 0); if (!keep_power) { handle->surprise_removed = MFALSE; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0) woal_do_flr(handle, false, false); +#endif } else { if (woal_check_driver_status(handle)) { PRINTM(MERROR, "Resuem, device is in hang state\n"); @@ -1304,7 +1336,7 @@ static mlan_status woal_pcie_register_dev(moal_handle *handle) } #ifdef PCIE9098 - if (card->dev->device == PCIE_DEVICE_ID_NXP_88W9098P_FN1) + if (card->dev->device == PCIE_DEVICE_ID_88W9098P_FN1) mlan_set_int_mode(handle->pmlan_adapter, pcie_int_mode, 1); else #endif @@ -1430,7 +1462,7 @@ void woal_pcie_bus_unregister(void) LEAVE(); } -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) #define PCIE9098_DUMP_CTRL_REG 0x1C94 #define PCIE9098_DUMP_START_REG 0x1C98 #define PCIE9098_DUMP_END_REG 0x1C9F @@ -1441,7 +1473,7 @@ void woal_pcie_bus_unregister(void) #define DEBUG_DUMP_END_REG 0xCFF #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) #define PCIE9098_SCRATCH_12_REG 0x1C90 #define PCIE9098_SCRATCH_14_REG 0x1C98 #define PCIE9098_SCRATCH_15_REG 0x1C9C @@ -1477,7 +1509,7 @@ static int woal_pcie_dump_reg_info(moal_handle *phandle, t_u8 *buffer) t_u32 dump_end_reg = 0; t_u32 scratch_14_reg = 0; t_u32 scratch_15_reg = 0; -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) /* Tx/Rx/Event AMDA start address */ t_u32 adma_reg_table[] = {0x10000, 0x10800, 0x10880, 0x11000, 0x11080}; t_u8 j; @@ -1505,8 +1537,9 @@ static int woal_pcie_dump_reg_info(moal_handle *phandle, t_u8 *buffer) } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (IS_PCIE9098(phandle->card_type) || + IS_PCIENW62X(phandle->card_type) || IS_PCIE9097(phandle->card_type)) { reg = PCIE9098_SCRATCH_12_REG; dump_start_reg = PCIE9098_DUMP_REG_START; @@ -1548,8 +1581,9 @@ static int woal_pcie_dump_reg_info(moal_handle *phandle, t_u8 *buffer) } i++; } -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (IS_PCIE9098(phandle->card_type) || + IS_PCIENW62X(phandle->card_type) || IS_PCIE9097(phandle->card_type)) { drv_ptr += sprintf( drv_ptr, @@ -1570,6 +1604,7 @@ static int woal_pcie_dump_reg_info(moal_handle *phandle, t_u8 *buffer) drv_ptr += sprintf(drv_ptr, "%s\n", buf); } if (IS_PCIE9098(phandle->card_type) || + IS_PCIENW62X(phandle->card_type) || IS_PCIE9097(phandle->card_type)) { drv_ptr += sprintf(drv_ptr, "ADMA Tx/Rx/Event/Cmd/CmdResp registers:\n"); @@ -1623,7 +1658,7 @@ static void woal_pcie_reg_dbg(moal_handle *phandle) t_u32 dump_end_reg = 0; t_u32 scratch_14_reg = 0; t_u32 scratch_15_reg = 0; -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) /* Tx/Rx/Event AMDA start address */ t_u32 adma_reg_table[] = {0x10000, 0x10800, 0x10880, 0x11000, 0x11080}; t_u8 j; @@ -1647,8 +1682,9 @@ static void woal_pcie_reg_dbg(moal_handle *phandle) } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (IS_PCIE9098(phandle->card_type) || + IS_PCIENW62X(phandle->card_type) || IS_PCIE9097(phandle->card_type)) { reg = PCIE9098_SCRATCH_12_REG; dump_start_reg = PCIE9098_DUMP_START_REG; @@ -1685,8 +1721,9 @@ static void woal_pcie_reg_dbg(moal_handle *phandle) } i++; } -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (IS_PCIE9098(phandle->card_type) || + IS_PCIENW62X(phandle->card_type) || IS_PCIE9097(phandle->card_type)) { PRINTM(MMSG, "PCIE registers from offset 0x1c20 to 0x1c9c:\n"); memset(buf, 0, sizeof(buf)); @@ -1705,6 +1742,7 @@ static void woal_pcie_reg_dbg(moal_handle *phandle) PRINTM(MMSG, "%s\n", buf); } if (IS_PCIE9098(phandle->card_type) || + IS_PCIENW62X(phandle->card_type) || IS_PCIE9097(phandle->card_type)) { PRINTM(MMSG, "ADMA Tx/Rx/Event/Cmd/CmdResp registers:\n"); for (j = 0; j < ARRAY_SIZE(adma_reg_table); j++) { @@ -1771,7 +1809,8 @@ static memory_type_mapping mem_type_mapping_tbl_8897[] = { }; #endif -#if defined(PCIE8997) || defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE8997) || defined(PCIE9098) || defined(PCIE9097) || \ + defined(PCIENW62X) #define DEBUG_HOST_READY_8997 0xCC #define DEBUG_HOST_EVENT_READY 0xAA static memory_type_mapping mem_type_mapping_tbl_8997 = {"DUMP", NULL, NULL, @@ -1780,7 +1819,7 @@ static memory_type_mapping mem_type_mapping_tbl_8997 = {"DUMP", NULL, NULL, #endif #if defined(PCIE8897) || defined(PCIE8997) || defined(PCIE9098) || \ - defined(PCIE9097) + defined(PCIE9097) || defined(PCIENW62X) /** * @brief This function reads data by 8 bit from card register * @@ -1828,8 +1867,9 @@ static rdwr_status woal_pcie_rdwr_firmware(moal_handle *phandle, t_u8 doneflag) } #endif -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (IS_PCIE9098(phandle->card_type) || + IS_PCIENW62X(phandle->card_type) || IS_PCIE9097(phandle->card_type)) { if (phandle->event_fw_dump) debug_host_ready = DEBUG_HOST_EVENT_READY; @@ -1844,8 +1884,9 @@ static rdwr_status woal_pcie_rdwr_firmware(moal_handle *phandle, t_u8 doneflag) PRINTM(MERROR, "PCIE Write ERR\n"); return RDWR_STATUS_FAILURE; } -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (IS_PCIE9098(phandle->card_type) || + IS_PCIENW62X(phandle->card_type) || IS_PCIE9097(phandle->card_type)) { if (phandle->event_fw_dump) return RDWR_STATUS_SUCCESS; @@ -2049,7 +2090,8 @@ done: } #endif -#if defined(PCIE8997) || defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE8997) || defined(PCIE9098) || defined(PCIE9097) || \ + defined(PCIENW62X) /** * @brief This function dump firmware memory to file * @@ -2077,8 +2119,9 @@ static void woal_pcie_dump_fw_info_v2(moal_handle *phandle) PRINTM(MERROR, "Could not dump firmwware info\n"); return; } -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (IS_PCIE9098(phandle->card_type) || + IS_PCIENW62X(phandle->card_type) || IS_PCIE9097(phandle->card_type)) { if (phandle->event_fw_dump) { if (RDWR_STATUS_FAILURE != @@ -2098,8 +2141,9 @@ static void woal_pcie_dump_fw_info_v2(moal_handle *phandle) /* read the number of the memories which will dump */ if (RDWR_STATUS_FAILURE == woal_pcie_rdwr_firmware(phandle, doneflag)) goto done; -#if defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) if (IS_PCIE9098(phandle->card_type) || + IS_PCIENW62X(phandle->card_type) || IS_PCIE9097(phandle->card_type)) { dump_start_reg = PCIE9098_DUMP_START_REG; dump_end_reg = PCIE9098_DUMP_END_REG; @@ -2224,7 +2268,7 @@ static t_u8 woal_pcie_is_second_mac(moal_handle *handle) { #ifdef PCIE9098 pcie_service_card *card = (pcie_service_card *)handle->card; - if (card->dev->device == PCIE_DEVICE_ID_NXP_88W9098P_FN1) + if (card->dev->device == PCIE_DEVICE_ID_88W9098P_FN1) return MTRUE; #endif return MFALSE; @@ -2238,8 +2282,10 @@ static void woal_pcie_dump_fw_info(moal_handle *phandle) if (IS_PCIE8897(phandle->card_type)) woal_pcie_dump_fw_info_v1(phandle); #endif -#if defined(PCIE8997) || defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE8997) || defined(PCIE9098) || defined(PCIE9097) || \ + defined(PCIENW62X) if (IS_PCIE8997(phandle->card_type) || + IS_PCIENW62X(phandle->card_type) || IS_PCIE9098(phandle->card_type) || IS_PCIE9097(phandle->card_type)) { woal_pcie_dump_fw_info_v2(phandle); @@ -2268,12 +2314,14 @@ static mlan_status woal_pcie_get_fw_name(moal_handle *handle) moal_handle *ref_handle = NULL; #endif -#if defined(PCIE8997) || defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE8997) || defined(PCIE9098) || defined(PCIE9097) || \ + defined(PCIENW62X) t_u32 rev_id_reg = handle->card_info->rev_id_reg; t_u32 revision_id = 0; #endif -#if defined(PCIE8997) || defined(PCIE9098) || defined(PCIE9097) +#if defined(PCIE8997) || defined(PCIE9098) || defined(PCIE9097) || \ + defined(PCIENW62X) t_u32 host_strap_reg = handle->card_info->host_strap_reg; t_u32 magic_reg = handle->card_info->magic_reg; t_u32 strap = 0; @@ -2326,7 +2374,7 @@ static mlan_status woal_pcie_get_fw_name(moal_handle *handle) #endif #ifdef PCIE9098 if (IS_PCIE9098(handle->card_type)) { - if (card->dev->device == PCIE_DEVICE_ID_NXP_88W9098P_FN0) { + if (card->dev->device == PCIE_DEVICE_ID_88W9098P_FN0) { woal_pcie_read_reg(handle, rev_id_reg, &revision_id); woal_pcie_read_reg(handle, host_strap_reg, &strap); woal_pcie_read_reg(handle, magic_reg, &magic); @@ -2431,6 +2479,26 @@ static mlan_status woal_pcie_get_fw_name(moal_handle *handle) } } #endif +#ifdef PCIENW62X + if (IS_PCIENW62X(handle->card_type)) { + woal_pcie_read_reg(handle, rev_id_reg, &revision_id); + woal_pcie_read_reg(handle, host_strap_reg, &strap); + woal_pcie_read_reg(handle, magic_reg, &magic); + revision_id &= 0xff; + strap &= 0x7; + magic &= 0xff; + PRINTM(MCMND, "magic=0x%x, strap=0x%x, revision_id=0x%x\n", + magic, strap, revision_id); + if (magic == CHIP_MAGIC_VALUE) { + if (strap == CARD_TYPE_PCIE_UART) + strcpy(handle->card_info->fw_name, + PCIEUARTNW62X_DEFAULT_COMBO_FW_NAME); + else + strcpy(handle->card_info->fw_name, + PCIEUSBNW62X_DEFAULT_COMBO_FW_NAME); + } + } +#endif done: PRINTM(MCMND, "combo fw:%s wlan fw:%s \n", handle->card_info->fw_name, handle->card_info->fw_name_wlan); diff --git a/mxm_wifiex/wlan_src/mlinux/moal_pcie.h b/mxm_wifiex/wlan_src/mlinux/moal_pcie.h index 4161d72..bf50278 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_pcie.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_pcie.h @@ -4,7 +4,7 @@ * driver. * * - * Copyright 2014-2020 NXP + * Copyright 2014-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -29,27 +29,34 @@ Change log: #ifndef _MOAL_PCIE_H_ #define _MOAL_PCIE_H_ -#define PCIE_VENDOR_ID_NXP (0x11ab) -#define PCIE_VENDOR_ID_V2_NXP (0x1b4b) +#define PCIE_VENDOR_ID_MRVL (0x11ab) +#define PCIE_VENDOR_ID_V2_MRVL (0x1b4b) +#define PCIE_VENDOR_ID_NXP (0x1131) + #ifdef PCIE8997 /** PCIE device ID for 8997 card */ -#define PCIE_DEVICE_ID_NXP_88W8997P (0x2b42) +#define PCIE_DEVICE_ID_88W8997P (0x2b42) #endif #ifdef PCIE8897 /** PCIE device ID for 8897 card */ -#define PCIE_DEVICE_ID_NXP_88W8897P (0x2b38) +#define PCIE_DEVICE_ID_88W8897P (0x2b38) #endif #ifdef PCIE9097 /** PCIE device ID for 9097 card */ -#define PCIE_DEVICE_ID_NXP_88W9097 (0x2b56) +#define PCIE_DEVICE_ID_88W9097 (0x2b56) #endif #ifdef PCIE9098 /** PCIE device ID for 9098 card FN0 */ -#define PCIE_DEVICE_ID_NXP_88W9098P_FN0 (0x2b43) +#define PCIE_DEVICE_ID_88W9098P_FN0 (0x2b43) /** PCIE device ID for 9098 card FN1 */ -#define PCIE_DEVICE_ID_NXP_88W9098P_FN1 (0x2b44) +#define PCIE_DEVICE_ID_88W9098P_FN1 (0x2b44) +#endif + +#ifdef PCIENW62X +/** PCIE device ID for NW62X card FN0 */ +#define PCIE_DEVICE_ID_88WNW62X (0x3000) #endif #include @@ -106,7 +113,14 @@ Change log: #define PCIE9097_WLAN_V1_FW_NAME "nxp/pcieiw620_wlan_v1.bin" #endif /* PCIE9097 */ -#if defined(PCIE9098) || defined(PCIE9097) +#ifdef PCIENW62X +#define PCIENW62X_DEFAULT_COMBO_FW_NAME "nxp/pcieusbnw62x_combo.bin" +#define PCIEUARTNW62X_DEFAULT_COMBO_FW_NAME "nxp/pcieuartnw62x_combo.bin" +#define PCIEUSBNW62X_DEFAULT_COMBO_FW_NAME "nxp/pcieusbnw62x_combo.bin" +#define PCIENW62X_DEFAULT_WLAN_FW_NAME "nxp/pcienw62x_wlan.bin" +#endif /* PCIE8997 */ + +#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X) #define PCIE_NUM_MSIX_VECTORS 32 #else #define PCIE_NUM_MSIX_VECTORS 4 diff --git a/mxm_wifiex/wlan_src/mlinux/moal_priv.c b/mxm_wifiex/wlan_src/mlinux/moal_priv.c index 50dd12c..dd9d4ad 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_priv.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_priv.c @@ -1792,6 +1792,145 @@ done: return ret; } +/** + * @brief Set/Get network monitor configurations + * + * @param priv A pointer to moal_private structure + * @param wrq A pointer to iwreq structure + * + * @return 0 --success, otherwise fail + */ +static int woal_net_monitor_ioctl(moal_private *priv, struct iwreq *wrq) +{ + int user_data_len = wrq->u.data.length; + int data[5] = {0}, copy_len; + int ret = 0; + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *misc = NULL; + mlan_ds_misc_net_monitor *net_mon = NULL; + mlan_status status = MLAN_STATUS_SUCCESS; + + ENTER(); + + copy_len = MIN(sizeof(data), sizeof(int) * user_data_len); + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (req == NULL) { + LEAVE(); + return -ENOMEM; + } + misc = (mlan_ds_misc_cfg *)req->pbuf; + net_mon = (mlan_ds_misc_net_monitor *)&misc->param.net_mon; + misc->sub_command = MLAN_OID_MISC_NET_MONITOR; + req->req_id = MLAN_IOCTL_MISC_CFG; + + if (!user_data_len) { + req->action = MLAN_ACT_GET; + } else if (user_data_len == 1 || user_data_len == 4 || + user_data_len == 5) { + if (copy_from_user(data, wrq->u.data.pointer, copy_len)) { + PRINTM(MERROR, "Copy from user failed\n"); + ret = -EFAULT; + goto done; + } + if (data[0] != MTRUE && data[0] != MFALSE) { + PRINTM(MERROR, + "NET_MON: Activity should be enable(=1)/disable(=0)\n"); + ret = -EINVAL; + goto done; + } + net_mon->enable_net_mon = data[0]; + if (data[0] == MTRUE) { + int i; + if (user_data_len != 4 && user_data_len != 5) { + PRINTM(MERROR, + "NET_MON: Invalid number of args!\n"); + ret = -EINVAL; + goto done; + } + /* Supported filter flags */ + if (!data[1] || + data[1] & ~(MLAN_NETMON_DATA_FRAME | + MLAN_NETMON_MANAGEMENT_FRAME | + MLAN_NETMON_CONTROL_FRAME)) { + PRINTM(MERROR, + "NET_MON: Invalid filter flag\n"); + ret = -EINVAL; + goto done; + } + /* Supported bands */ + for (i = 0; i < (int)sizeof(SupportedInfraBand); i++) + if (data[2] == SupportedInfraBand[i]) + break; + if (i == sizeof(SupportedInfraBand)) { + PRINTM(MERROR, "NET_MON: Invalid band\n"); + ret = -EINVAL; + goto done; + } + /* Supported channel */ + if (data[3] < 1 || data[3] > MLAN_MAX_CHANNEL) { + PRINTM(MERROR, + "NET_MON: Invalid channel number\n"); + ret = -EINVAL; + goto done; + } + if (user_data_len == 5) { + /* Secondary channel offset */ + if (!(data[2] & (BAND_GN | BAND_AN))) { + PRINTM(MERROR, + "No 11n in band, can not set " + "secondary channel offset\n"); + ret = -EINVAL; + goto done; + } + if ((data[4] != CHANNEL_BW_20MHZ) && + (data[4] != CHANNEL_BW_40MHZ_ABOVE) && + (data[4] != CHANNEL_BW_40MHZ_BELOW) && + (data[4] != CHANNEL_BW_80MHZ)) { + PRINTM(MERROR, + "Invalid secondary channel bandwidth, " + "only allowed 0, 1, 3 or 4\n"); + ret = -EINVAL; + goto done; + } + net_mon->chan_bandwidth = data[4]; + } + net_mon->filter_flag = data[1]; + net_mon->band = data[2]; + net_mon->channel = data[3]; + } + req->action = MLAN_ACT_SET; + } else { + PRINTM(MERROR, "NET_MON: Invalid number of args!\n"); + ret = -EINVAL; + goto done; + } + + status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } + + data[0] = net_mon->enable_net_mon; + data[1] = net_mon->filter_flag; + data[2] = net_mon->band; + data[3] = net_mon->channel; + data[4] = net_mon->chan_bandwidth; + wrq->u.data.length = 5; + if (copy_to_user(wrq->u.data.pointer, data, + sizeof(int) * wrq->u.data.length)) { + PRINTM(MERROR, "Copy to user failed\n"); + ret = -EFAULT; + goto done; + } + +done: + if (status != MLAN_STATUS_PENDING) + kfree(req); + LEAVE(); + return ret; +} + /** * @brief Get LOG * @@ -4587,17 +4726,26 @@ done: static int woal_set_user_scan_ext_ioctl(moal_private *priv, struct iwreq *wrq) { int ret = 0; - wlan_user_scan_cfg scan_req; + wlan_user_scan_cfg *scan_req; ENTER(); - memset(&scan_req, 0x00, sizeof(scan_req)); - if (copy_from_user(&scan_req, wrq->u.data.pointer, - MIN(wrq->u.data.length, sizeof(scan_req)))) { + scan_req = (wlan_user_scan_cfg *)kmalloc(sizeof(wlan_user_scan_cfg), + GFP_KERNEL); + if (!scan_req) { + PRINTM(MERROR, "Malloc buffer failed\n"); + LEAVE(); + return -ENOMEM; + } + memset(scan_req, 0x00, sizeof(wlan_user_scan_cfg)); + if (copy_from_user(scan_req, wrq->u.data.pointer, + MIN(wrq->u.data.length, + sizeof(wlan_user_scan_cfg)))) { PRINTM(MINFO, "Copy from user failed\n"); LEAVE(); return -EFAULT; } - if (MLAN_STATUS_FAILURE == woal_do_scan(priv, &scan_req)) + if (MLAN_STATUS_FAILURE == woal_do_scan(priv, scan_req)) ret = -EFAULT; + kfree(scan_req); LEAVE(); return ret; } @@ -6578,6 +6726,9 @@ int woal_wext_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) case WOAL_SLEEP_PARAMS: ret = woal_sleep_params_ioctl(priv, wrq); break; + case WOAL_NET_MONITOR: + ret = woal_net_monitor_ioctl(priv, wrq); + break; case WOAL_DFS_TESTING: ret = woal_dfs_testing(priv, wrq); break; diff --git a/mxm_wifiex/wlan_src/mlinux/moal_priv.h b/mxm_wifiex/wlan_src/mlinux/moal_priv.h index 67bbf78..c35ef67 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_priv.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_priv.h @@ -4,7 +4,7 @@ * @brief This file contains definition for extended private IOCTL call. * * - * Copyright 2008-2020 NXP + * Copyright 2008-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -130,6 +130,8 @@ Change log: #define WOAL_ADDBA_REJECT 27 /** Private command ID to set/get sleep parameters */ #define WOAL_SLEEP_PARAMS 28 +/** Private command ID to set/get network monitor */ +#define WOAL_NET_MONITOR 30 /** Private command ID to set/get TX BF capabilities */ #define WOAL_TX_BF_CAP 31 /** Private command ID to set/get dfs testing settings */ diff --git a/mxm_wifiex/wlan_src/mlinux/moal_proc.c b/mxm_wifiex/wlan_src/mlinux/moal_proc.c index af702c0..820dd1e 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_proc.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_proc.c @@ -3,7 +3,7 @@ * @brief This file contains functions for proc file. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mxm_wifiex/wlan_src/mlinux/moal_sdio.h b/mxm_wifiex/wlan_src/mlinux/moal_sdio.h index 714ec93..e99d8f4 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_sdio.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_sdio.h @@ -4,7 +4,7 @@ * driver. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -139,15 +139,26 @@ Change log: #define SD9097_WLAN_V1_FW_NAME "nxp/sdiw620_wlan_v1.bin" #endif /* SD9097 */ +#ifdef SDNW62X +#define SDNW62X_DEFAULT_COMBO_FW_NAME "nxp/sdsd_nw62x.bin" +#define SDUARTNW62X_COMBO_FW_NAME "nxp/sduart_nw62x.bin" +#define SDSDNW62X_COMBO_FW_NAME "sdsd_nw62x.bin" +#define SDNW62X_DEFAULT_WLAN_FW_NAME "nxp/sd_nw62x.bin" +#endif /* SDNW62X */ + #ifdef SD9177 -#define SD9177_A0 0x01 +#define SD9177_A0 0x00 +#define SD9177_A1 0x01 #define SD9177_DEFAULT_COMBO_FW_NAME "nxp/sdsd_nw61x.bin" +#define SD9177_DEFAULT_COMBO_V1_FW_NAME "nxp/sduart_nw61x_v1.bin" #define SDUART9177_DEFAULT_COMBO_FW_NAME "nxp/sduart_nw61x.bin" #define SDSD9177_DEFAULT_COMBO_FW_NAME "sdsd_nw61x.bin" #define SD9177_DEFAULT_WLAN_FW_NAME "nxp/sd_w61x.bin" -/** Device ID for SD9177 */ -#define SD_DEVICE_ID_9177 (0x0205) +#define SDUART9177_DEFAULT_COMBO_V1_FW_NAME "nxp/sduart_nw61x_v1.bin" +#define SDSD9177_DEFAULT_COMBO_V1_FW_NAME "sdsd_nw61x_v1.bin" +#define SD9177_DEFAULT_WLAN_V1_FW_NAME "nxp/sd_w61x_v1.bin" #endif /* SD9177 */ + /******************************************************** Global Functions ********************************************************/ diff --git a/mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c b/mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c index 99dadf8..7497008 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c @@ -4,7 +4,7 @@ * related functions. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -31,9 +31,7 @@ Change log: #include "moal_sdio.h" /** define nxp vendor id */ -#ifdef SD9177 #define NXP_VENDOR_ID 0x0471 -#endif #define MRVL_VENDOR_ID 0x02df /******************************************************** @@ -83,6 +81,14 @@ static moal_if_ops sdiommc_ops; /** Device ID for SD9097 */ #define SD_DEVICE_ID_9097 (0x9155) #endif +#ifdef SD9177 +/** Device ID for SD9177 */ +#define SD_DEVICE_ID_9177 (0x0205) +#endif +#ifdef SDNW62X +/** Device ID for SDNW62X */ +#define SD_DEVICE_ID_NW62X (0x020C) +#endif /** WLAN IDs */ static const struct sdio_device_id wlan_ids[] = { @@ -116,6 +122,9 @@ static const struct sdio_device_id wlan_ids[] = { #endif #ifdef SD9177 {SDIO_DEVICE(NXP_VENDOR_ID, SD_DEVICE_ID_9177)}, +#endif +#ifdef SDNW62X + {SDIO_DEVICE(NXP_VENDOR_ID, SD_DEVICE_ID_NW62X)}, #endif {}, }; @@ -381,6 +390,20 @@ static t_u16 woal_update_card_type(t_void *card) (strlen(INTF_CARDTYPE) + strlen(KERN_VERSION))); } #endif +#ifdef SDNW62X + if (cardp_sd->func->device == SD_DEVICE_ID_NW62X) { + card_type = CARD_TYPE_SDNW62X; + moal_memcpy_ext(NULL, driver_version, CARD_SDNW62X, + strlen(CARD_SDNW62X), strlen(driver_version)); + moal_memcpy_ext( + NULL, + driver_version + strlen(INTF_CARDTYPE) + + strlen(KERN_VERSION), + V17, strlen(V17), + strlen(driver_version) - + (strlen(INTF_CARDTYPE) + strlen(KERN_VERSION))); + } +#endif #ifdef SD9097 if (cardp_sd->func->device == SD_DEVICE_ID_9097) { card_type = CARD_TYPE_SD9097; @@ -1334,7 +1357,8 @@ static mlan_status woal_sdiommc_get_fw_name(moal_handle *handle) t_u32 rev_id_reg = handle->card_info->rev_id_reg; #if defined(SD8987) || defined(SD8997) || defined(SD9098) || \ - defined(SD9097) || defined(SD8978) || defined(SD9177) + defined(SD9097) || defined(SDNW62X) || defined(SD8978) || \ + defined(SD9177) t_u32 magic_reg = handle->card_info->magic_reg; t_u32 magic = 0; t_u32 host_strap_reg = handle->card_info->host_strap_reg; @@ -1354,7 +1378,8 @@ static mlan_status woal_sdiommc_get_fw_name(moal_handle *handle) PRINTM(MCMND, "revision_id=0x%x\n", revision_id); #if defined(SD8987) || defined(SD8997) || defined(SD9098) || \ - defined(SD9097) || defined(SD8978) || defined(SD9177) + defined(SD9097) || defined(SDNW62X) || defined(SD8978) || \ + defined(SD9177) /** Revision ID register */ woal_sdiommc_read_reg(handle, magic_reg, &magic); /** Revision ID register */ @@ -1502,6 +1527,19 @@ static mlan_status woal_sdiommc_get_fw_name(moal_handle *handle) } } #endif +#ifdef SDNW62X + if (IS_SDNW62X(handle->card_type)) { + if (magic == CHIP_MAGIC_VALUE) { + if (strap == CARD_TYPE_SD_UART) + strcpy(handle->card_info->fw_name, + SDUARTNW62X_COMBO_FW_NAME); + else + strcpy(handle->card_info->fw_name, + SDSDNW62X_COMBO_FW_NAME); + } + } +#endif + #ifdef SD9177 if (IS_SD9177(handle->card_type)) { switch (revision_id) { @@ -1517,6 +1555,18 @@ static mlan_status woal_sdiommc_get_fw_name(moal_handle *handle) strcpy(handle->card_info->fw_name_wlan, SD9177_DEFAULT_WLAN_FW_NAME); break; + case SD9177_A1: + if (magic == CHIP_MAGIC_VALUE) { + if (strap == CARD_TYPE_SD_UART) + strcpy(handle->card_info->fw_name, + SDUART9177_DEFAULT_COMBO_V1_FW_NAME); + else + strcpy(handle->card_info->fw_name, + SDSD9177_DEFAULT_COMBO_V1_FW_NAME); + } + strcpy(handle->card_info->fw_name_wlan, + SD9177_DEFAULT_WLAN_V1_FW_NAME); + break; default: break; } diff --git a/mxm_wifiex/wlan_src/mlinux/moal_shim.c b/mxm_wifiex/wlan_src/mlinux/moal_shim.c index 5779df5..a595e9f 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_shim.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_shim.c @@ -3,7 +3,7 @@ * @brief This file contains the callback functions registered to MLAN * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -862,9 +862,9 @@ mlan_status moal_get_vdll_data(t_void *pmoal, t_u32 len, t_u8 *pbuf) mlan_status moal_get_hw_spec_complete(t_void *pmoal, mlan_status status, mlan_hw_info *phw, pmlan_bss_tbl ptbl) { -#if defined(PCIE9098) moal_handle *handle = (moal_handle *)pmoal; -#endif + int i; + t_u32 drv_mode = handle->params.drv_mode; ENTER(); if (status == MLAN_STATUS_SUCCESS) { @@ -890,6 +890,38 @@ mlan_status moal_get_hw_spec_complete(t_void *pmoal, mlan_status status, MLAN_MAX_VER_STR_LEN - 1); } #endif + /** FW should only enable DFS on one mac */ + if (!(phw->fw_cap & FW_CAPINFO_ZERO_DFS)) + handle->params.drv_mode &= ~DRV_MODE_DFS; + + if (!(phw->fw_cap & FW_CAPINFO_80211BGA)) + handle->params.drv_mode &= ~DRV_MODE_WLAN; + if (!handle->params.drv_mode || + MLAN_STATUS_SUCCESS != + woal_update_drv_tbl(handle, + handle->params.drv_mode)) { + PRINTM(MERROR, + "Get_hw_spec_complete: Fail to update drv_tbl\n"); + LEAVE(); + return MLAN_STATUS_FAILURE; + } + memset(ptbl, 0, sizeof(mlan_bss_tbl)); + for (i = 0; i < handle->drv_mode.intf_num; i++) { + ptbl->bss_attr[i].bss_type = + handle->drv_mode.bss_attr[i].bss_type; + ptbl->bss_attr[i].frame_type = + handle->drv_mode.bss_attr[i].frame_type; + ptbl->bss_attr[i].active = + handle->drv_mode.bss_attr[i].active; + ptbl->bss_attr[i].bss_priority = + handle->drv_mode.bss_attr[i].bss_priority; + ptbl->bss_attr[i].bss_num = + handle->drv_mode.bss_attr[i].bss_num; + ptbl->bss_attr[i].bss_virtual = + handle->drv_mode.bss_attr[i].bss_virtual; + } + PRINTM(MCMND, "org_drv_mode=0x%x drv_mode=0x%x\n", drv_mode, + handle->params.drv_mode); } LEAVE(); return MLAN_STATUS_SUCCESS; @@ -1325,6 +1357,268 @@ mlan_status moal_read_reg(t_void *pmoal, t_u32 reg, t_u32 *data) #endif /* SDIO || PCIE */ +#if defined(STA_CFG80211) && defined(UAP_CFG80211) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) +/** + * @brief This function uploads the packet to the network stack monitor + * interface + * + * @param handle Pointer to the MOAL context + * @param pmbuf Pointer to mlan_buffer + * + * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING/MLAN_STATUS_FAILURE + */ +static mlan_status moal_recv_packet_to_mon_if(moal_handle *handle, + pmlan_buffer pmbuf) +{ + mlan_status status = MLAN_STATUS_SUCCESS; + struct sk_buff *skb = NULL; + struct radiotap_header *rth = NULL; + radiotap_info rt_info = {}; + t_u8 format = 0; + t_u8 bw = 0; + t_u8 gi = 0; + t_u8 ldpc = 0; + t_u8 chan_num; + t_u8 band = 0; + struct ieee80211_hdr *dot11_hdr = NULL; + t_u8 *payload = NULL; + t_u32 vht_sig1 = 0; + t_u32 vht_sig2 = 0; + ENTER(); + if (!pmbuf->pdesc) { + LEAVE(); + return status; + } + + skb = (struct sk_buff *)pmbuf->pdesc; + + if ((handle->mon_if) && netif_running(handle->mon_if->mon_ndev)) { + if (handle->mon_if->radiotap_enabled) { + if (skb_headroom(skb) < sizeof(*rth)) { + PRINTM(MERROR, + "%s No space to add Radio TAP header\n", + __func__); + status = MLAN_STATUS_FAILURE; + handle->mon_if->stats.rx_dropped++; + goto done; + } + dot11_hdr = + (struct ieee80211_hdr *)(pmbuf->pbuf + + pmbuf->data_offset); + moal_memcpy_ext(handle, &rt_info, + pmbuf->pbuf + pmbuf->data_offset - + sizeof(rt_info), + sizeof(rt_info), sizeof(rt_info)); + ldpc = (rt_info.rate_info.rate_info & 0x20) >> 5; + format = (rt_info.rate_info.rate_info & 0x18) >> 3; + bw = (rt_info.rate_info.rate_info & 0x06) >> 1; + gi = rt_info.rate_info.rate_info & 0x01; + skb_push(skb, sizeof(*rth)); + rth = (struct radiotap_header *)skb->data; + memset(skb->data, 0, sizeof(*rth)); + rth->hdr.it_version = PKTHDR_RADIOTAP_VERSION; + rth->hdr.it_pad = 0; + rth->hdr.it_len = cpu_to_le16(sizeof(*rth)); + rth->hdr.it_present = cpu_to_le32( + (1 << IEEE80211_RADIOTAP_TSFT) | + (1 << IEEE80211_RADIOTAP_FLAGS) | + (1 << IEEE80211_RADIOTAP_CHANNEL) | + (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | + (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | + (1 << IEEE80211_RADIOTAP_ANTENNA)); + /** Timstamp */ + rth->body.timestamp = woal_cpu_to_le64(jiffies); + /** Flags */ + rth->body.flags = (rt_info.extra_info.flags & + ~(RADIOTAP_FLAGS_USE_SGI_HT | + RADIOTAP_FLAGS_WITH_FRAGMENT | + RADIOTAP_FLAGS_WEP_ENCRYPTION | + RADIOTAP_FLAGS_FAILED_FCS_CHECK)); + /** reverse fail fcs, 1 means pass FCS in FW, but means + * fail FCS in radiotap */ + rth->body.flags |= (~rt_info.extra_info.flags) & + RADIOTAP_FLAGS_FAILED_FCS_CHECK; + if ((format == MLAN_RATE_FORMAT_HT) && (gi == 1)) + rth->body.flags |= RADIOTAP_FLAGS_USE_SGI_HT; + if (ieee80211_is_mgmt(dot11_hdr->frame_control) || + ieee80211_is_data(dot11_hdr->frame_control)) { + if ((ieee80211_has_morefrags( + dot11_hdr->frame_control)) || + (!ieee80211_is_first_frag( + dot11_hdr->seq_ctrl))) { + rth->body.flags |= + RADIOTAP_FLAGS_WITH_FRAGMENT; + } + } + if (ieee80211_is_data(dot11_hdr->frame_control) && + ieee80211_has_protected(dot11_hdr->frame_control)) { + payload = (t_u8 *)dot11_hdr + + ieee80211_hdrlen( + dot11_hdr->frame_control); + if (!(*(payload + 3) & 0x20)) /** ExtIV bit + shall be 0 for + WEP frame */ + rth->body.flags |= + RADIOTAP_FLAGS_WEP_ENCRYPTION; + } + /** Rate, t_u8 only apply for LG mode */ + if (format == MLAN_RATE_FORMAT_LG) { + rth->hdr.it_present |= cpu_to_le32( + 1 << IEEE80211_RADIOTAP_RATE); + rth->body.rate = rt_info.rate_info.bitrate; + } + /** Channel */ + rth->body.channel.flags = 0; + if (rt_info.chan_num) + chan_num = rt_info.chan_num; + else + chan_num = + handle->mon_if->band_chan_cfg.channel; + band = (chan_num <= 14) ? IEEE80211_BAND_2GHZ : + IEEE80211_BAND_5GHZ; + rth->body.channel.frequency = woal_cpu_to_le16( + ieee80211_channel_to_frequency(chan_num, band)); + rth->body.channel.flags |= + woal_cpu_to_le16((band == IEEE80211_BAND_2GHZ) ? + CHANNEL_FLAGS_2GHZ : + CHANNEL_FLAGS_5GHZ); + if (rth->body.channel.flags & + woal_cpu_to_le16(CHANNEL_FLAGS_2GHZ)) + rth->body.channel.flags |= woal_cpu_to_le16( + CHANNEL_FLAGS_DYNAMIC_CCK_OFDM); + else + rth->body.channel.flags |= + woal_cpu_to_le16(CHANNEL_FLAGS_OFDM); + if (handle->mon_if->chandef.chan && + (handle->mon_if->chandef.chan->flags & + (IEEE80211_CHAN_PASSIVE_SCAN | + IEEE80211_CHAN_RADAR))) + rth->body.channel.flags |= woal_cpu_to_le16( + CHANNEL_FLAGS_ONLY_PASSIVSCAN_ALLOW); + /** Antenna */ + rth->body.antenna_signal = -(rt_info.nf - rt_info.snr); + rth->body.antenna_noise = -rt_info.nf; + rth->body.antenna = rt_info.antenna; + /** MCS */ + if (format == MLAN_RATE_FORMAT_HT) { + rth->hdr.it_present |= cpu_to_le32( + 1 << IEEE80211_RADIOTAP_MCS); + rth->body.u.mcs.known = + rt_info.extra_info.mcs_known; + rth->body.u.mcs.flags = + rt_info.extra_info.mcs_flags; + /** MCS mcs */ + rth->body.u.mcs.known |= + MCS_KNOWN_MCS_INDEX_KNOWN; + rth->body.u.mcs.mcs = + rt_info.rate_info.mcs_index; + /** MCS bw */ + rth->body.u.mcs.known |= MCS_KNOWN_BANDWIDTH; + rth->body.u.mcs.flags &= ~(0x03); /** Clear, + 20MHz as + default */ + if (bw == 1) + rth->body.u.mcs.flags |= RX_BW_40; + /** MCS gi */ + rth->body.u.mcs.known |= + MCS_KNOWN_GUARD_INTERVAL; + rth->body.u.mcs.flags &= ~(1 << 2); + if (gi) + rth->body.u.mcs.flags |= gi << 2; + /** MCS FEC */ + rth->body.u.mcs.known |= MCS_KNOWN_FEC_TYPE; + rth->body.u.mcs.flags &= ~(1 << 4); + if (ldpc) + rth->body.u.mcs.flags |= ldpc << 4; + } + /** VHT */ + if (format == MLAN_RATE_FORMAT_VHT) { + vht_sig1 = rt_info.extra_info.vht_sig1; + vht_sig2 = rt_info.extra_info.vht_sig2; + /** Present Flag */ + rth->hdr.it_present |= cpu_to_le32( + 1 << IEEE80211_RADIOTAP_VHT); + /** STBC */ + rth->body.u.vht.known |= + woal_cpu_to_le16(VHT_KNOWN_STBC); + if (vht_sig1 & MBIT(3)) + rth->body.u.vht.flags |= VHT_FLAG_STBC; + /** TXOP_PS_NA */ + /** TODO: Not support now */ + /** GI */ + rth->body.u.vht.known |= + woal_cpu_to_le16(VHT_KNOWN_GI); + if (vht_sig2 & MBIT(0)) + rth->body.u.vht.flags |= VHT_FLAG_SGI; + /** SGI NSYM DIS */ + rth->body.u.vht.known |= woal_cpu_to_le16( + VHT_KNOWN_SGI_NSYM_DIS); + if (vht_sig2 & MBIT(1)) + rth->body.u.vht.flags |= + VHT_FLAG_SGI_NSYM_M10_9; + /** LDPC_EXTRA_OFDM_SYM */ + /** TODO: Not support now */ + /** BEAMFORMED */ + rth->body.u.vht.known |= + woal_cpu_to_le16(VHT_KNOWN_BEAMFORMED); + if (vht_sig2 & MBIT(8)) + rth->body.u.vht.flags |= + VHT_FLAG_BEAMFORMED; + /** BANDWIDTH */ + rth->body.u.vht.known |= + woal_cpu_to_le16(VHT_KNOWN_BANDWIDTH); + if (bw == 1) + rth->body.u.vht.bandwidth = RX_BW_40; + else if (bw == 2) + rth->body.u.vht.bandwidth = RX_BW_80; + /** GROUP_ID */ + rth->body.u.vht.known |= + woal_cpu_to_le16(VHT_KNOWN_GROUP_ID); + rth->body.u.vht.group_id = + (vht_sig1 & (0x3F0)) >> 4; + /** PARTIAL_AID */ + /** TODO: Not support now */ + /** mcs_nss */ + rth->body.u.vht.mcs_nss[0] = + (vht_sig2 & (0xF0)) >> 4; + rth->body.u.vht.mcs_nss[0] |= + (vht_sig1 & (0x1C00)) >> (10 - 4); + /** coding */ + if (vht_sig2 & MBIT(2)) + rth->body.u.vht.coding |= + VHT_CODING_LDPC_USER0; + } + } + skb_set_mac_header(skb, 0); + skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = htons(ETH_P_802_2); + memset(skb->cb, 0, sizeof(skb->cb)); + skb->dev = handle->mon_if->mon_ndev; + + handle->mon_if->stats.rx_bytes += skb->len; + handle->mon_if->stats.rx_packets++; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0) + netif_rx(skb); +#else + if (in_interrupt()) + netif_rx(skb); + else + netif_rx_ni(skb); +#endif + status = MLAN_STATUS_PENDING; + } + +done: + + LEAVE(); + return status; +} +#endif +#endif + /** * @brief This function uploads amsdu packet to the network stack * @@ -1552,6 +1846,18 @@ mlan_status moal_recv_packet(t_void *pmoal, pmlan_buffer pmbuf) goto done; } skb_put(skb, pmbuf->data_len); +#if defined(STA_CFG80211) && defined(UAP_CFG80211) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + if (pmbuf->flags & MLAN_BUF_FLAG_NET_MONITOR) { + status = moal_recv_packet_to_mon_if( + pmoal, pmbuf); + if (status == MLAN_STATUS_PENDING) + atomic_dec( + &handle->mbufalloc_count); + goto done; + } +#endif +#endif pmbuf->pdesc = NULL; pmbuf->pbuf = NULL; pmbuf->data_offset = pmbuf->data_len = 0; @@ -1562,6 +1868,20 @@ mlan_status moal_recv_packet(t_void *pmoal, pmlan_buffer pmbuf) } else { PRINTM(MERROR, "%s without skb attach!!!\n", __func__); +#if defined(STA_CFG80211) && defined(UAP_CFG80211) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + /** drop the packet without skb in + * monitor mode */ + if (pmbuf->flags & MLAN_BUF_FLAG_NET_MONITOR) { + PRINTM(MINFO, + "%s Drop packet without skb\n", + __func__); + status = MLAN_STATUS_FAILURE; + priv->stats.rx_dropped++; + goto done; + } +#endif +#endif skb = dev_alloc_skb(pmbuf->data_len + MLAN_NET_IP_ALIGN); if (!skb) { @@ -1666,6 +1986,7 @@ mlan_status moal_recv_packet(t_void *pmoal, pmlan_buffer pmbuf) skb->data, skb->len); #endif #endif +#ifdef ANDROID_KERNEL if (handle->params.wakelock_timeout) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) __pm_wakeup_event( @@ -1679,6 +2000,7 @@ mlan_status moal_recv_packet(t_void *pmoal, pmlan_buffer pmbuf) .wakelock_timeout)); #endif } +#endif if (priv->rx_protocols.protocol_num) { for (j = 0; j < priv->rx_protocols.protocol_num; j++) { @@ -1834,7 +2156,7 @@ int woal_check_media_connected(t_void *pmoal) * @param pmoal Pointer to the MOAL context * */ -static void moal_connection_status_check_pmqos(t_void *pmoal) +void moal_connection_status_check_pmqos(t_void *pmoal) { moal_handle *pmhandle = (moal_handle *)pmoal; if ((woal_check_media_connected(pmoal) == MTRUE)) { @@ -1919,11 +2241,27 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) moal_handle *handle = (moal_handle *)pmoal; moal_handle *ref_handle = NULL; +#ifdef STA_CFG80211 +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) + t_u8 enable = 1; +#endif + t_u8 *req_ie = NULL; + t_u16 ie_len = 0; + apinfo *pinfo = NULL, *req_tlv = NULL; + MrvlIEtypesHeader_t *tlv = NULL; + t_u16 tlv_type = 0, tlv_len = 0, tlv_buf_left = 0; +#endif #ifdef STA_CFG80211 t_u8 hw_test; #endif int cfg80211_wext; +#ifdef STA_CFG80211 +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + struct cfg80211_roam_info *roam_info = NULL; +#endif +#endif + t_u16 csi_len; #ifdef STA_CFG80211 t_u8 channel_status; moal_private *remain_priv = NULL; @@ -1932,6 +2270,11 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) chan_band_info *pchan_info = NULL; #endif t_u8 radar_detected; + t_u8 event_buf[64]; + t_u8 radar_chan; +#ifdef UAP_CFG80211 + moal_private *cfg_priv = NULL; +#endif t_u8 auto_fw_dump = MFALSE; ENTER(); @@ -2541,6 +2884,7 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) #endif ) { priv->roaming_required = MTRUE; +#ifdef ANDROID_KERNEL #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) __pm_wakeup_event(&priv->phandle->ws, ROAMING_WAKE_LOCK_TIMEOUT); @@ -2550,6 +2894,7 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) msecs_to_jiffies( ROAMING_WAKE_LOCK_TIMEOUT)); #endif +#endif #ifdef REASSOCIATION wake_up_interruptible( &priv->phandle->reassoc_thread.wait_q); @@ -2603,11 +2948,48 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) case MLAN_EVENT_ID_FW_CHANNEL_REPORT_RDY: radar_detected = pmevent->event_buf[0]; +#ifdef UAP_SUPPORT + if (priv->chan_rpt_req.chanNum && priv->chan_rpt_pending) { + radar_chan = pmevent->event_buf[1]; + if (radar_detected) { + snprintf(event_buf, sizeof(event_buf) - 1, + "%s %d", CUS_EVT_RADAR_DETECTED, + radar_chan); + woal_broadcast_event(priv, event_buf, + strlen(event_buf)); + } else { + snprintf(event_buf, sizeof(event_buf) - 1, + "%s %d", CUS_EVT_CAC_FINISHED, + priv->chan_rpt_req.chanNum); + woal_broadcast_event(priv, event_buf, + strlen(event_buf)); + } + if (priv->bss_type == MLAN_BSS_TYPE_DFS) + woal_chan_event(priv, WOAL_EVENT_CHAN_RPT, + priv->chan_rpt_req.chanNum, + radar_detected); + } +#endif #ifdef UAP_CFG80211 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 12, 0) if (!IS_STA_OR_UAP_CFG80211(cfg80211_wext)) break; + if (priv->chan_rpt_req.chanNum && priv->chan_rpt_pending) { + priv->chan_rpt_pending = MFALSE; + cfg_priv = woal_get_priv_with_wdev(priv->phandle); + if (cfg_priv) { + if (radar_detected) + woal_update_channel_dfs_state( + priv->chan_rpt_req.chanNum, + DFS_UNAVAILABLE); + else + woal_update_channel_dfs_state( + priv->chan_rpt_req.chanNum, + DFS_AVAILABLE); + } + break; + } if (priv->phandle->is_cac_timer_set) { PRINTM(MEVENT, "%s radar found when CAC \n", @@ -2650,11 +3032,36 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) #endif /* UAP_CFG80211 */ break; case MLAN_EVENT_ID_FW_RADAR_DETECTED: + radar_chan = pmevent->event_buf[0]; + snprintf(event_buf, sizeof(event_buf) - 1, "%s %d", + CUS_EVT_RADAR_DETECTED, radar_chan); + woal_broadcast_event(priv, event_buf, strlen(event_buf)); + PRINTM(MEVENT, "Radar detected on channel %d\n", radar_chan); + if ((priv->target_chan && priv->bss_started && + (priv->target_chan != radar_chan)) || + priv->backup_chan) { + PRINTM(MEVENT, "Move to target or backup chan %d %d\n", + priv->target_chan, priv->backup_chan); + woal_move_to_next_channel(priv); + priv->target_chan = 0; + break; + } #ifdef UAP_CFG80211 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 12, 0) if (!IS_STA_OR_UAP_CFG80211(cfg80211_wext)) break; + cfg_priv = woal_get_priv_with_wdev(priv->phandle); + if (cfg_priv) { + woal_update_channel_dfs_state(radar_chan, + DFS_UNAVAILABLE); + if (priv->bss_type == MLAN_BSS_TYPE_DFS) { + woal_chan_event(priv, WOAL_EVENT_RADAR, + priv->chan_rpt_req.chanNum, + MTRUE); + break; + } + } if (priv->phandle->is_cac_timer_set) { if (priv->bss_index == priv->phandle->cac_bss_index) { PRINTM(MEVENT, "radar detected during CAC \n"); @@ -2910,7 +3317,8 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) pchan_info->bandcfg.chanBand, pchan_info->bandcfg.chanWidth, pchan_info->bandcfg.chan2Offset); - if (priv->uap_host_based) + if (priv->uap_host_based && + (priv->channel != pchan_info->channel)) woal_channel_switch_event(priv, pchan_info); } #endif @@ -3494,6 +3902,8 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) #endif } break; case MLAN_EVENT_ID_DRV_FT_RESPONSE: + if (priv->phandle->fw_roam_enable) + break; #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) #ifdef STA_CFG80211 if (IS_STA_CFG80211(cfg80211_wext)) { @@ -3532,6 +3942,108 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) #endif #endif break; + case MLAN_EVENT_ID_FW_ROAM_OFFLOAD_RESULT: +#ifdef STA_CFG80211 +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) + woal_cfg80211_vendor_event(priv, event_set_key_mgmt_offload, + &enable, sizeof(enable)); +#endif + moal_memcpy_ext(priv->phandle, priv->cfg_bssid, + pmevent->event_buf, ETH_ALEN, ETH_ALEN); + tlv = (MrvlIEtypesHeader_t *)((t_u8 *)pmevent->event_buf + + MLAN_MAC_ADDR_LENGTH); + tlv_buf_left = pmevent->event_len - MLAN_MAC_ADDR_LENGTH; + while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t)) { + tlv_type = woal_le16_to_cpu(tlv->type); + tlv_len = woal_le16_to_cpu(tlv->len); + + if (tlv_buf_left < + (tlv_len + sizeof(MrvlIEtypesHeader_t))) { + PRINTM(MERROR, + "Error processing firmware roam success TLVs, bytes left < TLV length\n"); + break; + } + + switch (tlv_type) { + case TLV_TYPE_APINFO: + pinfo = (apinfo *)tlv; + break; + case TLV_TYPE_ASSOC_REQ_IE: + req_tlv = (apinfo *)tlv; + break; + default: + break; + } + tlv_buf_left -= tlv_len + sizeof(MrvlIEtypesHeader_t); + tlv = (MrvlIEtypesHeader_t + *)((t_u8 *)tlv + tlv_len + + sizeof(MrvlIEtypesHeader_t)); + } + if (!pinfo) { + PRINTM(MERROR, + "ERROR:AP info in roaming event buffer is NULL\n"); + goto done; + } + if (req_tlv) { + req_ie = req_tlv->rsp_ie; + ie_len = req_tlv->header.len; + } + woal_inform_bss_from_scan_result(priv, NULL, MOAL_NO_WAIT); +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + roam_info = + kzalloc(sizeof(struct cfg80211_roam_info), GFP_ATOMIC); + if (roam_info) { + roam_info->bssid = priv->cfg_bssid; + roam_info->req_ie = req_ie; + roam_info->req_ie_len = ie_len; + roam_info->resp_ie = pinfo->rsp_ie; + roam_info->resp_ie_len = pinfo->header.len; + cfg80211_roamed(priv->netdev, roam_info, GFP_KERNEL); + kfree(roam_info); + } +#else +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) + cfg80211_roamed(priv->netdev, NULL, priv->cfg_bssid, req_ie, + ie_len, pinfo->rsp_ie, pinfo->header.len, + GFP_KERNEL); +#else + cfg80211_roamed(priv->netdev, priv->cfg_bssid, req_ie, ie_len, + pinfo->rsp_ie, pinfo->header.len, GFP_KERNEL); +#endif +#endif + +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) + woal_roam_ap_info(priv, pmevent->event_buf, pmevent->event_len); +#endif +#endif + PRINTM(MMSG, "FW Roamed to bssid " MACSTR " successfully\n", + MAC2STR(pmevent->event_buf)); + break; + case MLAN_EVENT_ID_CSI: + DBG_HEXDUMP(MEVT_D, "CSI dump", pmevent->event_buf, + pmevent->event_len); +#ifdef STA_CFG80211 +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) + if (priv->csi_enable) + woal_cfg80211_event_csi_dump(priv, pmevent->event_buf, + pmevent->event_len); +#endif +#endif + /* Send Netlink event */ + custom_len = strlen(CUS_EVT_CSI) + sizeof(priv->csi_seq); + csi_len = pmevent->event_len; + memmove(pmevent->event_buf + custom_len, pmevent->event_buf, + csi_len); + moal_memcpy_ext(priv->phandle, pmevent->event_buf, CUS_EVT_CSI, + strlen(CUS_EVT_CSI), strlen(CUS_EVT_CSI)); + moal_memcpy_ext(priv->phandle, + pmevent->event_buf + strlen(CUS_EVT_CSI), + (t_u8 *)(&(priv->csi_seq)), + sizeof(priv->csi_seq), sizeof(priv->csi_seq)); + woal_broadcast_event(priv, pmevent->event_buf, + custom_len + csi_len); + priv->csi_seq++; + break; default: break; } diff --git a/mxm_wifiex/wlan_src/mlinux/moal_shim.h b/mxm_wifiex/wlan_src/mlinux/moal_shim.h index 5765ba7..c7f947e 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_shim.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_shim.h @@ -4,7 +4,7 @@ * functions defined in moal module * * - * Copyright 2008-2020 NXP + * Copyright 2008-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -122,6 +122,7 @@ void moal_tp_accounting_rx_param(t_void *pmoal, unsigned int type, void moal_amsdu_tp_accounting(t_void *pmoal, t_s32 amsdu_process_delay, t_s32 amsdu_copy_delay); +void moal_connection_status_check_pmqos(t_void *pmoal); #if defined(PCIE) || defined(SDIO) /* pmqos busfreq add request handler*/ void woal_request_busfreq_pmqos_add(t_void *pmhandle); diff --git a/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c b/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c index e60d74b..e6b70ba 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c @@ -3,7 +3,7 @@ * @brief This file contains the functions for STA CFG80211. * * - * Copyright 2011-2021 NXP + * Copyright 2011-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -53,6 +53,12 @@ static const u32 cfg80211_cipher_suites[] = { #endif }; +#ifdef UAP_SUPPORT +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) +static int woal_cfg80211_set_monitor_channel(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef); +#endif +#endif #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) static void #else @@ -395,6 +401,11 @@ static struct cfg80211_ops woal_cfg80211_ops = { .cancel_remain_on_channel = woal_cfg80211_cancel_remain_on_channel, #endif +#ifdef UAP_SUPPORT +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + .set_monitor_channel = woal_cfg80211_set_monitor_channel, +#endif +#endif #ifdef CONFIG_NL80211_TESTMODE .testmode_cmd = woal_testmode_cmd, #endif @@ -493,7 +504,7 @@ static const struct ieee80211_iface_limit cfg80211_ap_sta_limits[] = { {.max = 4, .types = MBIT(NL80211_IFTYPE_STATION) #ifdef UAP_CFG80211 - | MBIT(NL80211_IFTYPE_AP) + | MBIT(NL80211_IFTYPE_AP) | MBIT(NL80211_IFTYPE_MONITOR) #endif #ifdef WIFI_DIRECT_SUPPORT #if CFG80211_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION @@ -557,6 +568,99 @@ static const struct wiphy_coalesce_support coalesce_support = { /******************************************************** Local Functions ********************************************************/ +#ifdef UAP_SUPPORT +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) +static int woal_cfg80211_set_monitor_channel(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef) +{ + moal_handle *handle = (moal_handle *)woal_get_wiphy_priv(wiphy); + moal_private *priv = + (moal_private *)woal_get_priv(handle, MLAN_BSS_ROLE_STA); + netmon_band_chan_cfg band_chan_cfg; + t_u32 bandwidth = 0; + int ret = -EFAULT; + + ENTER(); + + if (!priv) { + ret = -EFAULT; + goto done; + } + if (handle->mon_if) { + if (cfg80211_chandef_identical(&handle->mon_if->chandef, + chandef)) { + ret = 0; + goto done; + } + + memset(&band_chan_cfg, 0x00, sizeof(band_chan_cfg)); + /* Set channel */ + band_chan_cfg.channel = ieee80211_frequency_to_channel( + chandef->chan->center_freq); + /* Set band */ + if (chandef->chan->band == IEEE80211_BAND_2GHZ) + band_chan_cfg.band |= (BAND_B | BAND_G); + if (chandef->chan->band == IEEE80211_BAND_5GHZ) + band_chan_cfg.band |= BAND_A; + if (chandef->chan->band == IEEE80211_BAND_2GHZ) + band_chan_cfg.band |= BAND_GN; + if (chandef->chan->band == IEEE80211_BAND_5GHZ) + band_chan_cfg.band |= BAND_AN; + if (chandef->chan->band == IEEE80211_BAND_2GHZ) + band_chan_cfg.band |= BAND_GAC; + if (chandef->chan->band == IEEE80211_BAND_5GHZ) + band_chan_cfg.band |= BAND_AAC; + /* Set bandwidth */ + if (chandef->width == NL80211_CHAN_WIDTH_20) + bandwidth = CHANNEL_BW_20MHZ; + else if (chandef->width == NL80211_CHAN_WIDTH_40) + bandwidth = chandef->center_freq1 > + chandef->chan->center_freq ? + CHANNEL_BW_40MHZ_ABOVE : + CHANNEL_BW_40MHZ_BELOW; + else if (chandef->width == NL80211_CHAN_WIDTH_80) + bandwidth = CHANNEL_BW_80MHZ; + band_chan_cfg.chan_bandwidth = bandwidth; + + if (MLAN_STATUS_SUCCESS != + woal_set_net_monitor(priv, MOAL_IOCTL_WAIT, + CHANNEL_SPEC_SNIFFER_MODE, 0x7, + &band_chan_cfg)) { + PRINTM(MERROR, "%s: woal_set_net_monitor fail\n", + __func__); + ret = -EFAULT; + goto done; + } + + moal_memcpy_ext(priv->phandle, &handle->mon_if->band_chan_cfg, + &band_chan_cfg, + sizeof(handle->mon_if->band_chan_cfg), + sizeof(handle->mon_if->band_chan_cfg)); + handle->mon_if->chandef = *chandef; + + if (handle->mon_if->chandef.chan) + PRINTM(MINFO, + "set_monitor_channel+++ chan[band=%d center_freq=%d hw_value=%d] width=%d center_freq1=%d center_freq2=%d\n", + handle->mon_if->chandef.chan->band, + handle->mon_if->chandef.chan->center_freq, + handle->mon_if->chandef.chan->hw_value, + handle->mon_if->chandef.width, + handle->mon_if->chandef.center_freq1, + handle->mon_if->chandef.center_freq2); + PRINTM(MINFO, + "set_monitor_channel+++ band=%x channel=%d bandwidth=%d\n", + handle->mon_if->band_chan_cfg.band, + handle->mon_if->band_chan_cfg.channel, + handle->mon_if->band_chan_cfg.chan_bandwidth); + ret = 0; + } + +done: + LEAVE(); + return ret; +} +#endif +#endif /** * @brief This function check cfg80211 special region code. @@ -1069,9 +1173,9 @@ static mlan_status woal_send_domain_info_cmd_fw(moal_private *priv, goto done; } - PRINTM(MCMD_D, "Send domain info: country=%c%c band=%d\n", + PRINTM(MCMD_D, "Send domain info: country=%c%c band=%d dfs_region=%d\n", priv->phandle->country_code[0], priv->phandle->country_code[1], - band); + band, priv->phandle->dfs_region); /* Allocate an IOCTL request buffer */ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11d_cfg)); if (req == NULL) { @@ -1082,7 +1186,7 @@ static mlan_status woal_send_domain_info_cmd_fw(moal_private *priv, cfg_11d->sub_command = MLAN_OID_11D_DOMAIN_INFO_EXT; req->req_id = MLAN_IOCTL_11D_CFG; req->action = MLAN_ACT_SET; - + cfg_11d->param.domain_info.dfs_region = priv->phandle->dfs_region; if (is_cfg80211_special_region_code(priv->phandle->country_code)) { /* Set country code */ cfg_11d->param.domain_info.country_code[0] = 'W'; @@ -1627,6 +1731,7 @@ static int woal_process_country_ie(moal_private *priv, struct cfg80211_bss *bss) req->req_id = MLAN_IOCTL_11D_CFG; req->action = MLAN_ACT_SET; + cfg_11d->param.domain_info.dfs_region = NXP_DFS_UNKNOWN; /* Set country code */ cfg_11d->param.domain_info.country_code[0] = priv->phandle->country_code[0]; @@ -1683,7 +1788,7 @@ woal_cfg80211_connect_scan(moal_private *priv, { moal_handle *handle = priv->phandle; int ret = 0; - wlan_user_scan_cfg scan_req; + wlan_user_scan_cfg *scan_req; enum ieee80211_band band; struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; @@ -1702,25 +1807,34 @@ woal_cfg80211_connect_scan(moal_private *priv, return -EBUSY; } #endif /* REASSOCIATION */ + scan_req = (wlan_user_scan_cfg *)kmalloc(sizeof(wlan_user_scan_cfg), + GFP_KERNEL); + if (!scan_req) { + PRINTM(MERROR, "Malloc buffer failed\n"); + LEAVE(); + return -ENOMEM; + } + priv->report_scan_result = MTRUE; - memset(&scan_req, 0x00, sizeof(scan_req)); - moal_memcpy_ext(priv->phandle, scan_req.ssid_list[0].ssid, + memset(scan_req, 0x00, sizeof(wlan_user_scan_cfg)); + moal_memcpy_ext(priv->phandle, scan_req->ssid_list[0].ssid, conn_param->ssid, conn_param->ssid_len, - sizeof(scan_req.ssid_list[0].ssid)); - scan_req.ssid_list[0].max_len = 0; + sizeof(scan_req->ssid_list[0].ssid)); + scan_req->ssid_list[0].max_len = 0; if (conn_param->channel) { - scan_req.chan_list[0].chan_number = + scan_req->chan_list[0].chan_number = conn_param->channel->hw_value; - scan_req.chan_list[0].radio_type = conn_param->channel->band; + scan_req->chan_list[0].radio_type = conn_param->channel->band; if (conn_param->channel->flags & IEEE80211_CHAN_PASSIVE_SCAN) - scan_req.chan_list[0].scan_type = + scan_req->chan_list[0].scan_type = MLAN_SCAN_TYPE_PASSIVE; else if (conn_param->channel->flags & IEEE80211_CHAN_RADAR) - scan_req.chan_list[0].scan_type = + scan_req->chan_list[0].scan_type = MLAN_SCAN_TYPE_PASSIVE_TO_ACTIVE; else - scan_req.chan_list[0].scan_type = MLAN_SCAN_TYPE_ACTIVE; - scan_req.chan_list[0].scan_time = 0; + scan_req->chan_list[0].scan_type = + MLAN_SCAN_TYPE_ACTIVE; + scan_req->chan_list[0].scan_time = 0; } else { for (band = 0; (band < IEEE80211_NUM_BANDS); band++) { if (!priv->wdev->wiphy->bands[band]) @@ -1730,25 +1844,26 @@ woal_cfg80211_connect_scan(moal_private *priv, ch = &sband->channels[i]; if (ch->flags & IEEE80211_CHAN_DISABLED) continue; - scan_req.chan_list[chan_idx].radio_type = band; + scan_req->chan_list[chan_idx].radio_type = band; if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) - scan_req.chan_list[chan_idx].scan_type = + scan_req->chan_list[chan_idx].scan_type = MLAN_SCAN_TYPE_PASSIVE; else if (ch->flags & IEEE80211_CHAN_RADAR) - scan_req.chan_list[chan_idx].scan_type = + scan_req->chan_list[chan_idx].scan_type = MLAN_SCAN_TYPE_PASSIVE_TO_ACTIVE; else - scan_req.chan_list[chan_idx].scan_type = + scan_req->chan_list[chan_idx].scan_type = MLAN_SCAN_TYPE_ACTIVE; - scan_req.chan_list[chan_idx].chan_number = + scan_req->chan_list[chan_idx].chan_number = (u32)ch->hw_value; chan_idx++; } } } - moal_memcpy_ext(priv->phandle, scan_req.random_mac, priv->random_mac, - ETH_ALEN, sizeof(scan_req.random_mac)); - ret = woal_request_userscan(priv, wait_option, &scan_req); + moal_memcpy_ext(priv->phandle, scan_req->random_mac, priv->random_mac, + ETH_ALEN, sizeof(scan_req->random_mac)); + ret = woal_request_userscan(priv, wait_option, scan_req); + kfree(scan_req); #ifdef REASSOCIATION MOAL_REL_SEMAPHORE(&handle->reassoc_sem); #endif @@ -1855,7 +1970,7 @@ static int woal_cfg80211_auth_scan(moal_private *priv, { moal_handle *handle = priv->phandle; int ret = 0; - wlan_user_scan_cfg scan_req; + wlan_user_scan_cfg *scan_req; enum ieee80211_band band; struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; @@ -1875,31 +1990,41 @@ static int woal_cfg80211_auth_scan(moal_private *priv, return -EBUSY; } #endif /* REASSOCIATION */ + scan_req = (wlan_user_scan_cfg *)kmalloc(sizeof(wlan_user_scan_cfg), + GFP_KERNEL); + if (!scan_req) { + PRINTM(MERROR, "Malloc buffer failed\n"); + LEAVE(); + return -ENOMEM; + } + priv->report_scan_result = MTRUE; - memset(&scan_req, 0x00, sizeof(scan_req)); + memset(scan_req, 0x00, sizeof(wlan_user_scan_cfg)); rcu_read_lock(); ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); if (ssid) { - moal_memcpy_ext(priv->phandle, scan_req.ssid_list[0].ssid, + moal_memcpy_ext(priv->phandle, scan_req->ssid_list[0].ssid, ssid + 2, ssid[1], - sizeof(scan_req.ssid_list[0].ssid)); - scan_req.ssid_list[0].max_len = 0; + sizeof(scan_req->ssid_list[0].ssid)); + scan_req->ssid_list[0].max_len = 0; } rcu_read_unlock(); - moal_memcpy_ext(priv->phandle, scan_req.specific_bssid, req->bss->bssid, - ETH_ALEN, ETH_ALEN); + moal_memcpy_ext(priv->phandle, scan_req->specific_bssid, + req->bss->bssid, ETH_ALEN, ETH_ALEN); if (req->bss->channel) { - scan_req.chan_list[0].chan_number = req->bss->channel->hw_value; - scan_req.chan_list[0].radio_type = req->bss->channel->band; + scan_req->chan_list[0].chan_number = + req->bss->channel->hw_value; + scan_req->chan_list[0].radio_type = req->bss->channel->band; if (req->bss->channel->flags & IEEE80211_CHAN_PASSIVE_SCAN) - scan_req.chan_list[0].scan_type = + scan_req->chan_list[0].scan_type = MLAN_SCAN_TYPE_PASSIVE; else if (req->bss->channel->flags & IEEE80211_CHAN_RADAR) - scan_req.chan_list[0].scan_type = + scan_req->chan_list[0].scan_type = MLAN_SCAN_TYPE_PASSIVE_TO_ACTIVE; else - scan_req.chan_list[0].scan_type = MLAN_SCAN_TYPE_ACTIVE; - scan_req.chan_list[0].scan_time = 0; + scan_req->chan_list[0].scan_type = + MLAN_SCAN_TYPE_ACTIVE; + scan_req->chan_list[0].scan_time = 0; } else { for (band = 0; (band < IEEE80211_NUM_BANDS); band++) { if (!priv->wdev->wiphy->bands[band]) @@ -1909,25 +2034,26 @@ static int woal_cfg80211_auth_scan(moal_private *priv, ch = &sband->channels[i]; if (ch->flags & IEEE80211_CHAN_DISABLED) continue; - scan_req.chan_list[chan_idx].radio_type = band; + scan_req->chan_list[chan_idx].radio_type = band; if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) - scan_req.chan_list[chan_idx].scan_type = + scan_req->chan_list[chan_idx].scan_type = MLAN_SCAN_TYPE_PASSIVE; else if (ch->flags & IEEE80211_CHAN_RADAR) - scan_req.chan_list[chan_idx].scan_type = + scan_req->chan_list[chan_idx].scan_type = MLAN_SCAN_TYPE_PASSIVE_TO_ACTIVE; else - scan_req.chan_list[chan_idx].scan_type = + scan_req->chan_list[chan_idx].scan_type = MLAN_SCAN_TYPE_ACTIVE; - scan_req.chan_list[chan_idx].chan_number = + scan_req->chan_list[chan_idx].chan_number = (u32)ch->hw_value; chan_idx++; } } } - moal_memcpy_ext(priv->phandle, scan_req.random_mac, priv->random_mac, - ETH_ALEN, sizeof(scan_req.random_mac)); - ret = woal_request_userscan(priv, wait_option, &scan_req); + moal_memcpy_ext(priv->phandle, scan_req->random_mac, priv->random_mac, + ETH_ALEN, sizeof(scan_req->random_mac)); + ret = woal_request_userscan(priv, wait_option, scan_req); + kfree(scan_req); #ifdef REASSOCIATION MOAL_REL_SEMAPHORE(&handle->reassoc_sem); #endif @@ -1972,6 +2098,7 @@ static int woal_cfg80211_authenticate(struct wiphy *wiphy, priv->cfg_disconnect = MFALSE; #ifdef UAP_CFG80211 if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) { + PRINTM(MERROR, "ERR: Role is AP\n"); LEAVE(); return -EFAULT; } @@ -2092,6 +2219,7 @@ static int woal_cfg80211_authenticate(struct wiphy *wiphy, KEY_INDEX_CLEAR_ALL, NULL, 1, MOAL_IOCTL_WAIT)) { /* Disable keys and clear all previous security settings */ + PRINTM(MERROR, "Fail to clear previous keys\n"); ret = -EFAULT; goto done; } @@ -2121,6 +2249,7 @@ static int woal_cfg80211_authenticate(struct wiphy *wiphy, goto done; if (MLAN_STATUS_SUCCESS != woal_set_auth_mode(priv, MOAL_IOCTL_WAIT, auth_alg)) { + PRINTM(MERROR, "Fail to set auth mode\n"); ret = -EFAULT; goto done; } @@ -2133,6 +2262,8 @@ static int woal_cfg80211_authenticate(struct wiphy *wiphy, if (MLAN_STATUS_SUCCESS != woal_cfg80211_set_wep_keys(priv, req->key, req->key_len, req->key_idx, MOAL_IOCTL_WAIT)) { + PRINTM(MERROR, "Fail to set wep key idx %d\n", + req->key_idx); ret = -EFAULT; goto done; } @@ -2140,6 +2271,8 @@ static int woal_cfg80211_authenticate(struct wiphy *wiphy, if (MLAN_STATUS_SUCCESS != woal_cfg80211_set_wep_keys(priv, NULL, 0, req->key_idx, MOAL_IOCTL_WAIT)) { + PRINTM(MERROR, "Fail to enable wep key idx %d\n", + req->key_idx); ret = -EFAULT; goto done; } @@ -2253,7 +2386,7 @@ static int woal_cfg80211_authenticate(struct wiphy *wiphy, priv->auth_flag = HOST_MLME_AUTH_PENDING; priv->auth_alg = woal_cpu_to_le16(auth_alg); - PRINTM(MCMND, "wlan: HostMlme %s send auth to bssid " MACSTR "\n", + PRINTM(MMSG, "wlan: HostMlme %s send auth to bssid " MACSTR "\n", dev->name, MAC2STR(req->bss->bssid)); DBG_HEXDUMP(MDAT_D, "Auth:", pmbuf->pbuf + pmbuf->data_offset, pmbuf->data_len); @@ -2276,6 +2409,7 @@ static int woal_cfg80211_authenticate(struct wiphy *wiphy, priv->auth_flag = 0; priv->auth_alg = 0xFFFF; ret = -EFAULT; + PRINTM(MERROR, "Fail to send packet status=%d\n", status); break; } done: @@ -3522,12 +3656,14 @@ woal_reg_apply_beaconing_flags(struct wiphy *wiphy, /** * @brief This function create the custom regdomain * + * @param priv pointer to moal_private * @param custom_reg pointer to mlan_ds_custom_reg_domain * * @return pointer to ieee80211_regdomain */ static struct ieee80211_regdomain * -create_custom_regdomain(mlan_ds_custom_reg_domain *custom_reg) +create_custom_regdomain(moal_private *priv, + mlan_ds_custom_reg_domain *custom_reg) { struct ieee80211_reg_rule *rule; bool new_rule; @@ -3642,7 +3778,7 @@ create_custom_regdomain(mlan_ds_custom_reg_domain *custom_reg) regd->dfs_region = NL80211_DFS_UNSET; break; } - + priv->phandle->dfs_region = regd->dfs_region; PRINTM(MCMND, "create_custom_regdomain: %c%c rules=%d dfs_region=%d\n", regd->alpha2[0], regd->alpha2[1], valid_rules, regd->dfs_region); for (idx = 0; idx < (int)regd->n_reg_rules; idx++) { @@ -3726,7 +3862,7 @@ static int woal_update_custom_regdomain(moal_private *priv, struct wiphy *wiphy) misc->param.custom_reg_domain.region.country_code[1], country_code[0], country_code[1]); } - regd = create_custom_regdomain(&misc->param.custom_reg_domain); + regd = create_custom_regdomain(priv, &misc->param.custom_reg_domain); if (regd) { PRINTM(MMSG, "call regulatory_set_wiphy_regd %c%c", misc->param.custom_reg_domain.region.country_code[0], @@ -3773,8 +3909,10 @@ void woal_regulatory_work_queue(struct work_struct *work) band = priv->phandle->band; priv->phandle->band = IEEE80211_BAND_2GHZ; woal_send_domain_info_cmd_fw(priv, MOAL_IOCTL_WAIT); - priv->phandle->band = IEEE80211_BAND_5GHZ; - woal_send_domain_info_cmd_fw(priv, MOAL_IOCTL_WAIT); + if (priv->phandle->fw_bands & BAND_A) { + priv->phandle->band = IEEE80211_BAND_5GHZ; + woal_send_domain_info_cmd_fw(priv, MOAL_IOCTL_WAIT); + } priv->phandle->band = band; } } @@ -3824,8 +3962,14 @@ woal_cfg80211_reg_notifier(struct wiphy *wiphy, PRINTM(MCMND, "cfg80211 regulatory domain callback " - "%c%c initiator=%d\n", - request->alpha2[0], request->alpha2[1], request->initiator); + "%c%c initiator=%d dfs_region=%d\n", + request->alpha2[0], request->alpha2[1], request->initiator, + request->dfs_region); +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) + if (!(wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)) +#endif + handle->dfs_region = request->dfs_region; + memset(&fw_info, 0, sizeof(mlan_fw_info)); woal_request_get_fw_info(priv, MOAL_IOCTL_WAIT, &fw_info); if (fw_info.force_reg) { @@ -3875,15 +4019,15 @@ woal_cfg80211_reg_notifier(struct wiphy *wiphy, load_power_table = MTRUE; } } - if (MTRUE != is_cfg80211_special_region_code(region)) { - if (!handle->params.cntry_txpwr) { - handle->country_code[0] = request->alpha2[0]; - handle->country_code[1] = request->alpha2[1]; - handle->country_code[2] = ' '; + if (!handle->params.cntry_txpwr) { + handle->country_code[0] = request->alpha2[0]; + handle->country_code[1] = request->alpha2[1]; + handle->country_code[2] = ' '; + if (MTRUE != is_cfg80211_special_region_code(region)) { + if (MLAN_STATUS_SUCCESS != + woal_set_region_code(priv, handle->country_code)) + PRINTM(MERROR, "Set country code failed!\n"); } - if (MLAN_STATUS_SUCCESS != - woal_set_region_code(priv, handle->country_code)) - PRINTM(MERROR, "Set country code failed!\n"); } switch (request->initiator) { case NL80211_REGDOM_SET_BY_DRIVER: @@ -3920,12 +4064,17 @@ woal_cfg80211_reg_notifier(struct wiphy *wiphy, break; } if (priv->wdev && priv->wdev->wiphy && +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) + !(wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) && +#endif (request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE)) { band = priv->phandle->band; priv->phandle->band = IEEE80211_BAND_2GHZ; woal_send_domain_info_cmd_fw(priv, MOAL_IOCTL_WAIT); - priv->phandle->band = IEEE80211_BAND_5GHZ; - woal_send_domain_info_cmd_fw(priv, MOAL_IOCTL_WAIT); + if (priv->phandle->fw_bands & BAND_A) { + priv->phandle->band = IEEE80211_BAND_5GHZ; + woal_send_domain_info_cmd_fw(priv, MOAL_IOCTL_WAIT); + } priv->phandle->band = band; } @@ -4372,10 +4521,8 @@ static int woal_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, if (scan_req->scan_chan_gap && priv->phandle->pref_mac) scan_req->scan_chan_gap |= GAP_FLAG_OPTIONAL; - if (priv->phandle->scan_request->n_channels <= 38) { - if (scan_cfg.ext_scan == 3) - scan_req->ext_scan_type = EXT_SCAN_ENHANCE; - } + if (scan_cfg.ext_scan == 3) + scan_req->ext_scan_type = EXT_SCAN_ENHANCE; for (i = 0; i < priv->phandle->scan_request->n_ssids; i++) { moal_memcpy_ext(priv->phandle, scan_req->ssid_list[i].ssid, @@ -5544,9 +5691,23 @@ static int woal_cfg80211_get_channel(struct wiphy *wiphy, { moal_private *priv = (moal_private *)woal_get_netdev_priv(wdev->netdev); chan_band_info channel; +#ifdef UAP_SUPPORT + moal_handle *handle = (moal_handle *)woal_get_wiphy_priv(wiphy); +#endif memset(&channel, 0x00, sizeof(channel)); +#ifdef UAP_SUPPORT + if (wdev->iftype == NL80211_IFTYPE_MONITOR) { + if ((handle->mon_if) && + (handle->mon_if->mon_ndev == wdev->netdev)) { + *chandef = handle->mon_if->chandef; + return 0; + } + return -EFAULT; + } +#endif + #ifdef UAP_SUPPORT if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) { if (priv->bss_started == MTRUE) { @@ -6391,6 +6552,7 @@ int woal_cfg80211_resume(struct wiphy *wiphy) handle->priv[i]->roaming_enabled) { handle->priv[i]->roaming_required = MTRUE; +#ifdef ANDROID_KERNEL #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) __pm_wakeup_event( &handle->ws, @@ -6401,6 +6563,7 @@ int woal_cfg80211_resume(struct wiphy *wiphy) msecs_to_jiffies( ROAMING_WAKE_LOCK_TIMEOUT)); #endif +#endif #ifdef REASSOCIATION wake_up_interruptible( &handle->reassoc_thread.wait_q); @@ -7171,12 +7334,17 @@ static int woal_construct_tdls_data_frame(moal_private *priv, t_u8 *peer, IEEEtypes_VHTCap_t *VHTcap; IEEEtypes_VHTOprat_t *vht_oprat; IEEEtypes_AID_t *AidInfo; + IEEEtypes_Header_t *ieee_hdr; + t_u8 *skb_data; + t_u8 len = 0; IEEEtypes_Generic_t *pSupp_chan = NULL, *pRegulatory_class = NULL; mlan_ds_misc_tdls_ies *tdls_ies = NULL; int ret = 0; mlan_bss_info bss_info; enum ieee80211_band band; mlan_fw_info fw_info; + t_u16 setup_flag = 0; + t_u16 confirm_flag = 0; ENTER(); @@ -7207,22 +7375,27 @@ static int woal_construct_tdls_data_frame(moal_private *priv, t_u8 *peer, tdata->payload_type = WLAN_TDLS_SNAP_RFTYPE; woal_request_get_fw_info(priv, MOAL_IOCTL_WAIT, &fw_info); + setup_flag = TDLS_IE_FLAGS_EXTCAP | TDLS_IE_FLAGS_HTCAP | + TDLS_IE_FLAGS_SUPP_CS_IE; + confirm_flag = TDLS_IE_FLAGS_EXTCAP | TDLS_IE_FLAGS_HTINFO | + TDLS_IE_FLAGS_QOS_INFO; + if (fw_info.fw_bands & BAND_AAC) { + setup_flag |= (TDLS_IE_FLAGS_VHTCAP | TDLS_IE_FLAGS_AID); + confirm_flag |= TDLS_IE_FLAGS_VHTOPRAT; + } + if (fw_info.fw_bands & BAND_AAX) { + setup_flag |= (TDLS_IE_FLAGS_VHTCAP | TDLS_IE_FLAGS_AID | + TDLS_IE_FLAGS_HECAP); + confirm_flag |= (TDLS_IE_FLAGS_VHTOPRAT | TDLS_IE_FLAGS_HEOP); + } + if (fw_info.fw_bands & BAND_GAX) { + setup_flag |= TDLS_IE_FLAGS_HECAP; + confirm_flag |= TDLS_IE_FLAGS_HEOP; + } switch (action_code) { case WLAN_TDLS_SETUP_REQUEST: - if (fw_info.fw_bands & BAND_AAC) - woal_tdls_get_ies(priv, peer, tdls_ies, - TDLS_IE_FLAGS_SETUP | - TDLS_IE_FLAGS_EXTCAP | - TDLS_IE_FLAGS_HTCAP | - TDLS_IE_FLAGS_VHTCAP | - TDLS_IE_FLAGS_AID | - TDLS_IE_FLAGS_SUPP_CS_IE); - else - woal_tdls_get_ies(priv, peer, tdls_ies, - TDLS_IE_FLAGS_SETUP | - TDLS_IE_FLAGS_EXTCAP | - TDLS_IE_FLAGS_HTCAP | - TDLS_IE_FLAGS_SUPP_CS_IE); + setup_flag |= TDLS_IE_FLAGS_SETUP; + woal_tdls_get_ies(priv, peer, tdls_ies, setup_flag); tdata->category = WLAN_CATEGORY_TDLS; tdata->action_code = WLAN_TDLS_SETUP_REQUEST; @@ -7233,18 +7406,7 @@ static int woal_construct_tdls_data_frame(moal_private *priv, t_u8 *peer, woal_add_ext_supported_rates_ie(priv, skb, band); break; case WLAN_TDLS_SETUP_RESPONSE: - if (fw_info.fw_bands & BAND_AAC) - woal_tdls_get_ies(priv, peer, tdls_ies, - TDLS_IE_FLAGS_EXTCAP | - TDLS_IE_FLAGS_HTCAP | - TDLS_IE_FLAGS_VHTCAP | - TDLS_IE_FLAGS_AID | - TDLS_IE_FLAGS_SUPP_CS_IE); - else - woal_tdls_get_ies(priv, peer, tdls_ies, - TDLS_IE_FLAGS_EXTCAP | - TDLS_IE_FLAGS_HTCAP | - TDLS_IE_FLAGS_SUPP_CS_IE); + woal_tdls_get_ies(priv, peer, tdls_ies, setup_flag); tdata->category = WLAN_CATEGORY_TDLS; tdata->action_code = WLAN_TDLS_SETUP_RESPONSE; @@ -7258,17 +7420,7 @@ static int woal_construct_tdls_data_frame(moal_private *priv, t_u8 *peer, woal_add_ext_supported_rates_ie(priv, skb, band); break; case WLAN_TDLS_SETUP_CONFIRM: - if (fw_info.fw_bands & BAND_AAC) - woal_tdls_get_ies(priv, peer, tdls_ies, - TDLS_IE_FLAGS_EXTCAP | - TDLS_IE_FLAGS_HTINFO | - TDLS_IE_FLAGS_VHTOPRAT | - TDLS_IE_FLAGS_QOS_INFO); - else - woal_tdls_get_ies(priv, peer, tdls_ies, - TDLS_IE_FLAGS_EXTCAP | - TDLS_IE_FLAGS_HTINFO | - TDLS_IE_FLAGS_QOS_INFO); + woal_tdls_get_ies(priv, peer, tdls_ies, confirm_flag); tdata->category = WLAN_CATEGORY_TDLS; tdata->action_code = WLAN_TDLS_SETUP_CONFIRM; @@ -7378,6 +7530,17 @@ static int woal_construct_tdls_data_frame(moal_private *priv, t_u8 *peer, } else { PRINTM(MIOCTL, "No TDLS AID info\n"); } + /* HE capability */ + if (tdls_ies->he_cap[2] == HE_CAPABILITY) { + ieee_hdr = (IEEEtypes_Header_t *)tdls_ies->he_cap; + len = sizeof(IEEEtypes_Header_t) + ieee_hdr->len; + skb_data = (void *)skb_put(skb, len); + memset(skb_data, 0, len); + moal_memcpy_ext(priv->phandle, skb_data, + tdls_ies->he_cap, len, len); + } else { + PRINTM(MIOCTL, "NO TDLS HE Capability IE\n"); + } break; case WLAN_TDLS_SETUP_CONFIRM: /*HT information*/ @@ -7402,6 +7565,16 @@ static int woal_construct_tdls_data_frame(moal_private *priv, t_u8 *peer, sizeof(IEEEtypes_VHTOprat_t)); } else PRINTM(MIOCTL, "NO TDLS VHT Operation IE\n"); + /** HE operation */ + if (tdls_ies->he_op[2] == HE_OPERATION) { + ieee_hdr = (IEEEtypes_Header_t *)tdls_ies->he_op; + len = sizeof(IEEEtypes_Header_t) + ieee_hdr->len; + skb_data = (void *)skb_put(skb, len); + memset(skb_data, 0, len); + moal_memcpy_ext(priv->phandle, skb_data, + tdls_ies->he_op, len, len); + } else + PRINTM(MIOCTL, "NO TDLS HE Operation IE\n"); break; default: break; @@ -7735,6 +7908,7 @@ static int woal_send_tdls_data_frame(struct wiphy *wiphy, sizeof(IEEEtypes_HTCap_t) + sizeof(IEEEtypes_2040BSSCo_t) + sizeof(IEEEtypes_HTInfo_t) + sizeof(IEEEtypes_VHTCap_t) + sizeof(IEEEtypes_VHTOprat_t) + sizeof(IEEEtypes_AID_t) + + sizeof(IEEEtypes_HECap_t) + sizeof(IEEEtypes_HeOp_t) + extra_ies_len + sizeof(IEEEtypes_tdls_linkie)); if (!skb) return -ENOMEM; @@ -8923,7 +9097,7 @@ int woal_cfg80211_uap_add_station(struct wiphy *wiphy, struct net_device *dev, ENTER(); req_len = sizeof(mlan_ds_bss); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) if (params->ext_capab_len) req_len += sizeof(MrvlIEtypesHeader_t) + params->ext_capab_len; #endif @@ -8938,7 +9112,7 @@ int woal_cfg80211_uap_add_station(struct wiphy *wiphy, struct net_device *dev, if (params->vht_capa) req_len += sizeof(MrvlIEtypesHeader_t) + sizeof(struct ieee80211_vht_cap); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) if (params->opmode_notif_used) req_len += sizeof(MrvlIEtypesHeader_t) + sizeof(u8); #endif @@ -8980,7 +9154,7 @@ int woal_cfg80211_uap_add_station(struct wiphy *wiphy, struct net_device *dev, params->sta_flags_set, params->listen_interval, params->aid); #endif pos = &bss->param.sta_info.tlv[0]; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) if (params->ext_capab_len) { tlv = (MrvlIEtypes_Data_t *)pos; tlv->header.type = EXT_CAPABILITY; @@ -9039,7 +9213,7 @@ int woal_cfg80211_uap_add_station(struct wiphy *wiphy, struct net_device *dev, sizeof(MrvlIEtypesHeader_t) + tlv->header.len; tlv = (MrvlIEtypes_Data_t *)pos; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) if (params->opmode_notif_used) { tlv = (MrvlIEtypes_Data_t *)pos; tlv->header.type = OPER_MODE_NTF; @@ -9151,7 +9325,7 @@ void woal_host_mlme_disconnect(moal_private *priv, u16 reason_code, u8 *sa) } if (GET_BSS_ROLE(priv) != MLAN_BSS_ROLE_UAP) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) mutex_lock(&priv->wdev->mtx); cfg80211_rx_mlme_mgmt(priv->netdev, frame_buf, 26); mutex_unlock(&priv->wdev->mtx); @@ -9257,8 +9431,10 @@ mlan_status woal_register_sta_cfg80211(struct net_device *dev, t_u8 bss_type) band = priv->phandle->band; priv->phandle->band = IEEE80211_BAND_2GHZ; woal_send_domain_info_cmd_fw(priv, MOAL_IOCTL_WAIT); - priv->phandle->band = IEEE80211_BAND_5GHZ; - woal_send_domain_info_cmd_fw(priv, MOAL_IOCTL_WAIT); + if (priv->phandle->fw_bands & BAND_A) { + priv->phandle->band = IEEE80211_BAND_5GHZ; + woal_send_domain_info_cmd_fw(priv, MOAL_IOCTL_WAIT); + } priv->phandle->band = band; } LEAVE(); @@ -9548,6 +9724,7 @@ mlan_status woal_register_cfg80211(moal_private *priv) wiphy->interface_modes = 0; wiphy->interface_modes = MBIT(NL80211_IFTYPE_STATION) | MBIT(NL80211_IFTYPE_AP); + wiphy->interface_modes |= MBIT(NL80211_IFTYPE_MONITOR); #ifdef WIFI_DIRECT_SUPPORT #if CFG80211_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION @@ -9565,12 +9742,8 @@ mlan_status woal_register_cfg80211(moal_private *priv) if (!fw_info.fw_bands) fw_info.fw_bands = BAND_B | BAND_G; if (fw_info.fw_bands & BAND_A) { - if (priv->phandle->second_mac) - wiphy->bands[IEEE80211_BAND_5GHZ] = - &mac1_cfg80211_band_5ghz; - else - - wiphy->bands[IEEE80211_BAND_5GHZ] = &cfg80211_band_5ghz; + wiphy->bands[IEEE80211_BAND_5GHZ] = + woal_setup_wiphy_bands(IEEE80211_BAND_5GHZ); #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) woal_update_channel_flag(wiphy, &fw_info); #endif @@ -9578,11 +9751,8 @@ mlan_status woal_register_cfg80211(moal_private *priv) } /* Supported bands */ if (fw_info.fw_bands & (BAND_B | BAND_G | BAND_GN | BAND_GAC)) { - if (priv->phandle->second_mac) - wiphy->bands[IEEE80211_BAND_2GHZ] = - &mac1_cfg80211_band_2ghz; - else - wiphy->bands[IEEE80211_BAND_2GHZ] = &cfg80211_band_2ghz; + wiphy->bands[IEEE80211_BAND_2GHZ] = + woal_setup_wiphy_bands(IEEE80211_BAND_2GHZ); /* If 2.4G enable, it will overwrite default to 2.4G*/ priv->phandle->band = IEEE80211_BAND_2GHZ; } @@ -9649,10 +9819,12 @@ mlan_status woal_register_cfg80211(moal_private *priv) #endif wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME; #endif +#ifdef ANDROID_KERNEL #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) if (!moal_extflg_isset(priv->phandle, EXT_HOST_MLME)) #endif wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME; +#endif #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) if (priv->phandle->params.sched_scan) { @@ -9766,6 +9938,7 @@ mlan_status woal_register_cfg80211(moal_private *priv) memset(&priv->phandle->country_code, 0, sizeof(priv->phandle->country_code)); + priv->phandle->dfs_region = NXP_DFS_UNKNOWN; if (reg_alpha2 && !strncmp(reg_alpha2, "99", strlen("99"))) { #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) @@ -9798,6 +9971,8 @@ mlan_status woal_register_cfg80211(moal_private *priv) goto err_wiphy; } + wiphy->interface_modes &= ~(MBIT(NL80211_IFTYPE_MONITOR)); + #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) if (fw_info.force_reg || (priv->phandle->params.txpwrlimit_cfg && @@ -9846,8 +10021,10 @@ mlan_status woal_register_cfg80211(moal_private *priv) priv->phandle->wiphy = wiphy; return ret; err_wiphy: - if (wiphy) + if (wiphy) { + woal_cfg80211_free_bands(wiphy); wiphy_free(wiphy); + } LEAVE(); return ret; } diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap.c b/mxm_wifiex/wlan_src/mlinux/moal_uap.c index 0f890ef..9396fbf 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap.c @@ -4,7 +4,7 @@ * driver. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -738,6 +738,40 @@ done: } #endif +/** + * @brief enable/disable 11h + * + * @param enable MTRUE/MFALSE + * @return 0 --success, otherwise fail + */ +int woal_uap_11h_ctrl(moal_private *priv, t_u32 enable) +{ + mlan_ioctl_req *ioctl_req = NULL; + mlan_ds_snmp_mib *snmp = NULL; + int ret = 0; + mlan_status status = MLAN_STATUS_SUCCESS; + ENTER(); + ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_snmp_mib)); + if (ioctl_req == NULL) { + LEAVE(); + return -ENOMEM; + } + snmp = (mlan_ds_snmp_mib *)ioctl_req->pbuf; + ioctl_req->req_id = MLAN_IOCTL_SNMP_MIB; + snmp->sub_command = MLAN_OID_SNMP_MIB_DOT11H; + snmp->param.oid_value = enable; + status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } +done: + if (status != MLAN_STATUS_PENDING) + kfree(ioctl_req); + LEAVE(); + return ret; +} + /** * @brief configure snmp mib * @@ -2053,7 +2087,75 @@ done: } /** - * @brief Set/Get skip CAC mode + * @brief Issue MLAN_OID_11H_CHAN_REPORT_REQUEST ioctl to cancel dozer + * + * @param priv Pointer to the moal_private driver data struct + * @param action MLAN_ACT_SET/MLAN_ACT_GET + * @param + * + * @return 0 --success, otherwise fail + */ +int woal_11h_chan_dfs_state(moal_private *priv, t_u8 action, + mlan_ds_11h_chan_dfs_state *ch_dfs_state) +{ + int ret = 0; + mlan_ioctl_req *req = NULL; + mlan_ds_11h_cfg *ds_11hcfg = NULL; + mlan_status status = MLAN_STATUS_SUCCESS; +#ifdef UAP_CFG80211 +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) + int cfg80211_wext = priv->phandle->params.cfg80211_wext; +#endif +#endif + + ENTER(); +#ifdef UAP_CFG80211 +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) + if (action == MLAN_ACT_GET) { + if (IS_UAP_CFG80211(cfg80211_wext)) { + ret = woal_get_wiphy_chan_dfs_state(priv->wdev->wiphy, + ch_dfs_state); + if (!ret) { + LEAVE(); + return ret; + } + } + } +#endif +#endif + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11h_cfg)); + if (req == NULL) { + ret = -ENOMEM; + goto done; + } + ds_11hcfg = (mlan_ds_11h_cfg *)req->pbuf; + + ds_11hcfg->sub_command = MLAN_OID_11H_CHAN_DFS_STATE; + req->req_id = MLAN_IOCTL_11H_CFG; + req->action = action; + moal_memcpy_ext(priv->phandle, &ds_11hcfg->param.ch_dfs_state, + ch_dfs_state, sizeof(mlan_ds_11h_chan_dfs_state), + sizeof(ds_11hcfg->param.ch_dfs_state)); + /* Send Channel Check command and wait until the report is ready */ + status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } + moal_memcpy_ext(priv->phandle, ch_dfs_state, + &ds_11hcfg->param.ch_dfs_state, + sizeof(mlan_ds_11h_chan_dfs_state), + sizeof(mlan_ds_11h_chan_dfs_state)); +done: + if (status != MLAN_STATUS_PENDING) + kfree(req); + LEAVE(); + return ret; +} + +/** + * @brief skip cac on specific channel + * @and Wext * * @param dev A pointer to net_device structure * @param req A pointer to ifreq structure @@ -2062,41 +2164,61 @@ done: */ static int woal_uap_skip_cac(struct net_device *dev, struct ifreq *req) { - moal_private *priv = (moal_private *)netdev_priv(dev); int ret = 0; skip_cac_para param; - + moal_private *priv = (moal_private *)netdev_priv(dev); +#ifdef UAP_CFG80211 +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) + int cfg80211_wext = priv->phandle->params.cfg80211_wext; +#endif +#endif + dfs_state_t dfs_state; + mlan_ds_11h_chan_dfs_state ch_dfs_state; ENTER(); /* Sanity check */ if (req->ifr_data == NULL) { - PRINTM(MERROR, "skip_cac() corrupt data\n"); + PRINTM(MERROR, "skip_dfs_cac() corrupt data\n"); ret = -EFAULT; goto done; } - memset(¶m, 0, sizeof(skip_cac_para)); - /* Get user data */ if (copy_from_user(¶m, req->ifr_data, sizeof(skip_cac_para))) { PRINTM(MERROR, "Copy from user failed\n"); ret = -EFAULT; goto done; } - - /* Currently default action is get */ - if (param.action == 0) { - param.skip_cac = (t_u16)priv->skip_cac; - } else { - priv->skip_cac = param.skip_cac; - } - - if (copy_to_user(req->ifr_data, ¶m, sizeof(skip_cac_para))) { - PRINTM(MERROR, "Copy to user failed\n"); - ret = -EFAULT; + if (param.skip_cac) + dfs_state = DFS_AVAILABLE; + else + dfs_state = DFS_USABLE; + memset(&ch_dfs_state, 0, sizeof(ch_dfs_state)); + ch_dfs_state.channel = param.channel; + woal_11h_chan_dfs_state(priv, MLAN_ACT_GET, &ch_dfs_state); + if (ch_dfs_state.dfs_state == dfs_state) + goto done; + if (param.skip_cac && ch_dfs_state.dfs_state == DFS_USABLE) + PRINTM(MMSG, + "ZeroDFS: Requst skip cac on the channel %d which hasn't do CAC before!\n", + param.channel); + ch_dfs_state.dfs_state = dfs_state; + woal_11h_chan_dfs_state(priv, MLAN_ACT_SET, &ch_dfs_state); + PRINTM(MCMND, "ZeroDFS: Skip CAC on chan %d %d\n", param.channel, + param.skip_cac); +#ifdef UAP_CFG80211 +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) + if (IS_UAP_CFG80211(cfg80211_wext)) { + if (param.skip_cac) + woal_update_channel_dfs_state(param.channel, + DFS_AVAILABLE); + else + woal_update_channel_dfs_state(param.channel, + DFS_USABLE); } +#endif +#endif done: - LEAVE(); return ret; } diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap.h b/mxm_wifiex/wlan_src/mlinux/moal_uap.h index 07052db..d0c5ff3 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap.h @@ -3,7 +3,7 @@ * @brief This file contains uap driver specific defines etc. * * - * Copyright 2008-2020 NXP + * Copyright 2008-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -201,10 +201,12 @@ typedef struct _cac_timer_status { typedef struct _skip_cac_para { /** subcmd */ t_u32 subcmd; - /** Set/Get */ + /** Set */ t_u32 action; - /** enable/disable deepsleep*/ + /** enable/disable skip cac*/ t_u16 skip_cac; + /** channel */ + t_u8 channel; } skip_cac_para; /** radio control command */ @@ -481,6 +483,8 @@ typedef struct _snmp_mib_para { /** Oid for 802.11H enable/disable */ #define OID_80211H_ENABLE 0x000a +int woal_uap_11h_ctrl(moal_private *priv, t_u32 enable); + /** dfs_testing parameters */ typedef struct _dfs_testing_param { /** subcmd */ @@ -528,6 +532,10 @@ typedef struct _domain_info_param { #define MAX_DOMAIN_TLV_LEN \ (TLV_HEADER_LEN + COUNTRY_CODE_LEN + (SUB_BAND_LEN * MAX_SUB_BANDS)) +/** Get/Set channel DFS state */ +int woal_11h_chan_dfs_state(moal_private *priv, t_u8 action, + mlan_ds_11h_chan_dfs_state *ch_dfs_state); + int woal_set_get_uap_power_mode(moal_private *priv, t_u32 action, mlan_ds_ps_mgmt *ps_mgmt); void woal_uap_set_multicast_list(struct net_device *dev); diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c b/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c index 4a545d2..ab739ed 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c @@ -3,7 +3,7 @@ * @brief This file contains the functions for uAP CFG80211. * * - * Copyright 2011-2021 NXP + * Copyright 2011-2022 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 @@ -1402,6 +1402,134 @@ done: return ret; } +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) +/** + * @brief Request the driver to add a monitor interface + * + * @param wiphy A pointer to wiphy structure + * @param name Virtual interface name + * @param name_assign_type Interface name assignment type + * @param flags Flags for the virtual interface + * @param params A pointer to vif_params structure + * @param new_dev Netdevice to be passed out + * + * @return 0 -- success, otherwise fail + */ +static int woal_cfg80211_add_mon_if(struct wiphy *wiphy, const char *name, + unsigned char name_assign_type, u32 *flags, + struct vif_params *params, + struct net_device **new_dev) +#else +/** + * @brief Request the driver to add a monitor interface + * + * @param wiphy A pointer to wiphy structure + * @param name Virtual interface name + * @param flags Flags for the virtual interface + * @param params A pointer to vif_params structure + * @param new_dev Netdevice to be passed out + * + * @return 0 -- success, otherwise fail + */ +static int woal_cfg80211_add_mon_if(struct wiphy *wiphy, +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 7, 0) + const +#endif + char *name, + u32 *flags, struct vif_params *params, + struct net_device **new_dev) +#endif +{ + int ret = 0; + moal_handle *handle = (moal_handle *)woal_get_wiphy_priv(wiphy); + moal_private *priv = + (moal_private *)woal_get_priv(handle, MLAN_BSS_ROLE_STA); + monitor_iface *mon_if = NULL; + struct net_device *ndev = NULL; +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + chan_band_info chan_info; +#endif + unsigned char name_assign_type_tmp = 0; + + ENTER(); + + ASSERT_RTNL(); + + if (handle->mon_if) { + PRINTM(MERROR, "%s: monitor interface exist: %s basedev %s\n", + __func__, handle->mon_if->mon_ndev->name, + handle->mon_if->base_ndev->name); + ret = -EFAULT; + goto fail; + } + if (!priv) { + PRINTM(MERROR, "add_mon_if: priv is NULL\n"); + ret = -EFAULT; + goto fail; + } + +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) + name_assign_type_tmp = name_assign_type; +#endif + mon_if = woal_prepare_mon_if(priv, name, name_assign_type_tmp, + CHANNEL_SPEC_SNIFFER_MODE); + if (!mon_if) { + PRINTM(MFATAL, "Prepare mon_if fail.\n"); + goto fail; + } + ndev = mon_if->mon_ndev; + dev_net_set(ndev, wiphy_net(wiphy)); + + moal_memcpy_ext(priv->phandle, ndev->perm_addr, wiphy->perm_addr, + ETH_ALEN, sizeof(ndev->perm_addr)); + moal_memcpy_ext(priv->phandle, ndev->dev_addr, ndev->perm_addr, + ETH_ALEN, MAX_ADDR_LEN); + SET_NETDEV_DEV(ndev, wiphy_dev(wiphy)); + ndev->ieee80211_ptr = &mon_if->wdev; + mon_if->wdev.iftype = NL80211_IFTYPE_MONITOR; + mon_if->wdev.wiphy = wiphy; + +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + /* Set default band channel config */ + mon_if->band_chan_cfg.band = BAND_B | BAND_G; + mon_if->band_chan_cfg.band |= BAND_GN; + mon_if->band_chan_cfg.channel = 1; + mon_if->band_chan_cfg.chan_bandwidth = CHANNEL_BW_20MHZ; + memset(&chan_info, 0x00, sizeof(chan_info)); + chan_info.channel = 1; + chan_info.is_11n_enabled = MTRUE; + if (MLAN_STATUS_FAILURE == + woal_chandef_create(priv, &mon_if->chandef, &chan_info)) { + ret = -EFAULT; + goto fail; + } + if (MLAN_STATUS_SUCCESS != + woal_set_net_monitor(priv, MOAL_IOCTL_WAIT, + CHANNEL_SPEC_SNIFFER_MODE, 0x7, + &mon_if->band_chan_cfg)) { + PRINTM(MERROR, "%s: woal_set_net_monitor fail\n", __func__); + ret = -EFAULT; + goto fail; + } +#endif + + ret = register_netdevice(ndev); + if (ret) { + PRINTM(MFATAL, "register net_device failed, ret=%d\n", ret); + free_netdev(ndev); + goto fail; + } + + handle->mon_if = mon_if; + + if (new_dev) + *new_dev = ndev; + +fail: + LEAVE(); + return ret; +} + #ifdef WIFI_DIRECT_SUPPORT #if CFG80211_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION /** @@ -1509,6 +1637,8 @@ moal_private *woal_alloc_virt_interface(moal_handle *handle, t_u8 bss_index, INIT_LIST_HEAD(&priv->tx_stat_queue); spin_lock_init(&priv->tx_stat_lock); + INIT_LIST_HEAD(&priv->mcast_list); + spin_lock_init(&priv->mcast_lock); spin_lock_init(&priv->connect_lock); @@ -1668,7 +1798,7 @@ int woal_cfg80211_add_virt_if(struct wiphy *wiphy, woal_cfg80211_init_p2p_client(new_priv); else if (type == NL80211_IFTYPE_P2P_GO) woal_cfg80211_init_p2p_go(new_priv); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) ret = cfg80211_register_netdevice(ndev); #else ret = register_netdevice(ndev); @@ -1677,7 +1807,7 @@ int woal_cfg80211_add_virt_if(struct wiphy *wiphy, handle->priv[new_priv->bss_index] = NULL; handle->priv_num--; if (ndev->reg_state == NETREG_REGISTERED) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) cfg80211_unregister_netdevice(ndev); #else unregister_netdevice(ndev); @@ -1804,6 +1934,7 @@ int woal_cfg80211_del_virt_if(struct wiphy *wiphy, struct net_device *dev) woal_cancel_scan(vir_priv, MOAL_IOCTL_WAIT); woal_flush_tx_stat_queue(vir_priv); + woal_flush_mcast_list(vir_priv); #if CFG80211_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) /* cancel previous remain on channel to avoid firmware hang */ @@ -1862,7 +1993,7 @@ int woal_cfg80211_del_virt_if(struct wiphy *wiphy, struct net_device *dev) vir_priv->phandle->priv[vir_priv->bss_index] = NULL; priv->phandle->priv_num--; if (dev->reg_state == NETREG_REGISTERED) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) cfg80211_unregister_netdevice(dev); #else unregister_netdevice(dev); @@ -1873,7 +2004,6 @@ int woal_cfg80211_del_virt_if(struct wiphy *wiphy, struct net_device *dev) #endif #endif -#if defined(WIFI_DIRECT_SUPPORT) /** * @brief This function removes an virtual interface. * @@ -1905,7 +2035,7 @@ void woal_remove_virtual_interface(moal_handle *handle) netif_device_detach(priv->netdev); if (priv->netdev->reg_state == NETREG_REGISTERED) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) cfg80211_unregister_netdevice( priv->netdev); #else @@ -1917,13 +2047,18 @@ void woal_remove_virtual_interface(moal_handle *handle) } } #endif + if (handle->mon_if) { + netif_device_detach(handle->mon_if->mon_ndev); + if (handle->mon_if->mon_ndev->reg_state == NETREG_REGISTERED) + unregister_netdevice(handle->mon_if->mon_ndev); + handle->mon_if = NULL; + } rtnl_unlock(); #ifdef WIFI_DIRECT_SUPPORT handle->priv_num -= vir_intf; #endif LEAVE(); } -#endif /** * @brief This function check if uap interface is ready @@ -2036,15 +2171,22 @@ woal_cfg80211_add_virtual_intf(struct wiphy *wiphy, const char *name, { struct net_device *ndev = NULL; int ret = 0; -#if defined(WIFI_DIRECT_SUPPORT) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) u32 *flags = ¶ms->flags; -#endif #endif ENTER(); PRINTM(MIOCTL, "add virtual intf: %d name: %s\n", type, name); switch (type) { + case NL80211_IFTYPE_MONITOR: +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) + ret = woal_cfg80211_add_mon_if(wiphy, name, name_assign_type, + flags, params, &ndev); +#else + ret = woal_cfg80211_add_mon_if(wiphy, name, flags, params, + &ndev); +#endif + break; #ifdef WIFI_DIRECT_SUPPORT #if CFG80211_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION case NL80211_IFTYPE_P2P_CLIENT: @@ -2127,6 +2269,25 @@ int woal_cfg80211_del_virtual_intf(struct wiphy *wiphy, PRINTM(MIOCTL, "del virtual intf %s\n", dev->name); ASSERT_RTNL(); + if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_MONITOR) { + if ((handle->mon_if) && (handle->mon_if->mon_ndev == dev)) { +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + if (MLAN_STATUS_SUCCESS != + woal_set_net_monitor(handle->mon_if->priv, + MOAL_IOCTL_WAIT, MFALSE, 0, + NULL)) { + PRINTM(MERROR, + "%s: woal_set_net_monitor fail\n", + __func__); + ret = -EFAULT; + } +#endif + handle->mon_if = NULL; + } + unregister_netdevice(dev); + LEAVE(); + return ret; + } if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP) { for (i = 0; i < handle->priv_num; i++) { diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.h b/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.h index 4f607e9..7d6c805 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.h @@ -3,7 +3,7 @@ * @brief This file contains the uAP CFG80211 specific defines. * * - * Copyright 2011-2020 NXP + * Copyright 2011-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap_priv.h b/mxm_wifiex/wlan_src/mlinux/moal_uap_priv.h index dcb391a..4eab2f5 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap_priv.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap_priv.h @@ -3,7 +3,7 @@ * @brief This file contains definition for extended private IOCTL call. * * - * Copyright 2010-2020 NXP + * Copyright 2010-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap_wext.c b/mxm_wifiex/wlan_src/mlinux/moal_uap_wext.c index ac3b136..72914f8 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap_wext.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap_wext.c @@ -57,7 +57,7 @@ static const chan_to_freq_t chan_to_freq[] = { {116, 5580, 1}, {120, 5600, 1}, {124, 5620, 1}, {128, 5640, 1}, {132, 5660, 1}, {136, 5680, 1}, {140, 5700, 1}, {144, 5720, 1}, {149, 5745, 1}, {153, 5765, 1}, {157, 5785, 1}, {161, 5805, 1}, - {165, 5825, 1}, + {165, 5825, 1}, {169, 5845, 1}, {173, 5865, 1}, {177, 5885, 1}, }; /** diff --git a/mxm_wifiex/wlan_src/mlinux/moal_usb.c b/mxm_wifiex/wlan_src/mlinux/moal_usb.c index 56b602c..e8cd45f 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_usb.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_usb.c @@ -34,7 +34,8 @@ extern struct semaphore AddRemoveCardSem; Local Variables ********************************************************/ -#if defined(USB8997) || defined(USB9098) || defined(USB9097) || defined(USB8978) +#if defined(USB8997) || defined(USB9098) || defined(USB9097) || \ + defined(USB8978) || defined(USBNW62X) /** Card-type detection frame response */ typedef struct { /** 32-bit ACK+WINNER field */ @@ -93,6 +94,12 @@ static struct usb_device_id woal_usb_table[] = { #ifdef USB9097 {NXP_USB_DEVICE(USB9097_VID_1, USB9097_PID_1, "NXP WLAN USB Adapter")}, {NXP_USB_DEVICE(USB9097_VID_1, USB9097_PID_2, "NXP WLAN USB Adapter")}, +#endif +#ifdef USBNW62X + {NXP_USB_DEVICE(USBNW62X_VID_1, USBNW62X_PID_1, + "NXP WLAN USB Adapter")}, + {NXP_USB_DEVICE(USBNW62X_VID_1, USBNW62X_PID_2, + "NXP WLAN USB Adapter")}, #endif /* Terminating entry */ {}, @@ -120,6 +127,10 @@ static struct usb_device_id woal_usb_table_skip_fwdnld[] = { #endif #ifdef USB9097 {NXP_USB_DEVICE(USB9097_VID_1, USB9097_PID_2, "NXP WLAN USB Adapter")}, +#endif +#ifdef USBNW62X + {NXP_USB_DEVICE(USBNW62X_VID_1, USBNW62X_PID_2, + "NXP WLAN USB Adapter")}, #endif /* Terminating entry */ {}, @@ -483,7 +494,8 @@ rx_ret: Global Functions ********************************************************/ -#if defined(USB8997) || defined(USB9098) || defined(USB9097) || defined(USB8978) +#if defined(USB8997) || defined(USB9098) || defined(USB9097) || \ + defined(USB8978) || defined(USBNW62X) /** * @brief Check chip revision * @@ -775,8 +787,24 @@ static t_u16 woal_update_card_type(t_void *card) woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) == (__force __le16)USB9097_PID_2) { card_type = CARD_TYPE_USB9097; - moal_memcpy_ext(NULL, driver_version, CARD_USBIW620, - strlen(CARD_USBIW620), strlen(driver_version)); + moal_memcpy_ext(NULL, driver_version, CARD_USB9097, + strlen(CARD_USB9097), strlen(driver_version)); + moal_memcpy_ext(NULL, + driver_version + strlen(INTF_CARDTYPE) + + strlen(KERN_VERSION), + V17, strlen(V17), + strlen(driver_version) - strlen(INTF_CARDTYPE) - + strlen(KERN_VERSION)); + } +#endif +#ifdef USBNW62X + if (woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) == + (__force __le16)USBNW62X_PID_1 || + woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) == + (__force __le16)USBNW62X_PID_2) { + card_type = CARD_TYPE_USBNW62X; + moal_memcpy_ext(NULL, driver_version, CARD_USBNW62X, + strlen(CARD_USBNW62X), strlen(driver_version)); moal_memcpy_ext(NULL, driver_version + strlen(INTF_CARDTYPE) + strlen(KERN_VERSION), @@ -852,6 +880,10 @@ static int woal_usb_probe(struct usb_interface *intf, #ifdef USB9097 case (__force __le16)USB9097_PID_1: #endif /* USB9097 */ +#ifdef USBNW62X + case (__force __le16)USBNW62X_PID_1: +#endif /* USBNW62X */ + /* If skip FW is set, we must return error so * the next driver can download the FW */ if (skip_fwdnld) @@ -878,6 +910,10 @@ static int woal_usb_probe(struct usb_interface *intf, #ifdef USB9097 case (__force __le16)USB9097_PID_2: #endif /* USB9097 */ +#ifdef USBNW62X + case (__force __le16)USBNW62X_PID_2: +#endif /* USBNW62X */ + usb_cardp->boot_state = USB_FW_READY; break; } @@ -1930,7 +1966,8 @@ done: static mlan_status woal_usb_get_fw_name(moal_handle *handle) { mlan_status ret = MLAN_STATUS_SUCCESS; -#if defined(USB8997) || defined(USB9098) || defined(USB9097) || defined(USB8978) +#if defined(USB8997) || defined(USB9098) || defined(USB9097) || \ + defined(USB8978) || defined(USBNW62X) t_u32 revision_id = 0; t_u32 strap = 0; #endif @@ -1949,7 +1986,8 @@ static mlan_status woal_usb_get_fw_name(moal_handle *handle) goto done; #endif -#if defined(USB8997) || defined(USB9098) || defined(USB9097) || defined(USB8978) +#if defined(USB8997) || defined(USB9098) || defined(USB9097) || \ + defined(USB8978) || defined(USBNW62X) ret = woal_check_chip_revision(handle, &revision_id, &strap); if (ret != MLAN_STATUS_SUCCESS) { PRINTM(MFATAL, "Chip revision check failure!\n"); @@ -2042,6 +2080,17 @@ static mlan_status woal_usb_get_fw_name(moal_handle *handle) } } #endif +#ifdef USBNW62X + if (IS_USBNW62X(handle->card_type)) { + if (strap == CARD_TYPE_USB_UART) + strcpy(handle->card_info->fw_name, + USBUARTNW62X_COMBO_FW_NAME); + else + strcpy(handle->card_info->fw_name, + USBUSBNW62X_COMBO_FW_NAME); + } +#endif + done: PRINTM(MCMND, "combo fw:%s wlan fw:%s \n", handle->card_info->fw_name, handle->card_info->fw_name_wlan); diff --git a/mxm_wifiex/wlan_src/mlinux/moal_usb.h b/mxm_wifiex/wlan_src/mlinux/moal_usb.h index 6e6b1c9..4eff643 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_usb.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_usb.h @@ -89,6 +89,15 @@ Change Log: #define USB9097_PID_2 0x2061 #endif /* USB9097 */ +#ifdef USBNW62X +/** USB VID 1 */ +#define USBNW62X_VID_1 0x0471 +/** USB PID 1 */ +#define USBNW62X_PID_1 0x020E +/** USB PID 2 */ +#define USBNW62X_PID_2 0x020F +#endif /* USBNW62X */ + /** Boot state: FW download */ #define USB_FW_DNLD 1 /** Boot state: FW ready */ @@ -101,7 +110,7 @@ Change Log: #define MVUSB_RX_DATA_URB 6 #if defined(USB8997) || defined(USB9098) || defined(USB9097) || \ - defined(USB8978) || defined(USB8801) + defined(USB8978) || defined(USB8801) || defined(USBNW62X) /* Transmit buffer size for chip revision check */ #define CHIP_REV_TX_BUF_SIZE 16 /* Receive buffer size for chip revision check */ @@ -162,6 +171,13 @@ Change Log: #define USBUSB9097_COMBO_V1_FW_NAME "nxp/usbusbiw620_combo_v1.bin" #endif /* USB9097 */ +#ifdef USBNW62X +#define USBNW62X_DEFAULT_COMBO_FW_NAME "nxp/usbusbnw62x_combo.bin" +#define USBUARTNW62X_COMBO_FW_NAME "nxp/usbuartnw62x_combo.bin" +#define USBUSBNW62X_COMBO_FW_NAME "nxp/usbusbnw62x_combo.bin" +#define USBNW62X_DEFAULT_WLAN_FW_NAME "nxp/usbnw62x_wlan.bin" +#endif /* USBNW62X */ + /** urb context */ typedef struct _urb_context { /** Pointer to moal_handle structure */ diff --git a/mxm_wifiex/wlan_src/mlinux/moal_wext.c b/mxm_wifiex/wlan_src/mlinux/moal_wext.c index f808ab0..dbdcc0f 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_wext.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_wext.c @@ -153,6 +153,8 @@ static const struct iw_priv_args woal_private_args[] = { #endif {WOAL_SLEEP_PARAMS, IW_PRIV_TYPE_INT | 16, IW_PRIV_TYPE_INT | 16, "sleepparams"}, + {WOAL_NET_MONITOR, IW_PRIV_TYPE_INT | 16, IW_PRIV_TYPE_INT | 16, + "netmon"}, {WOAL_DFS_TESTING, IW_PRIV_TYPE_INT | 16, IW_PRIV_TYPE_INT | 16, "dfstesting"}, {WOAL_MGMT_FRAME_CTRL, IW_PRIV_TYPE_INT | 16, IW_PRIV_TYPE_INT | 16, @@ -2465,31 +2467,42 @@ done: static mlan_status woal_wext_request_scan(moal_private *priv, t_u8 wait_option, mlan_802_11_ssid *req_ssid) { - wlan_user_scan_cfg scan_req; + wlan_user_scan_cfg *scan_req; mlan_scan_cfg scan_cfg; + mlan_status status; ENTER(); if (!woal_is_any_interface_active(priv->phandle)) { LEAVE(); return woal_request_scan(priv, wait_option, req_ssid); } + scan_req = (wlan_user_scan_cfg *)kmalloc(sizeof(wlan_user_scan_cfg), + GFP_KERNEL); + if (!scan_req) { + PRINTM(MERROR, "Malloc buffer failed\n"); + LEAVE(); + return MLAN_STATUS_FAILURE; + } + memset(&scan_cfg, 0, sizeof(scan_cfg)); - memset(&scan_req, 0, sizeof(scan_req)); + memset(scan_req, 0, sizeof(wlan_user_scan_cfg)); if (req_ssid && req_ssid->ssid_len != 0) { - moal_memcpy_ext(priv->phandle, scan_req.ssid_list[0].ssid, + moal_memcpy_ext(priv->phandle, scan_req->ssid_list[0].ssid, req_ssid->ssid, req_ssid->ssid_len, MLAN_MAX_SSID_LENGTH); - scan_req.ssid_list[0].max_len = 0; + scan_req->ssid_list[0].max_len = 0; } woal_get_scan_config(priv, &scan_cfg); if (scan_cfg.scan_chan_gap) - scan_req.scan_chan_gap = scan_cfg.scan_chan_gap; + scan_req->scan_chan_gap = scan_cfg.scan_chan_gap; else - scan_req.scan_chan_gap = priv->phandle->scan_chan_gap; + scan_req->scan_chan_gap = priv->phandle->scan_chan_gap; /** indicate FW, gap is optional */ - if (scan_req.scan_chan_gap && priv->phandle->pref_mac) - scan_req.scan_chan_gap |= GAP_FLAG_OPTIONAL; + if (scan_req->scan_chan_gap && priv->phandle->pref_mac) + scan_req->scan_chan_gap |= GAP_FLAG_OPTIONAL; + status = woal_request_userscan(priv, wait_option, scan_req); + kfree(scan_req); LEAVE(); - return woal_request_userscan(priv, wait_option, &scan_req); + return status; } /** diff --git a/mxm_wifiex/wlan_src/mlinux/moal_wext.h b/mxm_wifiex/wlan_src/mlinux/moal_wext.h index c7ae47b..af13eff 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_wext.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_wext.h @@ -3,7 +3,7 @@ * @brief This file contains definition for wireless extension IOCTL call. * * - * Copyright 2008-2020 NXP + * Copyright 2008-2021 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mxm_wifiex/wlan_src/script/wifidirect/start_auto_go.sh b/mxm_wifiex/wlan_src/script/wifidirect/start_auto_go.sh deleted file mode 100644 index 78aa8a8..0000000 --- a/mxm_wifiex/wlan_src/script/wifidirect/start_auto_go.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -# iwpriv mlan0 drvdbg 0x20037 -# change the mac address -./wifidirect/update_mac.sh -echo "wfd0 Mac address updated in config/wifidirect.conf" - - -./wifidirectutl wfd0 wifidirect_config config/wifidirect.conf -#ifdef STREAM_2X2 -iwpriv wfd0 bssrole 1 -#else -# iwpriv wfd0 bssrole 1 -#endif -./uaputl.exe -i wfd0 sys_config config/uaputl_wifidirect.conf -#ifdef STREAM_2X2 -iwpriv wfd0 bssrole 0 -#else -# iwpriv wfd0 bssrole 0 -#endif -# iwpriv wfd0 bssrole 1 -# change the group owner parameters -# either in uaputl_wifidirect.conf or using CLI below -#./uaputl.exe -i wfd0 sys_cfg_wpa_passphrase 1234567890 -#./uaputl.exe -i wfd0 sys_cfg_eapol_gwk_hsk 2000 3 -#./uaputl.exe -i wfd0 sys_cfg_eapol_pwk_hsk 2000 3 -# iwpriv wfd0 bssrole 0 -./wifidirectutl wfd0 wifidirect_mode 1 -iwpriv wfd0 bssrole 1 -./wifidirectutl wfd0 wifidirect_mode 2 -./uaputl.exe -i wfd0 bss_start diff --git a/mxm_wifiex/wlan_src/script/wifidirect/start_find_phase.sh b/mxm_wifiex/wlan_src/script/wifidirect/start_find_phase.sh deleted file mode 100644 index 26ddd60..0000000 --- a/mxm_wifiex/wlan_src/script/wifidirect/start_find_phase.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -# iwpriv wfd0 drvdbg 0x20037 -#change the mac address -./wifidirect/update_mac.sh -echo "wfd0 Mac address updated in config/wifidirect.conf" - -#ifdef STREAM_2X2 -iwpriv wfd0 bssrole 1 -#else -# iwpriv wfd0 bssrole 1 -#endif -./uaputl.exe -i wfd0 sys_config config/uaputl_wifidirect.conf -#ifdef STREAM_2X2 -iwpriv wfd0 bssrole 0 -#else -# iwpriv wfd0 bssrole 0 -#endif -./wifidirectutl wfd0 wifidirect_config config/wifidirect.conf -# change the passphrase -# either in uaputl_wifidirect.conf or using CLI below -#./uaputl.exe -i wfd0 sys_cfg_wpa_passphrase 1234567890 -./wifidirectutl wfd0 wifidirect_mode 1 -./wifidirectutl wfd0 wifidirect_params_config config/wifidirect.conf -./mlanutl wfd0 hostcmd config/bg_scan_wifidirect.conf bgscfg -./wifidirectutl wfd0 wifidirect_mode 4 diff --git a/mxm_wifiex/wlan_src/script/wifidirect/start_listen_state.sh b/mxm_wifiex/wlan_src/script/wifidirect/start_listen_state.sh deleted file mode 100644 index 91c1e4d..0000000 --- a/mxm_wifiex/wlan_src/script/wifidirect/start_listen_state.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -iwpriv wfd0 drvdbg 0x20037 -# change the mac address -ifconfig mlan0 hw ether 00:50:43:21:0e:08 -ifconfig wfd0 hw ether 00:50:43:21:0e:08 -ifconfig uap0 hw ether 00:50:43:21:0e:08 - -iwpriv wfd0 deepsleep 0 -iwconfig wfd0 power off - -iwpriv wfd0 bssrole 1 -./uaputl.exe -i wfd0 sys_config config/uaputl_wifidirect.conf -iwpriv wfd0 bssrole 0 -./wifidirectutl wfd0 wifidirect_config config/wifidirect.conf -./uaputl.exe -i wfd0 sys_cfg_protocol 32 -./uaputl.exe -i wfd0 sys_cfg_cipher 8 8 -./uaputl.exe -i wfd0 sys_cfg_wpa_passphrase 1234567890 -./wifidirectutl wfd0 wifidirect_mode 1 diff --git a/mxm_wifiex/wlan_src/script/wifidirect/stop_auto_go.sh b/mxm_wifiex/wlan_src/script/wifidirect/stop_auto_go.sh deleted file mode 100644 index eda03ef..0000000 --- a/mxm_wifiex/wlan_src/script/wifidirect/stop_auto_go.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -./uaputl.exe -i wfd0 bss_stop -sleep 1 -iwpriv wfd0 bssrole 0 -./wifidirectutl wfd0 wifidirect_mode 0 -# IE clear assume index 0, 1 -./uaputl.exe -i wfd0 sys_cfg_custom_ie 0 0 -./uaputl.exe -i wfd0 sys_cfg_custom_ie 1 0 diff --git a/mxm_wifiex/wlan_src/script/wifidirect/stop_wifidirect_client.sh b/mxm_wifiex/wlan_src/script/wifidirect/stop_wifidirect_client.sh deleted file mode 100644 index 5ae1ad5..0000000 --- a/mxm_wifiex/wlan_src/script/wifidirect/stop_wifidirect_client.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -# deauth the GO first -./wifidirectutl wfd0 wifidirect_mode 0 -# IE clear assume index 0, 1 -./uaputl.exe -i wfd0 sys_cfg_custom_ie 0 0 -./uaputl.exe -i wfd0 sys_cfg_custom_ie 1 0 diff --git a/mxm_wifiex/wlan_src/script/wifidirect/update_mac.sh b/mxm_wifiex/wlan_src/script/wifidirect/update_mac.sh deleted file mode 100644 index d744db9..0000000 --- a/mxm_wifiex/wlan_src/script/wifidirect/update_mac.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -MAC=`ifconfig wfd0 | grep wfd0 | tr -s ' ' | cut -d ' ' -f5` -MAC26=`echo $MAC | cut -d ':' -f2-6` -LAA=`echo $MAC | cut -d ':' -f1` -LAA=$((0x$LAA+2)) -if [ $LAA -lt 16 ] ; then -LAA=`printf "%X\n" $LAA` -MACLAA=0$LAA:$MAC26 -else -LAA=`printf "%X\n" $LAA` -MACLAA=$LAA:$MAC26 -fi -sed "s/00:50:43:00:00:00/$MAC/" config/wifidirect.conf > tmp$$ -mv tmp$$ config/wifidirect.conf -sed "s/02:50:43:00:00:00/$MACLAA/" config/wifidirect.conf > tmp$$ -mv tmp$$ config/wifidirect.conf