diff --git a/mxm_wifiex/mxmwifi.mk b/mxm_wifiex/mxmwifi.mk new file mode 100644 index 0000000..87e627e --- /dev/null +++ b/mxm_wifiex/mxmwifi.mk @@ -0,0 +1,44 @@ +# 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. + +KERNEL_SRC := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ +TARGET_ARCH := $(TARGET_KERNEL_ARCH) +MXMWIFI_CROSS_COMPILE := aarch64-linux-gnu- + +MXMWIFI_SRC_PATH := $(MXMWIFI_PATH)/mxm_wifiex/wlan_src +MXMWIFI_OUT := $(TARGET_OUT_INTERMEDIATES)/MXMWIFI_OBJ + +KERNEL_CFLAGS ?= KCFLAGS=-mno-android +ARCH ?= $(TARGET_ARCH) + +MXMWIFI_KERNELENVSH := $(MXMWIFI_OUT)/kernelenv.sh +.PHONY: $(MXMWIFI_KERNELENVSH) +$(MXMWIFI_KERNELENVSH): + mkdir -p $(MXMWIFI_OUT) + echo 'export KERNEL_SRC=$(KERNEL_SRC)' > $(MXMWIFI_KERNELENVSH) + echo 'export CROSS_COMPILE=$(MXMWIFI_CROSS_COMPILE)' >> $(MXMWIFI_KERNELENVSH) + echo 'export ARCH=$(ARCH)' >> $(MXMWIFI_KERNELENVSH) + +mxmwifi: $(MXMWIFI_KERNELENVSH) $(MXMWIFI_SRC_PATH) + $(hide) if [ ${clean_build} = 1 ]; then \ + PATH=$$PATH $(MAKE) -C $(MXMWIFI_SRC_PATH) ANDROID=yes clean; \ + fi + @ . $(MXMWIFI_KERNELENVSH); $(kernel_build_shell_env) \ + $(MAKE) -C $(MXMWIFI_SRC_PATH) ANDROID=yes \ + $(CLANG_TO_COMPILE) \ + $(KERNEL_CFLAGS) \ + ARCH=$(ARCH) \ + DEBUG=$(DEBUG); + cp $(MXMWIFI_SRC_PATH)/mlan.ko $(MXMWIFI_OUT); + cp $(MXMWIFI_SRC_PATH)/moal.ko $(MXMWIFI_OUT); diff --git a/mxm_wifiex/wlan_src/Makefile b/mxm_wifiex/wlan_src/Makefile index 50b15b1..83c8347 100644 --- a/mxm_wifiex/wlan_src/Makefile +++ b/mxm_wifiex/wlan_src/Makefile @@ -35,6 +35,7 @@ endif LD ?= $(CROSS_COMPILE)ld BACKUP= /root/backup YMD= `date +%Y%m%d%H%M` +PWD := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) ############################################################################# # Configuration Options @@ -126,14 +127,10 @@ CONFIG_USERSPACE_32BIT_OVER_KERNEL_64BIT=n ############################################################################# MODEXT = ko -ccflags-y += -I$(PWD)/mlan +ccflags-y += -I$(M)/mlan ccflags-y += -DLINUX - - - - - +KERNELDIR ?= $(KERNEL_SRC) ARCH ?= arm64 CONFIG_IMX_SUPPORT=y ifeq ($(CONFIG_IMX_SUPPORT),y) @@ -144,7 +141,7 @@ CROSS_COMPILE ?= /opt/fsl-imx-internal-xwayland/5.10-gatesgarth/sysroots/x86_64- LD += -S -BINDIR = ../bin_wlan +BINDIR = ../bin_mxm_wifiex APPDIR= $(shell if test -d "mapp"; then echo mapp; fi) ############################################################################# @@ -340,14 +337,14 @@ ifeq ($(CONFIG_MAC80211_SUPPORT_MESH),y) endif # add -Wno-packed-bitfield-compat when GCC version greater than 4.4 -GCC_VERSION := $(shell echo `gcc -dumpversion | cut -f1-2 -d.` \>= 4.4 | sed -e 's/\./*100+/g' | bc ) -ifeq ($(GCC_VERSION),1) - ccflags-y += -Wno-packed-bitfield-compat -endif -WimpGCC_VERSION := $(shell echo `gcc -dumpversion | cut -f1 -d.`| bc ) -ifeq ($(shell test $(WimpGCC_VERSION) -ge 7; echo $$?),0) -ccflags-y += -Wimplicit-fallthrough=3 -endif +#GCC_VERSION := $(shell echo `gcc -dumpversion | cut -f1-2 -d.` \>= 4.4 | sed -e 's/\./*100+/g' | bc ) +#ifeq ($(GCC_VERSION),1) +#ccflags-y += -Wno-packed-bitfield-compat +#endif + +#ifeq ($(shell test $(WimpGCC_VERSION) -ge 7; echo $$?),0) +#ccflags-y += -Wimplicit-fallthrough=3 +#endif #ccflags-y += -Wunused-but-set-variable #ccflags-y += -Wmissing-prototypes #ccflags-y += -Wold-style-definition @@ -361,7 +358,7 @@ endif #ccflags-y += -Wstringop-truncation #ccflags-y += -Wmisleading-indentation #ccflags-y += -Wunused-const-variable -ccflags-y += -Wno-array-bounds +#ccflags-y += -Wno-stringop-truncation ############################################################################# # Make Targets ############################################################################# @@ -480,7 +477,6 @@ endif - MOALOBJS = mlinux/moal_main.o \ mlinux/moal_ioctl.o \ mlinux/moal_shim.o \ @@ -583,6 +579,10 @@ else default: $(MAKE) -C $(KERNELDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules +modules_install: + $(MAKE) -C $(KERNELDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules_install + + endif ############################################################### @@ -604,9 +604,9 @@ appsbuild: fi cp -f README_MLAN $(BINDIR) + cp -rf mapp/mlanconfig/config $(BINDIR) ifneq ($(APPDIR),) - cp -rf mapp/mlanconfig/config $(BINDIR) $(MAKE) -C mapp/mlanutl $@ INSTALLDIR=$(BINDIR) endif @@ -623,9 +623,9 @@ build: echo default cp -rpf script/unload $(BINDIR)/ cp -f README_MLAN $(BINDIR) + cp -rf mapp/mlanconfig/config $(BINDIR) ifneq ($(APPDIR),) - cp -rf mapp/mlanconfig/config $(BINDIR) $(MAKE) -C mapp/mlanutl $@ INSTALLDIR=$(BINDIR) endif diff --git a/mxm_wifiex/wlan_src/mapp/mlanconfig/Android.mk b/mxm_wifiex/wlan_src/mapp/mlanconfig/Android.mk new file mode 100644 index 0000000..39b4bc8 --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/Android.mk @@ -0,0 +1,9 @@ +LOCAL_PATH := $(my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE := mlanconfig +OBJS = mlanconfig.c mlanhostcmd.c mlanmisc.c +LOCAL_SRC_FILES := $(OBJS) +LOCAL_MODULE_TAGS := optional + +include $(BUILD_EXECUTABLE) 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..5d8bfac --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/coex_int_api.conf @@ -0,0 +1,113 @@ +# 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=2 # GET 15.4 Statistics + length:4=52 # Length of collected statistics + stats:52=0 # Accumulated Statistics + } +} diff --git a/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V1_8801.conf b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V1_8801.conf new file mode 100644 index 0000000..c673547 --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V1_8801.conf @@ -0,0 +1,15 @@ +# File : ed_mac_ctrl_V1_8801.conf +# +# ./mlanutl mlan0 hostcmd config/ed_mac_ctrl_V1_8801.conf ed_mac_ctrl +# +# +## Set Energy Detect Threshold for EU Adaptivity test + +ed_mac_ctrl={ + CmdCode=0x0124 #Command code, DO NOT change this line + Enable:2=0x1 # 0 - disable EU adaptivity + # 1 - enable EU adaptivity + + Offset:2=0x1b # 0 - Default Energy Detect threshold + #offset value range: 0x80 to 0x7F +} diff --git a/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V2_8987.conf b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V2_8987.conf new file mode 100644 index 0000000..c5ec4bf --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V2_8987.conf @@ -0,0 +1,22 @@ +# File : ed_mac_ctrl_V2_8987.conf +# +# ./mlanutl mlan0 hostcmd config/ed_mac_ctrl_V2_8987.conf ed_mac_ctrl_v2 +# +## Set Energy Detect Threshold for EU Adaptivity test + +ed_mac_ctrl_v2={ + CmdCode=0x0130 #Command code, DO NOT change this line + ed_ctrl_2g.enable:2=0x1 # 0 - disable EU adaptivity for 2.4GHz band + # 1 - enable EU adaptivity for 2.4GHz band + + ed_ctrl_2g.offset:2=0x6 # 0 - Default Energy Detect threshold + #offset value range: 0x80 to 0x7F + + ed_ctrl_5g.enable:2=0x1 # 0 - disable EU adaptivity for 5GHz band + # 1 - enable EU adaptivity for 5GHz band + + ed_ctrl_5g.offset:2=0x6 # 0 - Default Energy Detect threshold + #offset value range: 0x80 to 0x7F + + ed_ctrl_txq_lock:4=0xFF #DO NOT Change this line +} diff --git a/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V2_8997.conf b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V2_8997.conf new file mode 100644 index 0000000..76d2dab --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V2_8997.conf @@ -0,0 +1,22 @@ +# File : ed_mac_ctrl_V2_8997.conf +# +# ./mlanutl mlan0 hostcmd config/ed_mac_ctrl_V2_8997.conf ed_mac_ctrl_v2 +# +## Set Energy Detect Threshold for EU Adaptivity test + +ed_mac_ctrl_v2={ + CmdCode=0x0130 #Command code, DO NOT change this line + ed_ctrl_2g.enable:2=0x1 # 0 - disable EU adaptivity for 2.4GHz band + # 1 - enable EU adaptivity for 2.4GHz band + + ed_ctrl_2g.offset:2=0x0 # 0 - Default Energy Detect threshold + #offset value range: 0x80 to 0x7F + + ed_ctrl_5g.enable:2=0x1 # 0 - disable EU adaptivity for 5GHz band + # 1 - enable EU adaptivity for 5GHz band + + ed_ctrl_5g.offset:2=0x4 # 0 - Default Energy Detect threshold + #offset value range: 0x80 to 0x7F + + ed_ctrl_txq_lock:4=0xFF #DO NOT Change this line +} diff --git a/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V2_iw416.conf b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V2_iw416.conf new file mode 100644 index 0000000..8d2cce6 --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V2_iw416.conf @@ -0,0 +1,22 @@ +# File : ed_mac_ctrl_V2_iw416.conf +# +# ./mlanutl mlan0 hostcmd config/ed_mac_ctrl_V2_iw416.conf ed_mac_ctrl_v2 +# +## Set Energy Detect Threshold for EU Adaptivity test + +ed_mac_ctrl_v2={ + CmdCode=0x0130 #Command code, DO NOT change this line + ed_ctrl_2g.enable:2=0x1 # 0 - disable EU adaptivity for 2.4GHz band + # 1 - enable EU adaptivity for 2.4GHz band + + ed_ctrl_2g.offset:2=0x9 # 0 - Default Energy Detect threshold + #offset value range: 0x80 to 0x7F + + ed_ctrl_5g.enable:2=0x1 # 0 - disable EU adaptivity for 5GHz band + # 1 - enable EU adaptivity for 5GHz band + + ed_ctrl_5g.offset:2=0xC # 0 - Default Energy Detect threshold + #offset value range: 0x80 to 0x7F + + ed_ctrl_txq_lock:4=0xFF #DO NOT Change this line +} diff --git a/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V2_nw61x.conf b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V2_nw61x.conf new file mode 100644 index 0000000..44bc003 --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V2_nw61x.conf @@ -0,0 +1,22 @@ +# File : ed_mac_ctrl_V2_nw61x.conf +# +# ./mlanutl mlan0 hostcmd config/ed_mac_ctrl_V2_nw61x.conf ed_mac_ctrl_v2 +# +## Set Energy Detect Threshold for EU Adaptivity test + +ed_mac_ctrl_v2={ + CmdCode=0x0130 #Command code, DO NOT change this line + ed_ctrl_2g.enable:2=0x1 # 0 - disable EU adaptivity for 2.4GHz band + # 1 - enable EU adaptivity for 2.4GHz band + + ed_ctrl_2g.offset:2=0xA # 0 - Default Energy Detect threshold + #offset value range: 0x80 to 0x7F + + ed_ctrl_5g.enable:2=0x1 # 0 - disable EU adaptivity for 5GHz band + # 1 - enable EU adaptivity for 5GHz band + + ed_ctrl_5g.offset:2=0xA # 0 - Default Energy Detect threshold + #offset value range: 0x80 to 0x7F + + ed_ctrl_txq_lock:4=0x1e00FF #DO NOT Change this line +} diff --git a/mxm_wifiex/wlan_src/mapp/mlanconfig/config/keep_alive.conf b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/keep_alive.conf new file mode 100644 index 0000000..0ebac1c --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/keep_alive.conf @@ -0,0 +1,24 @@ +######################### Keep-Alive command ################## +stop={ + mkeep_alive_id=1 + enable=0 #1-enable; 0-disable +} + +reset={ + mkeep_alive_id=1 + enable=0 #1-enable; 0-disable + reset=1 #enable reset +} + +start={ + mkeep_alive_id=1 + enable=1 #1-enable; 0-disable + sendInterval=55000 # 55 seconds(The unit of sendInterval is milliseconds) + retryInterval=20000 # 20 seconds(The unit of retryInterval is milliseconds) + retryCount=3 # tcp alive retry count + destMacAddr=00:50:43:21:3b:7b # destination MAC address. need change accordingly + srcMacAddr=00:00:00:00:00:00 # source MAC address. need change accordingly + pktLen=67 #IP packet len + ipPkt=45 00 00 43 8c 9e 00 00 ff 06 ac bf c0 a8 00 7c c0 a8 00 8a c0 03 22 b7 b0 b6 60 9f 42 dd 9e 1e 50 18 80 00 d0 88 00 00 74 68 69 73 20 69 73 20 61 20 6b 65 65 70 20 61 6c 69 76 65 20 70 61 63 6b 65 74 #packet content. "c0 a8 00 7c" is the source ip address. "c0 a8 00 8a" is the destination ip address. They may need change accordingly. +} + 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..e14bee3 --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/robust_btc_MM.conf @@ -0,0 +1,295 @@ +# File : robust_btc.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_timeshare={ + CmdCode=0x00e0 # do NOT change this line + Action:2=1 # SET + RSVD:2=0 + + # Robust Coex Mode TLV + RobustCoexTlvType:2=0x0160 + RobustCoexTlvLength:2={ + # All the modes below are mutually exclusive of each other; + Enable:1=0x01 # Bit0: Enable 2x2 or 1x1 Time Distribute(TMD) + # Robust Coex(RBC) mode, when uAP bss start, + # uAP TMD RBC scheme is enabled, + # STA TMD RBC scheme is disabled. + Reserved:3=0 + } +} + +mode_spatial={ + CmdCode=0x00e0 # do NOT change this line + Action:2=1 # SET + RSVD:2=0 + + # Robust Coex Mode TLV + RobustCoexTlvType:2=0x0160 + RobustCoexTlvLength:2={ + # All the modes below are mutually exclusive of each other; + Enable:1=0x82 # Bit1: Enable 1x1 SMPS Spatial RBC Mode, e.g. 0x02 + # Bit7: Enable uAP+STA SMPS RBC Mode, + # when uAP bss start, uAP SMPS RBC scheme enable, + # must combined with BIT1 or BIT2, e.g. 0x82, 0x84. + 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 + } +} + + +mode_2={ + 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=0x20 # Concurrent Coex mode with Tx power control and Rx De-sense. + # Used for chips which has separate antenna for BT + Reserved:3=0 + } +} + +gpio_cfg={ + CmdCode=0x00e0 # do NOT change this line + Action:2=1 # SET + RSVD:2=0 + + # Robust Coex Mode TLV + RobustCoexTlvType:2=0x021B + RobustCoexTlvLength:2={ + Enable:1=0x1 # enable GPIO cfg for external bt request + gpionum:1=4 # gpio 4 + gpiopolarity:1=1 # Polarity High + } +} + +external_coex_config={ + CmdCode=0x00e0 + Action:2=1 //0x0 get, 0x1 set + RSVD:2=0 + RobustCoexTlvType:2=0x0238 //TLV ID + RobustCoexTlvLength:2={ + Enabled:1=0x01 // 0x00 disable, 0x01 enable + + ExtHighInputPriority:1=0x02 // Input priority: 0x00 Input Low Priority, 0x01 Input Medium Priority, 0x02 Input High Priority + ExtLowInputPriority:1=0x02 + + ExtPriGPIONum:1=0x06; // Input Priority signal GPIO pin number + ExtPriGPIOPolarity:1=0x01; // Polarity: 0x00 Active Low, 0x01 Active High + + ExtReqGPIONum:1=0x07; // Input Request signal GPIO pin number + ExtReqGPIOPolarity:1=0x01; // Polarity: 0x00 Active Low, 0x01 Active High + + ExtGrntGPIONum:1=0x05; // Output Grant signal GPIO pin number + ExtGrntGPIOPolarity:1=0x01; // Polarity: 0x00 Active Low, 0x01 Active High + + } +} + +external_coex_uwb_config={ + CmdCode=0x00e0 + Action:2=1 # 0x0 get, 0x1 set + RSVD:2=0 + RobustCoexTlvType:2=0x0238 # TLV ID + RobustCoexTlvLength:2={ + Enabled:1=0x03 # 0x03 to configure UWB + } +} + +external_coex_config_2={ + CmdCode=0x00e0 + Action:2=1 //0x0 get, 0x1 set + RSVD:2=0 + RobustCoexTlvType:2=0x0238 //TLV ID + RobustCoexTlvLength:2={ + Enabled:1=0x02 // 0x00 disable, 0x02 enable (KF2, Fixed GPIO external COEX) + + ExtHighInputPriority:1=0x02 // Input priority: 0x00 Input Low Priority, 0x01 Input Medium Priority, 0x02 Input High Priority + ExtLowInputPriority:1=0x02 + } +} + +external_coex_uart_config={ + CmdCode=0x00e0 + Action:2=1 //0x0 get, 0x1 set + RSVD:2=0 + RobustCoexTlvType:2=0x0238 //TLV ID + RobustCoexTlvLength:2={ + Enabled:1=0x04 // 0x00 disable, 0x04: UART enable + Loopback:1=0x00 // 0x00 Loopback disable, 0x01 Loopback enable 0x02 UARTGPIO, 0x06 Get LTE Stats, 0x05 Clear LTE stats + BaudRate:4=4000000 // UART Baud Rate, 4000000: 4M baudrate, 3000000 = 3M baudrate + } +} + +external_coex_pta_config={ + CmdCode=0x00e0 + Action:2=1 // 0x0 get, 0x1 set + RSVD:2=0 + RobustCoexTlvType:2=0x0238 // TLV ID + RobustCoexTlvLength:2={ + Enabled:1=0x05 // 0x00 disable, 0x01 enable + ExtWifiBtArb:1=0x01 // 0x00 disable, 0x01 enable + PolGrantPin:1=0x01 // 0x00 active high, 0x01 active low + EnablePriPtaInt:1=0x01 // 0x00 disable, 0x01 enable + EnableStateFromPta:1=0x02 // 0x00 state input disable + // 0x01 state info is from state pin + // 0x02 state info is sampled on priority pin. + SetPriSampTiming:2=100 // Timing to sample Priority bit + SetStateInfoSampTiming:2=100 // Timing to sample Tx/Rx info + ExtRadioTrafficPrio:1=0x01 // 0x00 disable, 0x01 enable external traffic Tx/Rx Priority. + ExtCoexHwIntWci2:1=0x00 // 0x00 disable, 0x01 enable(wci-2 interface) + } +} + +#In Station generic case +#BT time is set as BTTime +#Wlan time is set as Wlan Time +generictime={ + CmdCode=0x00e0 + Action:2=1 + RSVD:2=0 + RobustCoexTlvType:2=0x0390 + RobustCoexTlvLength:2={ + Enable:2=0x01 + BtTime:2=10 #(12.5ms)Enter value in Units (1Unit = 1.25ms), BTTime must be less than 65535 + WlanTime:2=20 #(25ms)Enter value in Units (1Unit = 1.25ms), WlanTime must be less than 65535 + } +} + +#WLAN duty low prio time is set as WlanLowPrioTime +#WLAN duty total time is set as TotalTime +wlandutytime={ + CmdCode=0x00e0 + Action:2=1 + RSVD:2=0 + RobustCoexTlvType:2=0x0390 + RobustCoexTlvLength:2={ + Enable:2=0x02 # Enable = 1 is for generic time, 0x02 for Dutycycle feature, 0x03 disables DutyCycle feature + WlanLowPrioTime:2=30 #(30ms)Enter value in Units (1Unit = 1ms), keep it less than TotalTime + TotalTime:2=100 #(100ms)Enter value in Units (1Unit = 1ms), TotalTime must be <= 100 + } +} + +#In Station A2DP case +#BT time is set as BTTime +#Wlan time is set as Wlan Time +a2dptime={ + CmdCode=0x00e0 + Action:2=1 + RSVD:2=0 + RobustCoexTlvType:2=0x0391 + RobustCoexTlvLength:2={ + Enable:2=0x01 + BtTime:2=10000 #(10ms) BTTime must be less than 65535 + WlanTime:2=39500 #(39.5ms) WlanTime must be less than 65535 + } +} + +#In Station inquiry case +#BT time is set as BTTime +#Wlan time is set as Wlan Time +inquirytime={ + CmdCode=0x00e0 + Action:2=1 + RSVD:2=0 + RobustCoexTlvType:2=0x0392 + RobustCoexTlvLength:2={ + Enable:2=0x01 + BtTime:2=21215 #(21.215ms) BTTime must be less than 65535 + WlanTime:2=11000 #(11ms) WlanTime must be less than 65535 + } +} + +#In Ap generic case +#BT time is BTTimeBusy when BT has traffic +#BT time is BTTimeIdle when BT is idle +#Wlan time is WlanTimeBusy when Wlan has traffic +#Wlan time is WlanTimeIdle when Wlan is idle +ap_generictime={ + CmdCode=0x00e0 + Action:2=1 + RSVD:2=0 + RobustCoexTlvType:2=0x0393 + RobustCoexTlvLength:2={ + Enable:2=0x01 + BtTime_MAX:2=23000 #(23ms) BTTime(BT Busy) must be less than 28767 + BtTime_MIN:2=6500 #(6.5ms) BTTime(BT Idle) must be less than 28767 + WlanTime_MAX:2=18000 #(18ms) WlanTime(Wlan Busy) must be less than 32767 + WlanTime_MIN:2=5750 #(5.75ms) WlanTime(Wlan Idle) must be less than 32767 + } +} + +#In Ap A2DP case +#BT time is change from BTTimeMax to BTTimeMin +#Wlan time is change from WlanTimeMax to WlanTimeMin +ap_a2dptime={ + CmdCode=0x00e0 + Action:2=1 + RSVD:2=0 + RobustCoexTlvType:2=0x0394 + RobustCoexTlvLength:2={ + Enable:2=0x01 + BtTimebusy:2=23000 #(23ms) Maximum BTTime must be less than 32767 + BtTimeidle:2=6500 #(6.5ms) Minimum BTTime must be less than 32767 + WlanTimebusy:2=18000 #(18ms) Maximum WlanTime must be less than 32767 + WlanTimeidle:2=5750 #(5.75ms) Minimum WlanTime must be less than 32767 + } +} + +#In Ap inquiry case +#BT time is set as BTTime +#Wlan time is set as Wlan Time +ap_inquirytime={ + CmdCode=0x00e0 + Action:2=1 + RSVD:2=0 + RobustCoexTlvType:2=0x0395 + RobustCoexTlvLength:2={ + Enable:2=0x01 + BtTime:2=28750 #(28.75ms) BTTime must less than 32767 + WlanTime:2=20000 #(20ms) WlanTime must be less than 32767 + } +} +######################### Robust Coex command ############### diff --git a/mxm_wifiex/wlan_src/mapp/mlanconfig/config/txpwrlimit_cfg_8987.conf b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/txpwrlimit_cfg_8987.conf new file mode 100644 index 0000000..aef78cb --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/txpwrlimit_cfg_8987.conf @@ -0,0 +1,537 @@ +# File : txpwrlimit_cfg.conf +## Get CFG data for Tx power limitation +txpwrlimit_2g_cfg_get={ + CmdCode=0x00fb # do NOT change this line + Action:2=0 # 0 - GET + SubBand:2=0x00 # 0x00 2G subband (2.4G: channel 1-14) + # 0x10 5G subband0 (5G: channel 36,40,44,48, + # 52,56,60,64) + # 0x11 5G subband1 (5G: channel 100,104,108,112, + # 116,120,124,128, + # 132,136,140,144) + # 0x12 5G subband2 (5G: channel 149,153,157,161,165,172) + # 0x13 5G subband3 (5G: channel 183,184,185,187,188, + # 189, 192,196; + # 5G: channel 7,8,11,12,16,34) + ChanTRPC.TlvType:2=0x0249 + ChanTRPC.TlvLength:2={ # Get Tx Power Values for a particular antenna + TLVAntNum:1=0 # Antenna Num: 0 - Both, 1 - Main, 2 - Aux + } +} + + +txpwrlimit_5g_cfg_get_sub0={ + CmdCode=0x00fb # do NOT change this line + Action:2=0 # 0 - GET + SubBand:2=0x10 # 0x00 2G subband (2.4G: channel 1-14) + # 0x10 5G subband0 (5G: channel 36,40,44,48, + # 52,56,60,64) + # 0x11 5G subband1 (5G: channel 100,104,108,112, + # 116,120,124,128, + # 132,136,140,144) + # 0x12 5G subband2 (5G: channel 149,153,157,161,165,172) + # 0x13 5G subband3 (5G: channel 183,184,185,187,188, + # 189, 192,196; + # 5G: channel 7,8,11,12,16,34) + ChanTRPC.TlvType:2=0x0249 + ChanTRPC.TlvLength:2={ # Get Tx Power Values for a particular antenna + TLVAntNum:1=0 # Antenna Num: 0 - Both, 1 - Main, 2 - Aux + } +} + + +txpwrlimit_5g_cfg_get_sub1={ + CmdCode=0x00fb # do NOT change this line + Action:2=0 # 0 - GET + SubBand:2=0x11 # 0x00 2G subband (2.4G: channel 1-14) + # 0x10 5G subband0 (5G: channel 36,40,44,48, + # 52,56,60,64) + # 0x11 5G subband1 (5G: channel 100,104,108,112, + # 116,120,124,128, + # 132,136,140,144) + # 0x12 5G subband2 (5G: channel 149,153,157,161,165,172) + # 0x13 5G subband3 (5G: channel 183,184,185,187,188, + # 189, 192,196; + # 5G: channel 7,8,11,12,16,34) + ChanTRPC.TlvType:2=0x0249 + ChanTRPC.TlvLength:2={ # Get Tx Power Values for a particular antenna + TLVAntNum:1=0 # Antenna Num: 0 - Both, 1 - Main, 2 - Aux + } +} + + +txpwrlimit_5g_cfg_get_sub2={ + CmdCode=0x00fb # do NOT change this line + Action:2=0 # 0 - GET + SubBand:2=0x12 # 0x00 2G subband (2.4G: channel 1-14) + # 0x10 5G subband0 (5G: channel 36,40,44,48, + # 52,56,60,64) + # 0x11 5G subband1 (5G: channel 100,104,108,112, + # 116,120,124,128, + # 132,136,140,144) + # 0x12 5G subband2 (5G: channel 149,153,157,161,165,172) + # 0x13 5G subband3 (5G: channel 183,184,185,187,188, + # 189, 192,196; + # 5G: channel 7,8,11,12,16,34) + ChanTRPC.TlvType:2=0x0249 + ChanTRPC.TlvLength:2={ # Get Tx Power Values for a particular antenna + TLVAntNum:1=0 # Antenna Num: 0 - Both, 1 - Main, 2 - Aux + } +} + + +txpwrlimit_5g_cfg_get_sub3={ + CmdCode=0x00fb # do NOT change this line + Action:2=0 # 0 - GET + SubBand:2=0x13 # 0x00 2G subband (2.4G: channel 1-14) + # 0x10 5G subband0 (5G: channel 36,40,44,48, + # 52,56,60,64) + # 0x11 5G subband1 (5G: channel 100,104,108,112, + # 116,120,124,128, + # 132,136,140,144) + # 0x12 5G subband2 (5G: channel 149,153,157,161,165,172) + # 0x13 5G subband3 (5G: channel 183,184,185,187,188, + # 189, 192,196; + # 5G: channel 7,8,11,12,16,34) + ChanTRPC.TlvType:2=0x0249 + ChanTRPC.TlvLength:2={ # Get Tx Power Values for a particular antenna + TLVAntNum:1=0 # Antenna Num: 0 - Both, 1 - Main, 2 - Aux + } +} + +## Set CFG data for Tx power limitation +## +## TLVStartFreq: Starting Frequency of the band for this channel +## 2407, 2414 or 2400 for 2.4 GHz +## 5000 +## 4000 +## TLVChanWidth: Channel Width +## 20 +## TLVChanNum : Channel Number +## TLVPwr[] : ModulationGroup +## 0: CCK (1,2,5.5,11 Mbps) +## 1: OFDM (6,9,12,18 Mbps) +## 2: OFDM (24,36 Mbps) +## 3: OFDM (48,54 Mbps) +## 4: HT20 (0,1,2) +## 5: HT20 (3,4) +## 6: HT20 (5,6,7) +## 7: HT40 (0,1,2) +## 8: HT40 (3,4) +## 9: HT40 (5,6,7) +## 10: VHT_QAM256 (MCS8) +## 11: VHT_40_QAM256 (MCS8,9) +## 12: VHT_80_PSK (MCS0,1,2) +## 13: VHT_80_QAM16 (MCS3,4) +## 14: VHT_80_QAM64 (MCS5,6,7) +## 15: VHT_80_QAM256 (MCS8,9) +## Power Limit in dBm +## +## For 40MHz modulation groups, specify same Tx power value for a set of +## two consecutive channel frequencies +## Valid channel sets: +## (36, 40), (44, 48), (52, 56), (60, 64) +## (100, 104), (108, 112), (116, 120), (124, 128), (132, 136), (140, 144) +## (149, 153), (157, 161) +## +## For 80MHz modulation groups, specify same Tx power value for a set of +## four consecutive channel frequencies +## Valid channel sets: +## (36, 40, 44, 48), (52, 56, 60, 64) +## (100, 104, 108, 112), (116, 120, 124, 128), (132, 136, 140, 144) +## (149, 153, 157, 161) + +## 2G Tx power limit CFG +txpwrlimit_2g_cfg_set={ + CmdCode=0x00fb # do NOT change this line + Action:2=1 # 1 - SET + RSVD:2=0 # do NOT change this line + + ChanTRPC.TlvType:2=0x0249 + ChanTRPC.TlvLength:2={ # Configure Tx Power Values for a particular antenna + TLVAntNum:1=0 # Antenna Num: 0 - Both, 1 - Main, 2 - Aux + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=1 + TLVPwr:24='0,18,1,18,2,16,3,14,4,18,5,16,6,14,7,18,8,16,9,14,10,16,11,16' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=2 + TLVPwr:24='0,18,1,18,2,16,3,14,4,18,5,16,6,14,7,18,8,16,9,14,10,16,11,16' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=3 + TLVPwr:24='0,18,1,18,2,16,3,14,4,18,5,16,6,14,7,18,8,16,9,14,10,16,11,16' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=4 + TLVPwr:24='0,18,1,18,2,16,3,14,4,18,5,16,6,14,7,18,8,16,9,14,10,16,11,16' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=5 + TLVPwr:24='0,18,1,18,2,16,3,14,4,18,5,16,6,14,7,18,8,16,9,14,10,16,11,16' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=6 + TLVPwr:24='0,18,1,18,2,16,3,14,4,18,5,16,6,14,7,18,8,16,9,14,10,16,11,16' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=7 + TLVPwr:24='0,18,1,18,2,16,3,14,4,18,5,16,6,14,7,18,8,16,9,14,10,16,11,16' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=8 + TLVPwr:24='0,18,1,18,2,16,3,14,4,18,5,16,6,14,7,18,8,16,9,14,10,16,11,16' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=9 + TLVPwr:24='0,18,1,18,2,16,3,14,4,18,5,16,6,14,7,18,8,16,9,14,10,16,11,16' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=10 + TLVPwr:24='0,18,1,18,2,16,3,14,4,18,5,16,6,14,7,18,8,16,9,14,10,16,11,16' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=11 + TLVPwr:24='0,18,1,18,2,16,3,14,4,18,5,16,6,14,7,18,8,16,9,14,10,16,11,16' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=12 + TLVPwr:24='0,16,1,16,2,16,3,14,4,16,5,16,6,14,7,16,8,16,9,14,10,16,11,16' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=13 + TLVPwr:24='0,16,1,16,2,16,3,14,4,16,5,16,6,14,7,16,8,16,9,14,10,16,11,16' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2414 + TLVChanWidth:1=20 + TLVChanNum:1=14 + TLVPwr:24='0,12,1,12,2,12,3,12,4,12,5,12,6,12,7,12,8,12,9,12,10,12,11,12' + } +} + +## 5G Tx power limit CFG +txpwrlimit_5g_cfg_set={ + CmdCode=0x00fb # do NOT change this line + Action:2=1 # 1 - SET + RSVD:2=0 # do NOT change this line + + ChanTRPC.TlvType:2=0x0249 + ChanTRPC.TlvLength:2={ # Configure Tx Power Values for a particular antenna + TLVAntNum:1=0 # Antenna Num: 0 - Both, 1 - Main, 2 - Aux + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=36 + TLVPwr:32='0,0,1,16,2,16,3,14,4,16,5,16,6,14,7,16,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=40 + TLVPwr:32='0,0,1,16,2,16,3,14,4,16,5,16,6,14,7,16,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=44 + TLVPwr:32='0,0,1,16,2,16,3,14,4,16,5,16,6,14,7,16,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=48 + TLVPwr:32='0,0,1,16,2,16,3,14,4,16,5,16,6,14,7,16,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=52 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=56 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=60 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=64 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=100 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=104 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=108 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=112 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=116 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=120 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=124 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=128 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=132 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=136 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=140 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=144 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=149 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=153 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=157 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=161 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=165 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=183 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=184 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=185 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=187 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=188 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=189 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=192 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=196 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=7 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=8 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=11 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=12 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=16 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=34 + TLVPwr:32='0,0,1,17,2,16,3,14,4,17,5,16,6,14,7,17,8,16,9,14,10,15,11,14,12,15,13,15,14,14,15,13' + } +} diff --git a/mxm_wifiex/wlan_src/mapp/mlanconfig/config/txpwrlimit_cfg_8997.conf b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/txpwrlimit_cfg_8997.conf new file mode 100644 index 0000000..0f3b71a --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/txpwrlimit_cfg_8997.conf @@ -0,0 +1,621 @@ +# File : txpwrlimit_cfg.conf +## Get CFG data for Tx power limitation +txpwrlimit_2g_cfg_get={ + CmdCode=0x00fb # do NOT change this line + Action:2=0 # 0 - GET + SubBand:2=0x00 # 0x00 2G subband (2.4G: channel 1-14) + # 0x10 5G subband0 (5G: channel 36,40,44,48, + # 52,56,60,64) + # 0x11 5G subband1 (5G: channel 100,104,108,112, + # 116,120,124,128, + # 132,136,140,144) + # 0x12 5G subband2 (5G: channel 149,153,157,161,165,172) + # 0x13 5G subband3 (5G: channel 183,184,185,187,188, + # 189, 192,196; + # 5G: channel 7,8,11,12,16,34) +} + + +txpwrlimit_5g_cfg_get_sub0={ + CmdCode=0x00fb # do NOT change this line + Action:2=0 # 0 - GET + SubBand:2=0x10 # 0x00 2G subband (2.4G: channel 1-14) + # 0x10 5G subband0 (5G: channel 36,40,44,48, + # 52,56,60,64) + # 0x11 5G subband1 (5G: channel 100,104,108,112, + # 116,120,124,128, + # 132,136,140,144) + # 0x12 5G subband2 (5G: channel 149,153,157,161,165,172) + # 0x13 5G subband3 (5G: channel 183,184,185,187,188, + # 189, 192,196; + # 5G: channel 7,8,11,12,16,34) +} + + +txpwrlimit_5g_cfg_get_sub1={ + CmdCode=0x00fb # do NOT change this line + Action:2=0 # 0 - GET + SubBand:2=0x11 # 0x00 2G subband (2.4G: channel 1-14) + # 0x10 5G subband0 (5G: channel 36,40,44,48, + # 52,56,60,64) + # 0x11 5G subband1 (5G: channel 100,104,108,112, + # 116,120,124,128, + # 132,136,140,144) + # 0x12 5G subband2 (5G: channel 149,153,157,161,165,172) + # 0x13 5G subband3 (5G: channel 183,184,185,187,188, + # 189, 192,196; + # 5G: channel 7,8,11,12,16,34) +} + + +txpwrlimit_5g_cfg_get_sub2={ + CmdCode=0x00fb # do NOT change this line + Action:2=0 # 0 - GET + SubBand:2=0x12 # 0x00 2G subband (2.4G: channel 1-14) + # 0x10 5G subband0 (5G: channel 36,40,44,48, + # 52,56,60,64) + # 0x11 5G subband1 (5G: channel 100,104,108,112, + # 116,120,124,128, + # 132,136,140,144) + # 0x12 5G subband2 (5G: channel 149,153,157,161,165,172) + # 0x13 5G subband3 (5G: channel 183,184,185,187,188, + # 189, 192,196; + # 5G: channel 7,8,11,12,16,34) +} + + +txpwrlimit_5g_cfg_get_sub3={ + CmdCode=0x00fb # do NOT change this line + Action:2=0 # 0 - GET + SubBand:2=0x13 # 0x00 2G subband (2.4G: channel 1-14) + # 0x10 5G subband0 (5G: channel 36,40,44,48, + # 52,56,60,64) + # 0x11 5G subband1 (5G: channel 100,104,108,112, + # 116,120,124,128, + # 132,136,140,144) + # 0x12 5G subband2 (5G: channel 149,153,157,161,165,172) + # 0x13 5G subband3 (5G: channel 183,184,185,187,188, + # 189, 192,196; + # 5G: channel 7,8,11,12,16,34) +} + +## Set CFG data for Tx power limitation +## +## TLVStartFreq: Starting Frequency of the band for this channel +## 2407, 2414 or 2400 for 2.4 GHz +## 5000 +## 4000 +## TLVChanWidth: Channel Width +## 20 +## TLVChanNum : Channel Number +## TLVPwr[] : ModulationGroup +## 0: CCK (1,2,5.5,11 Mbps) +## 1: OFDM (6,9,12,18 Mbps) +## 2: OFDM (24,36 Mbps) +## 3: OFDM (48,54 Mbps) +## 4: HT20 (MCS0,1,2) +## 5: HT20 (MCS3,4) +## 6: HT20 (MCS5,6,7) +## 7: HT40 (MCS0,1,2) +## 8: HT40 (MCS3,4) +## 9: HT40 (MCS5,6,7) +## 10: HT2_20 (MCS8,9,10) +## 11: HT2_20 (MCS11,12) +## 12: HT2_20 (MCS13,14,15) +## 13: HT2_40 (MCS8,9,10) +## 14: HT2_40 (MCS11,12) +## 15: HT2_40 (MCS13,14,15) +## 16: VHT_QAM256 (MCS8) +## 17: VHT_40_QAM256 (MCS8,9) +## 18: VHT_80_PSK (MCS0,1,2) +## 19: VHT_80_QAM16 (MCS3,4) +## 20: VHT_80_QAM64 (MCS5,6,7) +## 21: VHT_80_QAM256 (MCS8,9) +## 22: VHT2_20_QAM256 (MCS8,9) +## 23: VHT2_40_QAM256 (MCS8,9) +## 24: VHT2_80_PSK (MCS0, 1, 2) +## 25: VHT2_80_QAM16 (MCS3,4) +## 26: VHT2_80_QAM64 (MCS5,6,7) +## 27: VHT2_80_QAM256 (MCS8,9) +## Power Limit in dBm + +## For 40MHz modulation groups, specify same Tx power value for a set of +## two consecutive channel frequencies +## Valid channel sets: +## (36, 40), (44, 48), (52, 56), (60, 64) +## (100, 104), (108, 112), (116, 120), (124, 128), (132, 136), (140, 144) +## (149, 153), (157, 161) +## +## For 80MHz modulation groups, specify same Tx power value for a set of +## four consecutive channel frequencies +## Valid channel sets: +## (36, 40, 44, 48), (52, 56, 60, 64) +## (100, 104, 108, 112), (116, 120, 124, 128), (132, 136, 140, 144) +## (149, 153, 157, 161) + + +## 2G subband0 Tx power limit CFG +txpwrlimit_2g_cfg_set={ + CmdCode=0x00fb # do NOT change this line + Action:2=1 # 1 - SET + SubBand:2=0 # do NOT use this member in set cmd + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=1 + TLVPwr:32='0,17,1,15,2,15,3,13,4,15,5,15,6,13,7,15,8,15,9,13,10,15,11,15,12,15,13,15,14,15,15,15' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=2 + TLVPwr:32='0,17,1,15,2,15,3,13,4,15,5,15,6,13,7,15,8,15,9,13,10,15,11,15,12,15,13,15,14,15,15,15' + } + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=3 + TLVPwr:32='0,17,1,15,2,15,3,13,4,15,5,15,6,13,7,15,8,15,9,13,10,15,11,15,12,15,13,15,14,15,15,15' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=4 + TLVPwr:32='0,17,1,15,2,15,3,13,4,15,5,15,6,13,7,15,8,15,9,13,10,15,11,15,12,15,13,15,14,15,15,15' + } + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=5 + TLVPwr:32='0,17,1,15,2,15,3,13,4,15,5,15,6,13,7,15,8,15,9,13,10,15,11,15,12,15,13,15,14,15,15,15' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=6 + TLVPwr:32='0,17,1,15,2,15,3,13,4,15,5,15,6,13,7,15,8,15,9,13,10,15,11,15,12,15,13,15,14,15,15,15' + } + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=7 + TLVPwr:32='0,17,1,15,2,15,3,13,4,15,5,15,6,13,7,15,8,15,9,13,10,15,11,15,12,15,13,15,14,15,15,15' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=8 + TLVPwr:32='0,17,1,15,2,15,3,13,4,15,5,15,6,13,7,15,8,15,9,13,10,15,11,15,12,15,13,15,14,15,15,15' + } + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=9 + TLVPwr:32='0,17,1,15,2,15,3,13,4,15,5,15,6,13,7,15,8,15,9,13,10,15,11,15,12,15,13,15,14,15,15,15' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=10 + TLVPwr:32='0,17,1,15,2,15,3,13,4,15,5,15,6,13,7,15,8,15,9,13,10,15,11,15,12,15,13,15,14,15,15,15' + } + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=11 + TLVPwr:32='0,17,1,15,2,15,3,13,4,15,5,15,6,13,7,15,8,15,9,13,10,15,11,15,12,15,13,15,14,15,15,15' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=12 + TLVPwr:32='0,17,1,15,2,15,3,13,4,15,5,15,6,13,7,15,8,15,9,13,10,15,11,15,12,15,13,15,14,15,15,15' + } + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=13 + TLVPwr:32='0,17,1,15,2,15,3,13,4,15,5,15,6,13,7,15,8,15,9,13,10,15,11,15,12,15,13,15,14,15,15,15' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=14 + TLVPwr:32='0,12,1,12,2,12,3,12,4,12,5,12,6,12,7,12,8,12,9,12,10,12,11,12,12,12,13,12,14,12,15,12' + } +} + +## 5G subband1 Tx power limit CFG +txpwrlimit_5g_cfg_set_sub0={ + CmdCode=0x00fb # do NOT change this line + Action:2=1 # 1 - SET + SubBand:2=0 # do NOT use this member in set cmd + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=36 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=40 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=44 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=48 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=52 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=56 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=60 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=64 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } +} + +## 5G subband2 Tx power limit CFG +txpwrlimit_5g_cfg_set_sub1={ + CmdCode=0x00fb # do NOT change this line + Action:2=1 # 1 - SET + SubBand:2=0 # do NOT use this member in set cmd + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=100 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=104 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=108 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=112 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=116 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=120 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=124 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=128 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=132 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=136 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=140 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=144 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + +} + + +## 5G subband3 Tx power limit CFG +txpwrlimit_5g_cfg_set_sub2={ + CmdCode=0x00fb # do NOT change this line + Action:2=1 # 1 - SET + SubBand:2=0 # do NOT use this member in set cmd + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=149 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=153 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=157 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=161 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=165 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } +} + + +## 5G subband4 Tx power limit CFG +txpwrlimit_5g_cfg_set_sub3={ + CmdCode=0x00fb # do NOT change this line + Action:2=1 # 1 - SET + SubBand:2=0 # do NOT use this in set cmd + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=4000 + TLVChanWidth:1=20 + TLVChanNum:1=183 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=4000 + TLVChanWidth:1=20 + TLVChanNum:1=184 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=4000 + TLVChanWidth:1=20 + TLVChanNum:1=185 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=4000 + TLVChanWidth:1=20 + TLVChanNum:1=187 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=4000 + TLVChanWidth:1=20 + TLVChanNum:1=188 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=4000 + TLVChanWidth:1=20 + TLVChanNum:1=189 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=4000 + TLVChanWidth:1=20 + TLVChanNum:1=192 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=4000 + TLVChanWidth:1=20 + TLVChanNum:1=196 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=7 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=8 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=11 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=12 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=16 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } + + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=34 + TLVPwr:56='0,17,1,15,2,15,3,11,4,15,5,15,6,11,7,15,8,15,9,11,10,15,11,15,12,14,13,15,14,15,15,14,16,11,17,11,18,13,19,13,20,10,21,10,22,11,23,11,24,13,25,13,26,12,27,10' + } +} diff --git a/mxm_wifiex/wlan_src/mapp/mlanconfig/config/txpwrlimit_cfg_iw416.conf b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/txpwrlimit_cfg_iw416.conf new file mode 100644 index 0000000..0bc7305 --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/txpwrlimit_cfg_iw416.conf @@ -0,0 +1,497 @@ +# File : txpwrlimit_cfg_iw416.conf +## Get CFG data for Tx power limitation +txpwrlimit_2g_cfg_get={ + CmdCode=0x00fb # do NOT change this line + Action:2=0 # 0 - GET + SubBand:2=0x00 # 0x00 2G subband (2.4G: channel 1-14) + # 0x10 5G subband0 (5G: channel 36,40,44,48, + # 52,56,60,64) + # 0x11 5G subband1 (5G: channel 100,104,108,112, + # 116,120,124,128, + # 132,136,140,144) + # 0x12 5G subband2 (5G: channel 149,153,157,161,165,172) + # 0x13 5G subband3 (5G: channel 183,184,185,187,188, + # 189, 192,196; + # 5G: channel 7,8,11,12,16,34) +} + + +txpwrlimit_5g_cfg_get_sub0={ + CmdCode=0x00fb # do NOT change this line + Action:2=0 # 0 - GET + SubBand:2=0x10 # 0x00 2G subband (2.4G: channel 1-14) + # 0x10 5G subband0 (5G: channel 36,40,44,48, + # 52,56,60,64) + # 0x11 5G subband1 (5G: channel 100,104,108,112, + # 116,120,124,128, + # 132,136,140,144) + # 0x12 5G subband2 (5G: channel 149,153,157,161,165,172) + # 0x13 5G subband3 (5G: channel 183,184,185,187,188, + # 189, 192,196; + # 5G: channel 7,8,11,12,16,34) +} + + +txpwrlimit_5g_cfg_get_sub1={ + CmdCode=0x00fb # do NOT change this line + Action:2=0 # 0 - GET + SubBand:2=0x11 # 0x00 2G subband (2.4G: channel 1-14) + # 0x10 5G subband0 (5G: channel 36,40,44,48, + # 52,56,60,64) + # 0x11 5G subband1 (5G: channel 100,104,108,112, + # 116,120,124,128, + # 132,136,140,144) + # 0x12 5G subband2 (5G: channel 149,153,157,161,165,172) + # 0x13 5G subband3 (5G: channel 183,184,185,187,188, + # 189, 192,196; + # 5G: channel 7,8,11,12,16,34) +} + + +txpwrlimit_5g_cfg_get_sub2={ + CmdCode=0x00fb # do NOT change this line + Action:2=0 # 0 - GET + SubBand:2=0x12 # 0x00 2G subband (2.4G: channel 1-14) + # 0x10 5G subband0 (5G: channel 36,40,44,48, + # 52,56,60,64) + # 0x11 5G subband1 (5G: channel 100,104,108,112, + # 116,120,124,128, + # 132,136,140,144) + # 0x12 5G subband2 (5G: channel 149,153,157,161,165,172) + # 0x13 5G subband3 (5G: channel 183,184,185,187,188, + # 189, 192,196; + # 5G: channel 7,8,11,12,16,34) +} + + +txpwrlimit_5g_cfg_get_sub3={ + CmdCode=0x00fb # do NOT change this line + Action:2=0 # 0 - GET + SubBand:2=0x13 # 0x00 2G subband (2.4G: channel 1-14) + # 0x10 5G subband0 (5G: channel 36,40,44,48, + # 52,56,60,64) + # 0x11 5G subband1 (5G: channel 100,104,108,112, + # 116,120,124,128, + # 132,136,140,144) + # 0x12 5G subband2 (5G: channel 149,153,157,161,165,172) + # 0x13 5G subband3 (5G: channel 183,184,185,187,188, + # 189, 192,196; + # 5G: channel 7,8,11,12,16,34) +} + +## Set CFG data for Tx power limitation +## +## TLVStartFreq: Starting Frequency of the band for this channel +## 2407, 2414 or 2400 for 2.4 GHz +## 5000 +## 4000 +## TLVChanWidth: Channel Width +## 20 +## TLVChanNum : Channel Number +## TLVPwr[] : ModulationGroup +## 0: CCK (1,2,5.5,11 Mbps) +## 1: OFDM (6,9,12,18 Mbps) +## 2: OFDM (24,36 Mbps) +## 3: OFDM (48,54 Mbps) +## 4: HT20 (0,1,2) +## 5: HT20 (3,4) +## 6: HT20 (5,6,7) +## 7: HT40 (0,1,2) +## 8: HT40 (3,4) +## 9: HT40 (5,6,7) +## Power Limit in dBm +## +## For 40MHz modulation groups, specify same Tx power value for a set of +## two consecutive channel frequencies +## Valid channel sets: +## (36, 40), (44, 48), (52, 56), (60, 64) +## (100, 104), (108, 112), (116, 120), (124, 128), (132, 136), (140, 144) +## (149, 153), (157, 161) +## + +## 2G Tx power limit CFG +txpwrlimit_2g_cfg_set={ + CmdCode=0x00fb # do NOT change this line + Action:2=1 # 1 - SET + RSVD:2=0 # do NOT change this line + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=1 + TLVPwr:20='0,16,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=2 + TLVPwr:20='0,16,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=3 + TLVPwr:20='0,16,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=4 + TLVPwr:20='0,16,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=5 + TLVPwr:20='0,16,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=6 + TLVPwr:20='0,16,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=7 + TLVPwr:20='0,16,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=8 + TLVPwr:20='0,16,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=9 + TLVPwr:20='0,16,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=10 + TLVPwr:20='0,16,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=11 + TLVPwr:20='0,16,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=12 + TLVPwr:20='0,16,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2407 + TLVChanWidth:1=20 + TLVChanNum:1=13 + TLVPwr:20='0,16,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=2414 + TLVChanWidth:1=20 + TLVChanNum:1=14 + TLVPwr:20='0,16,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } +} + +## 5G Tx power limit CFG +txpwrlimit_5g_cfg_set={ + CmdCode=0x00fb # do NOT change this line + Action:2=1 # 1 - SET + RSVD:2=0 # do NOT change this line + + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=36 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=40 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=44 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=48 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=52 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=56 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=60 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=64 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=100 + TLVPwr:20='0,0,1,16,2,16,3,13,4,16,5,16,6,12,7,16,8,15,9,12' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=104 + TLVPwr:20='0,0,1,16,2,16,3,13,4,16,5,16,6,12,7,16,8,15,9,12' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=108 + TLVPwr:20='0,0,1,16,2,16,3,13,4,16,5,16,6,12,7,16,8,15,9,12' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=112 + TLVPwr:20='0,0,1,16,2,16,3,13,4,16,5,16,6,12,7,16,8,15,9,12' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=116 + TLVPwr:20='0,0,1,16,2,16,3,13,4,16,5,16,6,12,7,16,8,15,9,12' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=120 + TLVPwr:20='0,0,1,16,2,16,3,13,4,16,5,16,6,12,7,16,8,15,9,12' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=124 + TLVPwr:20='0,0,1,16,2,16,3,13,4,16,5,16,6,12,7,16,8,15,9,12' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=128 + TLVPwr:20='0,0,1,16,2,16,3,13,4,16,5,16,6,12,7,16,8,15,9,12' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=132 + TLVPwr:20='0,0,1,16,2,16,3,13,4,16,5,16,6,12,7,16,8,15,9,12' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=136 + TLVPwr:20='0,0,1,16,2,16,3,13,4,16,5,16,6,12,7,16,8,15,9,12' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=140 + TLVPwr:20='0,0,1,16,2,16,3,13,4,16,5,16,6,12,7,15,8,15,9,10' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=144 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=149 + TLVPwr:20='0,0,1,16,2,16,3,13,4,16,5,16,6,12,7,15,8,15,9,10' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=153 + TLVPwr:20='0,0,1,16,2,16,3,13,4,16,5,16,6,12,7,15,8,15,9,10' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=157 + TLVPwr:20='0,0,1,16,2,16,3,13,4,16,5,16,6,12,7,15,8,15,9,10' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=161 + TLVPwr:20='0,0,1,16,2,16,3,13,4,16,5,16,6,12,7,15,8,15,9,10' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=165 + TLVPwr:20='0,0,1,16,2,16,3,13,4,16,5,16,6,12,7,15,8,15,9,10' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=183 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=184 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=185 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=187 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=188 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=189 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=192 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=196 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=7 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=8 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=11 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=12 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=16 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } + ChanTRPC.TlvType:2=0x0189 + ChanTRPC.TlvLength:2={ + TLVStartFreq:2=5000 + TLVChanWidth:1=20 + TLVChanNum:1=34 + TLVPwr:20='0,0,1,16,2,16,3,15,4,16,5,16,6,14,7,16,8,16,9,14' + } +} 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 new file mode 100644 index 0000000..5e978b8 --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/wifi_mod_para.conf @@ -0,0 +1,204 @@ +# Not matter how many spaces or tabs are inserted in a line, +# components and ending format must be exactly same as given +# example: +# +# [_] = { +# key=value +# } +# +# card_type : 8XXX (mandatory) +# block_id : configuration block id (optional ) +# key : module parameter name +# value : value for module parameter +# for string value, no need to add "" +# +# card_type supported: 8887/8897/8997/8977/8987/9098 +# block_id: support same chipset with +# different module parameter. +# For example to support mutiple SD8997 cards, usr can +# specify the configuration block id number [0 - 9], if not +# specified, it is taken as 0 by default. +# +# debug related module parameters could not be set via module +# configure file, ex. drvdbg could not be set in this file +# +# line started with "#" will be ignored +# refer to the USB8997_1 for parameters that could be set in +# this configuration file, and set the corresponding value +# according to your real needs + +SD8997 = { + cfg80211_wext=0xf + wfd_name=p2p + max_vir_bss=1 + cal_data_cfg=nxp/WlanCalData_ext_8997_QFN_TB.conf + drv_mode=7 +} + +#SD8997_1 = { +# cfg80211_wext=0xf +# wfd_name=wfd0 +# max_vir_bss=1 +# cal_data_cfg=nxp/WlanCalData_ext_8997_QFN_TB.conf +# drv_mode=5 +#} + +#SD8887 = { +# cfg80211_wext=0xf +# wfd_name=p2p +# max_vir_bss=1 +# cal_data_cfg=nxp/WlanCalData_ext_8997_QFN_TB.conf +# drv_mode=7 +#} + +#SD8897 = { +# cfg80211_wext=0xf +# wfd_name=p2p +# max_vir_bss=1 +# cal_data_cfg=nxp/WlanCalData_ext_8997_QFN_TB.conf +# drv_mode=7 +#} + +#SD8977 = { +# cfg80211_wext=0xf +# wfd_name=p2p +# max_vir_bss=1 +# cal_data_cfg=nxp/WlanCalData_ext_8997_QFN_TB.conf +# drv_mode=7 +#} + +#SDIW416 = { +# 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 +# max_vir_bss=1 +# cal_data_cfg=nxp/WlanCalData_ext_8997_QFN_TB.conf +# drv_mode=7 +#} + +#SDIW612 = { +# cfg80211_wext=0xf +# wfd_name=p2p +# hw_name=SDIW612 +# max_vir_bss=1 +# drv_mode=7 +#} + +USB8997 = { + cfg80211_wext=0xf + wfd_name=p2p + max_vir_bss=1 + cal_data_cfg=nxp/WlanCalData_ext_8997_QFN_TB.conf + 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 + max_vir_bss=1 + cal_data_cfg=nxp/WlanCalData_ext_8997_QFN_TB.conf + drv_mode=7 +} + +PCIE9098_0 = { + cfg80211_wext=0xf + wfd_name=p2p + max_vir_bss=1 + cal_data_cfg=none + drv_mode=7 + mac_addr=00:50:43:20:12:34 +} + +PCIE9098_1 = { + cfg80211_wext=0xf + wfd_name=p2p + max_vir_bss=1 + cal_data_cfg=none + drv_mode=7 + mac_addr=00:50:43:20:52:56 +} + +#USB8997 = { +# hw_test=0 +# fw_name="nxp/usbusb8997_combo_v4.bin" +# req_fw_nowait=1 +# fw_reload=3 +# fw_serial=1 +# mac_addr=00:50:43:22:1e:3d +# mfg_mode=0 +# drv_mode=0x5 +# max_sta_bss=1 +# sta_name=wlan +# max_uap_bss=1 +# uap_name=uap +# wfd_name=p2p +# max_vir_bss=1 +# max_mpl_bss=1 +# nan_name=nan +# max_nan_bss=1 +# max_11p_bss=1 +# auto_ds=0 +# ps_mode=1 +# max_tx_buf=4096 +# intmode=0 +# gpiopin=0 +# pm_keep_power=0 +# shutdown_hs=1 +# cfg_11d=1 +# start_11ai_scan=0 +# oob_mode=0 +# sdio_pd=1 +# cal_data_cfg=nxp/WlanCalData_ext_8997_QFN_TB.conf +# txpwrtlimit_cfg=nxp/txpwr_limit.conf +# cntry_txpwrt=0 +# init_hostcmd_cfg=nxp/init_hostcmd_cfg.conf +# minicard_pwrup=0 +# cfg80211_wext=0xf +# skip_fwdnld=0 +# wq_sched_prio=0 +# wq_sched_policy=0 +# rx_work=1 +# aggrctrl=1 +# usb_aggr=1 +# pcie_int_mode=1 +# low_power_mode_enable=1 +# wakelock_timeout=10 +# dev_cap_mask=0xffffffff +# sdio_rx_aggr=1 +# pmic=1 +# antcfg=0 +# uap_oper_ctrl=0 +# hs_wake_interval=400 +# indication_gpio=0xff +# disconnect_on_suspend=0 +# hs_mimo_switch=1 +# indrstcfg=0xffffffff +# fixed_beacon_buffer=0 +# GoAgeoutTime=0 +# gtk_rekey_offload=1 +# multi_dtim=0 +# inact_tmo=0 +# usb_fw_option=1 +# napi=1 +# dfs_offload=1 +# cfg80211_drcs=1 +# drcs_chantime_mode=0 +# reg_alpha2=US +#} diff --git a/mxm_wifiex/wlan_src/mapp/mlanutl/Android.mk b/mxm_wifiex/wlan_src/mapp/mlanutl/Android.mk new file mode 100644 index 0000000..8d5e85a --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanutl/Android.mk @@ -0,0 +1,40 @@ +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=n +ifeq ($(CONFIG_USERSPACE_32BIT_OVER_KERNEL_64BIT), y) +LOCAL_CFLAGS += -DUSERSPACE_32BIT_OVER_KERNEL_64BIT +endif + +LOCAL_MODULE := mlanutl +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 new file mode 100644 index 0000000..121d378 --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanutl/Makefile @@ -0,0 +1,59 @@ +# File : mlanutl/Makefile +# +# Copyright 2011-2022 NXP + +# Path to the top directory of the wlan 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)) + + +#CFLAGS += -DAP22 -fshort-enums +CFLAGS += -Wall +CFLAGS += -Wno-stringop-truncation +#ECHO = @ +ifeq (,$(findstring ANDROID_KERNEL, $(CFLAGS))) +LIBS=-lrt +endif + +.PHONY: default tags all + +OBJECTS = mlanutl.o +HEADERS = mlanutl.h + + + + + +exectarget=mlanutl +TARGET := $(exectarget) + +build appsbuild default: $(TARGET) + @cp -f $(TARGET) $(INSTALLPATH) + +all : tags default + +$(TARGET): $(OBJECTS) $(HEADERS) + $(ECHO)$(CC) $(LIBS) -o $@ $(OBJECTS) + +%.o: %.c $(HEADERS) + $(ECHO)$(CC) $(CFLAGS) -c -o $@ $< + +tags: + ctags -R -f tags.txt + +distclean clean: + $(ECHO)$(RM) $(OBJECTS) $(TARGET) + $(ECHO)$(RM) tags.txt + diff --git a/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.c b/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.c new file mode 100644 index 0000000..0c34549 --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.c @@ -0,0 +1,5353 @@ +/** @file mlanutl.c + * + * @brief Program to control parameters in the mlandriver + * + * + * 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 + * (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: + 11/04/2011: initial version +************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "mlanutl.h" + +/** Supported stream modes */ +#define HT_STREAM_MODE_1X1 0x11 +#define HT_STREAM_MODE_2X2 0x22 + +/** mlanutl version number */ +#define MLANUTL_VER "M1.3.02" + +/** Termination flag */ +int terminate_flag = 0; + +/** Termination flag */ +boolean mcast_debug_flag = 0; + +/******************************************************** + Local Variables +********************************************************/ + +#define BAND_B (1U << 0) +#define BAND_G (1U << 1) +#define BAND_A (1U << 2) +#define BAND_GN (1U << 3) +#define BAND_AN (1U << 4) +#define BAND_GAC (1U << 5) +#define BAND_AAC (1U << 6) +#define BAND_GAX (1U << 8) +#define BAND_AAX (1U << 9) + +/** Stringification of rateId enumeration */ +const char *rateIdStr[] = {"1", "2", "5.5", "11", "--", "6", "9", "12", + "18", "24", "36", "48", "54", "--", "M0", "M1", + "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) +#define MERROR MBIT(2) +#define MDATA MBIT(3) +#define MCMND MBIT(4) +#define MEVENT MBIT(5) +#define MINTR MBIT(6) +#define MIOCTL MBIT(7) + +#define MREG_D MBIT(9) + +#define MMPA_D MBIT(15) +#define MDAT_D MBIT(16) +#define MCMD_D MBIT(17) +#define MEVT_D MBIT(18) +#define MFW_D MBIT(19) +#define MIF_D MBIT(20) + +#ifdef DEBUG_LEVEL2 +#define MENTRY MBIT(28) +#define MWARN MBIT(29) +#define MINFO MBIT(30) +#endif +#endif + +#define MAX_CH_LOAD_DURATION 10 + +static int process_version(int argc, char *argv[]); +static int process_verext(int argc, char *argv[]); +static int process_hostcmd(int argc, char *argv[]); +#ifdef DEBUG_LEVEL1 +static int process_drvdbg(int argc, char *argv[]); +#endif +static int process_datarate(int argc, char *argv[]); +static int process_getlog(int argc, char *argv[]); +static int process_get_txpwrlimit(int argc, char *argv[]); +#ifdef STA_SUPPORT +static int process_get_signal(int argc, char *argv[]); +static int process_get_signal_ext(int argc, char *argv[]); +static int process_signalext_cfg(int argc, char *argv[]); +#endif +static int process_vhtcfg(int argc, char *argv[]); +static int process_dyn_bw(int argc, char *argv[]); +static int process_11axcfg(int argc, char *argv[]); +static int process_11axcmdcfg(int argc, char *argv[]); +static int process_txratecfg(int argc, char *argv[]); +static int process_httxcfg(int argc, char *argv[]); +static int process_htcapinfo(int argc, char *argv[]); +static int process_addbapara(int argc, char *argv[]); +static int process_aggrpriotbl(int argc, char *argv[]); +static int process_addbareject(int argc, char *argv[]); +static int process_hssetpara(int argc, char *argv[]); +static int process_mefcfg(int argc, char *argv[]); +static int process_cloud_keep_alive(int argc, char *argv[]); +static int process_min_ba_threshold_cfg(int argc, char *argv[]); +static int process_txwatchdog(int argc, char *argv[]); +static int process_getuuid(int argc, char *argv[]); + +struct command_node command_list[] = { + {"version", process_version}, + {"verext", process_verext}, + {"hostcmd", process_hostcmd}, +#ifdef DEBUG_LEVEL1 + {"drvdbg", process_drvdbg}, +#endif + {"getdatarate", process_datarate}, + {"getlog", process_getlog}, + {"get_txpwrlimit", process_get_txpwrlimit}, +#ifdef STA_SUPPORT + {"getsignal", process_get_signal}, + {"getsignalext", process_get_signal_ext}, + {"getsignalextv2", process_get_signal_ext}, + {"signalextcfg", process_signalext_cfg}, +#endif + {"vhtcfg", process_vhtcfg}, + {"dyn_bw", process_dyn_bw}, + {"11axcfg", process_11axcfg}, + {"11axcmd", process_11axcmdcfg}, + {"txratecfg", process_txratecfg}, + {"addbapara", process_addbapara}, + {"aggrpriotbl", process_aggrpriotbl}, + {"addbareject", process_addbareject}, + {"httxcfg", process_httxcfg}, + {"htcapinfo", process_htcapinfo}, + {"hssetpara", process_hssetpara}, + {"mefcfg", process_mefcfg}, + {"cloud_keep_alive", process_cloud_keep_alive}, + {"min_ba_threshold", process_min_ba_threshold_cfg}, + {"txwatchdog", process_txwatchdog}, + {"getuuid", process_getuuid}, +}; + +static char *usage[] = { + "Usage: ", + " mlanutl -v (version)", + " mlanutl [...]", + " where", + " ifname : wireless network interface name, such as mlanX or uapX", + " cmd :", + " version", + " verext", + " hostcmd", +#ifdef DEBUG_LEVEL1 + " drvdbg", +#endif + " getdatarate", + " getlog", + " get_txpwrlimit", +#ifdef STA_SUPPORT + " getsignal", + " signalextcfg", + " getsignalext", + " getsignalextv2", +#endif + " vhtcfg", + " dyn_bw", + " 11axcfg", + " 11axcmd", + " txratecfg", + " httxcfg", + " htcapinfo", + " aggrpriotbl", + " addbapara", + " addbareject", + " hssetpara", + " mefcfg", + " cloud_keep_alive", + " min_ba_threshold", +}; + +/** Socket */ +t_s32 sockfd; +/** Device name */ +char dev_name[IFNAMSIZ + 1]; +#define HOSTCMD "hostcmd" + +char *config_get_line(char *s, int size, FILE *stream, int *line, char **_pos); +#define BSSID_FILTER 1 +#define SSID_FILTER 2 +/******************************************************** + Global Variables +********************************************************/ + +int setuserscan_filter = 0; +int num_ssid_filter = 0; +/******************************************************** + Local Functions +********************************************************/ +/** + * @brief Convert char to hex integer + * + * @param chr Char to convert + * @return Hex integer or 0 + */ +static int hexval(t_s32 chr) +{ + if (chr >= '0' && chr <= '9') + return chr - '0'; + if (chr >= 'A' && chr <= 'F') + return chr - 'A' + 10; + if (chr >= 'a' && chr <= 'f') + return chr - 'a' + 10; + + return 0; +} + +/** + * @brief Hump hex data + * + * @param prompt A pointer prompt buffer + * @param p A pointer to data buffer + * @param len The len of data buffer + * @param delim Delim char + * @return Hex integer + */ +t_void hexdump(char *prompt, t_void *p, t_s32 len, char delim) +{ + t_s32 i; + t_u8 *s = p; + + if (prompt) { + printf("%s: len=%d\n", prompt, (int)len); + } + for (i = 0; i < len; i++) { + if (i != len - 1) + printf("%02x%c", *s++, delim); + else + printf("%02x\n", *s); + if ((i + 1) % 16 == 0) + printf("\n"); + } + printf("\n"); +} + +/** + * @brief Convert char to hex integer + * + * @param chr Char + * @return Hex integer + */ +t_u8 hexc2bin(char chr) +{ + if (chr >= '0' && chr <= '9') + chr -= '0'; + else if (chr >= 'A' && chr <= 'F') + chr -= ('A' - 10); + else if (chr >= 'a' && chr <= 'f') + chr -= ('a' - 10); + + return chr; +} + +/** + * @brief Convert string to hex integer + * + * @param s A pointer string buffer + * @return Hex integer + */ +t_u32 a2hex(char *s) +{ + t_u32 val = 0; + + if (!strncasecmp("0x", s, 2)) { + s += 2; + } + + while (*s && isxdigit((unsigned char)*s)) { + val = (val << 4) + hexc2bin(*s++); + } + + return val; +} + +/* + * @brief Convert String to integer + * + * @param value A pointer to string + * @return Integer + */ +t_u32 a2hex_or_atoi(char *value) +{ + if (value[0] == '0' && (value[1] == 'X' || value[1] == 'x')) { + return a2hex(value + 2); + } else { + return (t_u32)atoi(value); + } +} + +/** + * @brief Convert string to hex + * + * @param ptr A pointer to data buffer + * @param chr A pointer to return integer + * @return A pointer to next data field + */ +static char *convert2hex(char *ptr, t_u8 *chr) +{ + t_u8 val; + + for (val = 0; *ptr && isxdigit((unsigned char)*ptr); ptr++) { + val = (val * 16) + hexval(*ptr); + } + + *chr = val; + + return ptr; +} + +/** + * @brief Display usage + * + * @return NA + */ +static t_void display_usage(t_void) +{ + t_u32 i; + for (i = 0; i < NELEMENTS(usage); i++) + fprintf(stderr, "%s\n", usage[i]); +} + +/** + * @brief Find and execute command + * + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS for success, otherwise failure + */ +static int process_command(int argc, char *argv[]) +{ + int i = 0, ret = MLAN_STATUS_NOTFOUND; + struct command_node *node = NULL; + + for (i = 0; i < (int)NELEMENTS(command_list); i++) { + node = &command_list[i]; + if (!strcasecmp(node->name, argv[2])) { + ret = node->handler(argc, argv); + break; + } + } + + return ret; +} + +/** + * @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 prepare_buffer(t_u8 *buffer, char *cmd, t_u32 num, char *args[]) +{ + t_u8 *pos = NULL; + unsigned int i = 0; + + memset(buffer, 0, BUFFER_LENGTH); + + /* 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 Trims leading and traling spaces only + * @param str A pointer to argument string + * @return pointer to trimmed string + */ +static char *trim_spaces(char *str) +{ + char *str_end = NULL; + + if (!str) + return NULL; + + /* Trim leading spaces */ + while (!*str && isspace((unsigned char)*str)) + str++; + + if (*str == 0) /* All spaces? */ + return str; + + /* Trim trailing spaces */ + str_end = str + strlen(str) - 1; + while (str_end > str && isspace((unsigned char)*str_end)) + str_end--; + + /* null terminate the string */ + *(str_end + 1) = '\0'; + + return str; +} + +/** + * @brief read current command + * @param ptr A pointer to data + * @param curCmd A pointer to the buf which will hold current command + * @return NULL or the pointer to the left command buf + */ +static t_s8 *readCurCmd(t_s8 *ptr, t_s8 *curCmd) +{ + t_s32 i = 0; +#define MAX_CMD_SIZE 64 /**< Max command size */ + + while (*ptr != ']' && i < (MAX_CMD_SIZE - 1)) + curCmd[i++] = *(++ptr); + + if (*ptr != ']') + return NULL; + + curCmd[i - 1] = '\0'; + + return ++ptr; +} + +/** + * @brief parse command and hex data + * @param fp A pointer to FILE stream + * @param dst A pointer to the dest buf + * @param cmd A pointer to command buf for search + * @return Length of hex data or MLAN_STATUS_FAILURE + */ +static int fparse_for_cmd_and_hex(FILE *fp, t_u8 *dst, t_u8 *cmd) +{ + t_s8 *ptr; + t_u8 *dptr; + t_s8 buf[256], curCmd[64] = {0}; + t_s32 isCurCmd = 0; + + dptr = dst; + while (fgets((char *)buf, sizeof(buf), fp)) { + ptr = buf; + + while (*ptr) { + /* skip leading spaces */ + while (*ptr && isspace((unsigned char)*ptr)) + ptr++; + + /* skip blank lines and lines beginning with '#' */ + if (*ptr == '\0' || *ptr == '#') + break; + + if (*ptr == '[' && *(ptr + 1) != '/') { + ptr = readCurCmd(ptr, curCmd); + if (!ptr) + return MLAN_STATUS_FAILURE; + + if (strcasecmp((char *)curCmd, + (char *)cmd)) /* Not equal */ + isCurCmd = 0; + else + isCurCmd = 1; + } + + /* Ignore the rest if it is not correct cmd */ + if (!isCurCmd) + break; + + if (*ptr == '[' && *(ptr + 1) == '/') + return dptr - dst; + + if (isxdigit((unsigned char)*ptr)) { + ptr = (t_s8 *)convert2hex((char *)ptr, dptr++); + } else { + /* Invalid character on data line */ + ptr++; + } + } + } + + return MLAN_STATUS_FAILURE; +} + +/** + * @brief Process version + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_version(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + prepare_buffer(buffer, argv[2], 0, NULL); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: version fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + /* Process result */ + printf("Version string received: %s\n", buffer); + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief Process extended version + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_verext(int argc, char *argv[]) +{ + int ret = 0; + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + memset(buffer, 0, BUFFER_LENGTH); + + /* Sanity tests */ + if (argc < 3 || argc > 4) { + printf("Error: invalid no of arguments\n"); + printf("mlanutl mlanX verext [#]\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + 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, &buffer, sizeof(buffer)); +#else + cmd->buf = buffer; +#endif + cmd->used_len = 0; + cmd->total_len = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: verext fail\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + /* Process result */ + if (cmd->used_len) + printf("Extended Version string received: %s\n", buffer); + +done: + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return ret; +} + +int process_host_cmd_resp(char *cmd_name, t_u8 *buf); + +/** + * @brief Get one line from the File + * + * @param fp File handler + * @param str Storage location for data. + * @param size Maximum number of characters to read. + * @param lineno A pointer to return current line number + * @return returns string or NULL + */ +char *mlan_config_get_line(FILE *fp, char *str, t_s32 size, int *lineno) +{ + char *start, *end; + int out, next_line; + + if (!fp || !str) + return NULL; + + do { + read_line: + if (!fgets(str, size, fp)) + break; + start = str; + start[size - 1] = '\0'; + end = start + strlen(str); + (*lineno)++; + + out = 1; + while (out && (start < end)) { + next_line = 0; + /* Remove empty lines and lines starting with # */ + switch (start[0]) { + case ' ': /* White space */ + case '\t': /* Tab */ + start++; + break; + case '#': + case '\n': + case '\0': + next_line = 1; + break; + case '\r': + if (start[1] == '\n') + next_line = 1; + else + start++; + break; + default: + out = 0; + break; + } + if (next_line) + goto read_line; + } + + /* Remove # comments unless they are within a double quoted + * string. Remove trailing white space. */ + end = strstr(start, "\""); + if (end) { + end = strstr(end + 1, "\""); + if (!end) + end = start; + } else + end = start; + + end = strstr(end + 1, "#"); + if (end) + *end-- = '\0'; + else + end = start + strlen(start) - 1; + + out = 1; + while (out && (start < end)) { + switch (*end) { + case ' ': /* White space */ + case '\t': /* Tab */ + case '\n': + case '\r': + *end = '\0'; + end--; + break; + default: + out = 0; + break; + } + } + + if (*start == '\0') + continue; + + return start; + } while (1); + + return NULL; +} + +/** + * @brief Parse function for a configuration line + * + * @param s Storage buffer for data + * @param size Maximum size of data + * @param stream File stream pointer + * @param line Pointer to current line within the file + * @param _pos Output string or NULL + * @return String or NULL + */ +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; +} + +/** + * @brief get hostcmd data + * + * @param ln A pointer to line number + * @param buf A pointer to hostcmd data + * @param size A pointer to the return size of hostcmd buffer + * @return MLAN_STATUS_SUCCESS + */ +static int mlan_get_hostcmd_data(FILE *fp, int *ln, t_u8 *buf, t_u16 *size) +{ + t_s32 errors = 0, i; + char line[512], *pos, *pos1, *pos2, *pos3; + t_u16 len; + + while ((pos = mlan_config_get_line(fp, line, sizeof(line), ln))) { + (*ln)++; + if (strcmp(pos, "}") == 0) { + break; + } + + pos1 = strchr(pos, ':'); + if (pos1 == NULL) { + printf("Line %d: Invalid hostcmd line '%s'\n", *ln, + pos); + errors++; + continue; + } + *pos1++ = '\0'; + + pos2 = strchr(pos1, '='); + if (pos2 == NULL) { + printf("Line %d: Invalid hostcmd line '%s'\n", *ln, + pos); + errors++; + continue; + } + *pos2++ = '\0'; + + len = a2hex_or_atoi(pos1); + if (len < 1 || len > BUFFER_LENGTH) { + printf("Line %d: Invalid hostcmd line '%s'\n", *ln, + pos); + errors++; + continue; + } + + *size += len; + + if (*pos2 == '"') { + pos2++; + pos3 = strchr(pos2, '"'); + if (pos3 == NULL) { + printf("Line %d: invalid quotation '%s'\n", *ln, + pos); + errors++; + continue; + } + *pos3 = '\0'; + memset(buf, 0, len); + memmove(buf, pos2, MIN(strlen(pos2), len)); + buf += len; + } else if (*pos2 == '\'') { + pos2++; + pos3 = strchr(pos2, '\''); + if (pos3 == NULL) { + printf("Line %d: invalid quotation '%s'\n", *ln, + pos); + errors++; + continue; + } + *pos3 = ','; + for (i = 0; i < len; i++) { + pos3 = strchr(pos2, ','); + if (pos3 != NULL) { + *pos3 = '\0'; + *buf++ = (t_u8)a2hex_or_atoi(pos2); + pos2 = pos3 + 1; + } else + *buf++ = 0; + } + } else if (*pos2 == '{') { + t_u16 tlvlen = 0, tmp_tlvlen; + mlan_get_hostcmd_data(fp, ln, buf + len, &tlvlen); + tmp_tlvlen = tlvlen; + while (len--) { + *buf++ = (t_u8)(tmp_tlvlen & 0xff); + tmp_tlvlen >>= 8; + } + *size += tlvlen; + buf += tlvlen; + } else { + t_u32 value = a2hex_or_atoi(pos2); + while (len--) { + *buf++ = (t_u8)(value & 0xff); + value >>= 8; + } + } + } + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief Prepare host-command buffer + * @param fp File handler + * @param cmd_name Command name + * @param buf A pointer to comand buffer + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int prepare_host_cmd_buffer(FILE *fp, char *cmd_name, t_u8 *buf) +{ + char line[256], cmdname[256], *pos, cmdcode[10]; + HostCmd_DS_GEN *hostcmd; + t_u32 hostcmd_size = 0; + int ln = 0; + int cmdname_found = 0, cmdcode_found = 0; + + hostcmd = (HostCmd_DS_GEN *)(buf + sizeof(t_u32)); + hostcmd->command = 0xffff; + + snprintf(cmdname, sizeof(cmdname), "%s={", cmd_name); + cmdname_found = 0; + while ((pos = mlan_config_get_line(fp, line, sizeof(line), &ln))) { + if (strcmp(pos, cmdname) == 0) { + cmdname_found = 1; + snprintf(cmdcode, sizeof(cmdcode), "CmdCode="); + cmdcode_found = 0; + while ((pos = mlan_config_get_line( + fp, line, sizeof(line), &ln))) { + if (strncmp(pos, cmdcode, strlen(cmdcode)) == + 0) { + t_u16 len = 0; + cmdcode_found = 1; + hostcmd->command = a2hex_or_atoi( + pos + strlen(cmdcode)); + hostcmd->size = S_DS_GEN; + mlan_get_hostcmd_data( + fp, &ln, + buf + sizeof(t_u32) + + hostcmd->size, + &len); + hostcmd->size += len; + break; + } + } + if (!cmdcode_found) { + fprintf(stderr, + "mlanutl: CmdCode not found in conf file\n"); + return MLAN_STATUS_FAILURE; + } + break; + } + } + + if (!cmdname_found) { + fprintf(stderr, + "mlanutl: cmdname '%s' is not found in conf file\n", + cmd_name); + return MLAN_STATUS_FAILURE; + } + + hostcmd->seq_num = 0; + hostcmd->result = 0; + hostcmd->command = cpu_to_le16(hostcmd->command); + hostcmd->size = cpu_to_le16(hostcmd->size); + + hostcmd_size = (t_u32)(hostcmd->size); + memcpy(buf, (t_u8 *)&hostcmd_size, sizeof(t_u32)); + + return MLAN_STATUS_SUCCESS; +} + +#define CMDCODE_OFFSET 0 +#define SUBID_OFFSET (S_DS_GEN + 2) + +static const t_u16 debug_cmd = 0x008b; +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}; + +static int check_if_hostcmd_allowed(t_u8 *buf) +{ + t_u32 maxcnt_cmd = sizeof(supported_cmd) / sizeof(supported_cmd[0]); + t_u32 maxcnt_subcmd = + sizeof(supported_8b_subcmd) / sizeof(supported_8b_subcmd[0]); + + /* Check if CmdCode is 0x008b (debug cmd from debug.conf) */ + if (!memcmp(buf + CMDCODE_OFFSET, &debug_cmd, sizeof(t_u16))) { + for (int i = 0; i < maxcnt_subcmd; i++) { + /* Check if SUBID matches with allowed subcmd */ + if (!memcmp(buf + SUBID_OFFSET, + (supported_8b_subcmd + i), sizeof(t_u16))) + return MLAN_STATUS_SUCCESS; + } + return MLAN_STATUS_NOTFOUND; + } + + for (int i = 0; i < maxcnt_cmd; i++) { + /* If CmdCode is other than 0x008b, then only check the CmdCode + */ + if (!memcmp(buf + CMDCODE_OFFSET, (supported_cmd + i), + sizeof(t_u16))) + return MLAN_STATUS_SUCCESS; + } + + return MLAN_STATUS_NOTFOUND; +} + +/** + * @brief Process hostcmd command + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_hostcmd(int argc, char *argv[]) +{ + t_u8 *buffer = NULL, *raw_buf = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + FILE *fp = NULL; + FILE *fp_raw = NULL; + FILE *fp_dtsi = NULL; + char cmdname[256]; + boolean call_ioctl = TRUE; + t_u32 buf_len = 0, i, j, k; + char *line = NULL, *pos = NULL; + int li = 0, blk_count = 0, ob = 0; + int ret = MLAN_STATUS_SUCCESS; + + struct cmd_node { + char cmd_string[256]; + struct cmd_node *next; + }; + struct cmd_node *command = NULL, *header = NULL, *new_node = NULL; + + if (argc < 5) { + printf("Error: invalid no of arguments\n"); + printf("Syntax: ./mlanutl mlanX hostcmd \n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + snprintf(cmdname, sizeof(cmdname), "%s", argv[4]); + + if (!strcmp(cmdname, "generate_raw")) { + call_ioctl = FALSE; + } + if (!call_ioctl && argc != 6) { + printf("Error: invalid no of arguments\n"); + printf("Syntax: ./mlanutl mlanX hostcmd %s \n", + cmdname); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + fp = fopen(argv[3], "r"); + if (fp == NULL) { + fprintf(stderr, "Cannot open file %s\n", argv[3]); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + fclose(fp); + ret = MLAN_STATUS_FAILURE; + goto done; + } + memset(buffer, 0, BUFFER_LENGTH); + + if (call_ioctl) { + /* Prepare the hostcmd buffer */ + prepare_buffer(buffer, argv[2], 0, NULL); + if (MLAN_STATUS_FAILURE == + prepare_host_cmd_buffer(fp, cmdname, + buffer + strlen(CMD_NXP) + + strlen(argv[2]))) { + fclose(fp); + ret = MLAN_STATUS_FAILURE; + goto done; + } + fclose(fp); + } else { + line = (char *)malloc(MAX_CONFIG_LINE); + if (!line) { + printf("ERR:Cannot allocate memory for line\n"); + fclose(fp); + ret = MLAN_STATUS_FAILURE; + goto done; + } + memset(line, 0, MAX_CONFIG_LINE); + + while (config_get_line(line, MAX_CONFIG_LINE, fp, &li, &pos)) { + line = trim_spaces(line); + if (line[strlen(line) - 1] == '{') { + if (ob == 0) { + new_node = (struct cmd_node *)malloc( + sizeof(struct cmd_node)); + if (!new_node) { + printf("ERR:Cannot allocate memory for cmd_node\n"); + fclose(fp); + ret = MLAN_STATUS_FAILURE; + goto done; + } + memset(new_node, 0, + sizeof(struct cmd_node)); + new_node->next = NULL; + if (blk_count == 0) { + header = new_node; + command = new_node; + } else { + command->next = new_node; + command = new_node; + } + strncpy(command->cmd_string, line, + (strchr(line, '=') - line)); + memmove(command->cmd_string, + trim_spaces( + command->cmd_string), + strlen(trim_spaces( + command->cmd_string)) + + 1); + } + ob++; + continue; /* goto while() */ + } + if (line[strlen(line) - 1] == '}') { + ob--; + if (ob == 0) + blk_count++; + continue; /* goto while() */ + } + } + + rewind(fp); /* Set the source file pointer to the beginning + again */ + command = header; /* Set 'command' at the beginning of the + command list */ + + fp_raw = fopen(argv[5], "w"); + if (fp_raw == NULL) { + fprintf(stderr, + "Cannot open the destination raw_data file %s\n", + argv[5]); + fclose(fp); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + /* prepare .dtsi output */ + snprintf(cmdname, sizeof(cmdname), "%s.dtsi", argv[5]); + fp_dtsi = fopen(cmdname, "w"); + if (fp_dtsi == NULL) { + fprintf(stderr, "Cannot open the destination file %s\n", + cmdname); + fclose(fp); + fclose(fp_raw); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + for (k = 0; k < (t_u32)blk_count && command != NULL; k++) { + if (MLAN_STATUS_FAILURE == + prepare_host_cmd_buffer(fp, command->cmd_string, + buffer)) + memset(buffer, 0, BUFFER_LENGTH); + + memcpy(&buf_len, buffer, sizeof(t_u32)); + if (buf_len) { + raw_buf = buffer + sizeof(t_u32); /* raw_buf + points to + start of + actual */ + printf("buf_len = %d\n", (int)buf_len); + if (k > 0) + fprintf(fp_raw, "\n\n"); + fprintf(fp_raw, "%s={\n", command->cmd_string); + fprintf(fp_dtsi, + "/ {\n\tmarvell_cfgdata {\n\t\tmarvell,%s = /bits/ 8 <\n", + command->cmd_string); + i = j = 0; + while (i < buf_len) { + for (j = 0; j < 16; j++) { + fprintf(fp_raw, "%02x ", + *(raw_buf + i)); + if (i >= 8) { + fprintf(fp_dtsi, + "0x%02x", + *(raw_buf + i)); + if ((j < 16 - 1) && + (i < buf_len - 1)) + fprintf(fp_dtsi, + " "); + } + if (++i >= buf_len) + break; + } + fputc('\n', fp_raw); + fputc('\n', fp_dtsi); + } + fprintf(fp_raw, "}"); + fprintf(fp_dtsi, "\t\t>;\n\t};\n};\n"); + } + command = command->next; + rewind(fp); + } + + fclose(fp_dtsi); + fclose(fp_raw); + fclose(fp); + } + + if (call_ioctl) { + /* raw_buf points to start of command id */ + raw_buf = buffer + strlen(CMD_NXP) + strlen(argv[2]) + + sizeof(t_u32); + if (check_if_hostcmd_allowed(raw_buf) != MLAN_STATUS_SUCCESS) { + printf("ERR:Entered hostcmd not allowed!\n"); + 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, &buffer, sizeof(buffer)); +#else + cmd->buf = buffer; +#endif + cmd->used_len = 0; + cmd->total_len = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: hostcmd fail\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + /* Process result */ + process_host_cmd_resp(argv[2], buffer); + } +done: + while (header) { + command = header; + header = header->next; + free(command); + } + if (line) + free(line); + if (buffer) + free(buffer); + if (cmd) + free(cmd); + return ret; +} + +#ifdef DEBUG_LEVEL1 +/** + * @brief Process driver debug configuration + * @param argc number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_drvdbg(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + t_u32 drvdbg; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: drvdbg config fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + /* Process result */ + if (argc == 3) { + memcpy(&drvdbg, buffer, sizeof(drvdbg)); + printf("drvdbg: 0x%08x\n", drvdbg); +#ifdef DEBUG_LEVEL2 + printf("MINFO (%08x) %s\n", MINFO, + (drvdbg & MINFO) ? "X" : ""); + printf("MWARN (%08x) %s\n", MWARN, + (drvdbg & MWARN) ? "X" : ""); + printf("MENTRY (%08x) %s\n", MENTRY, + (drvdbg & MENTRY) ? "X" : ""); +#endif + printf("MMPA_D (%08x) %s\n", MMPA_D, + (drvdbg & MMPA_D) ? "X" : ""); + printf("MIF_D (%08x) %s\n", MIF_D, + (drvdbg & MIF_D) ? "X" : ""); + printf("MFW_D (%08x) %s\n", MFW_D, + (drvdbg & MFW_D) ? "X" : ""); + printf("MEVT_D (%08x) %s\n", MEVT_D, + (drvdbg & MEVT_D) ? "X" : ""); + printf("MCMD_D (%08x) %s\n", MCMD_D, + (drvdbg & MCMD_D) ? "X" : ""); + printf("MDAT_D (%08x) %s\n", MDAT_D, + (drvdbg & MDAT_D) ? "X" : ""); + printf("MREG_D (%08x) %s\n", MREG_D, + (drvdbg & MREG_D) ? "X" : ""); + printf("MIOCTL (%08x) %s\n", MIOCTL, + (drvdbg & MIOCTL) ? "X" : ""); + printf("MINTR (%08x) %s\n", MINTR, + (drvdbg & MINTR) ? "X" : ""); + printf("MEVENT (%08x) %s\n", MEVENT, + (drvdbg & MEVENT) ? "X" : ""); + printf("MCMND (%08x) %s\n", MCMND, + (drvdbg & MCMND) ? "X" : ""); + printf("MDATA (%08x) %s\n", MDATA, + (drvdbg & MDATA) ? "X" : ""); + printf("MERROR (%08x) %s\n", MERROR, + (drvdbg & MERROR) ? "X" : ""); + printf("MFATAL (%08x) %s\n", MFATAL, + (drvdbg & MFATAL) ? "X" : ""); + printf("MMSG (%08x) %s\n", MMSG, (drvdbg & MMSG) ? "X" : ""); + } + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} +#endif + +static char *rate_format[4] = {"LG", "HT", "VHT", "HE"}; +static char *lg_rate[] = {"1 Mbps", "2 Mbps", "5.5 Mbps", "11 Mbps", + "6 Mbps", "9 Mbps", "12 Mbps", "18 Mbps", + "24 Mbps", "36 Mbps", "48 Mbps", "54 Mbps"}; + +/** + * @brief Process Get data rate + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_datarate(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct eth_priv_data_rate *datarate = NULL; + struct ifreq ifr; + char *bw[] = {"20 MHz", "40 MHz", "80 MHz", "160 MHz"}; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + prepare_buffer(buffer, argv[2], 0, NULL); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: getdatarate fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + /* Process result */ + datarate = (struct eth_priv_data_rate *)buffer; + printf("Data Rate:\n"); + printf(" TX: \n"); + if (datarate->tx_rate_format <= 3) { + printf(" Type: %s\n", rate_format[datarate->tx_rate_format]); + if ((datarate->tx_rate_format == 0) && + datarate->tx_data_rate <= 11) + /* LG */ + printf(" Rate: %s\n", + lg_rate[datarate->tx_data_rate]); + else { + /* HT and VHT*/ + if (datarate->tx_bw <= 3) + printf(" BW: %s\n", bw[datarate->tx_bw]); + if (datarate->tx_rate_format < 3) { + if (datarate->tx_gi == 0) + printf(" GI: Long\n"); + else + printf(" GI: Short\n"); + } else if (datarate->tx_rate_format == 3) { + switch (datarate->tx_gi) { + case 0: + printf(" GI: 1xHELTF + GI 0.8us \n"); + break; + case 1: + printf(" GI: 2xHELTF + GI 0.8us \n"); + break; + case 2: + printf(" GI: 2xHELTF + GI 1.6us \n"); + break; + case 3: + printf(" GI: 4xHELTF + GI 0.8us DCM=0 and STBC=0 or\n" + " 4xHELTF + GI 3.2us Otherwise \n"); + break; + } + } + if (datarate->tx_rate_format >= 2) + printf(" NSS: %d\n", datarate->tx_nss + 1); + if (datarate->tx_mcs_index != 0xFF) + printf(" MCS: MCS %d\n", + (int)datarate->tx_mcs_index); + else + printf(" MCS: Auto\n"); + if (datarate->tx_rate_format < 3) + printf(" Rate: %f Mbps\n", + (float)datarate->tx_data_rate / 2); + } + } + + printf(" RX: \n"); + if (datarate->rx_rate_format <= 3) { + printf(" Type: %s\n", rate_format[datarate->rx_rate_format]); + if ((datarate->rx_rate_format == 0) && + datarate->rx_data_rate <= 11) + /* LG */ + printf(" Rate: %s\n", + lg_rate[datarate->rx_data_rate]); + else { + /* HT and VHT*/ + if (datarate->rx_bw <= 3) + printf(" BW: %s\n", bw[datarate->rx_bw]); + if (datarate->rx_rate_format < 3) { + if (datarate->rx_gi == 0) + printf(" GI: Long\n"); + else + printf(" GI: Short\n"); + } else if (datarate->rx_rate_format == 3) { + switch (datarate->rx_gi) { + case 0: + printf(" GI: 1xHELTF + GI 0.8us \n"); + break; + case 1: + printf(" GI: 2xHELTF + GI 0.8us \n"); + break; + case 2: + printf(" GI: 2xHELTF + GI 1.6us \n"); + break; + case 3: + printf(" GI: 4xHELTF + GI 0.8us DCM=0 and STBC=0 or\n" + " 4xHELTF + GI 3.2us Otherwise \n"); + break; + } + } + if (datarate->rx_rate_format >= 2) + printf(" NSS: %d\n", datarate->rx_nss + 1); + if (datarate->rx_mcs_index != 0xFF) + printf(" MCS: MCS %d\n", + (int)datarate->rx_mcs_index); + else + printf(" MCS: Auto\n"); + if (datarate->rx_rate_format < 3) + printf(" Rate: %f Mbps\n", + (float)datarate->rx_data_rate / 2); + } + } + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief Process get wireless stats + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_getlog(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct eth_priv_get_log *stats = NULL; + struct ifreq ifr; + struct timeval tv; + int i = 0; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: getlog fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + gettimeofday(&tv, NULL); + + /* Process results */ + stats = (struct eth_priv_get_log *)buffer; + printf("Get log: timestamp %d.%06d sec\n", (int)tv.tv_sec, + (int)tv.tv_usec); + printf("dot11GroupTransmittedFrameCount %u\n" + "dot11FailedCount %u\n" + "dot11RetryCount %u\n" + "dot11MultipleRetryCount %u\n" + "dot11FrameDuplicateCount %u\n" + "dot11RTSSuccessCount %u\n" + "dot11RTSFailureCount %u\n" + "dot11ACKFailureCount %u\n" + "dot11ReceivedFragmentCount %u\n" + "dot11GroupReceivedFrameCount %u\n" + "dot11FCSErrorCount %u\n" + "dot11TransmittedFrameCount %u\n" + "wepicverrcnt-1 %u\n" + "wepicverrcnt-2 %u\n" + "wepicverrcnt-3 %u\n" + "wepicverrcnt-4 %u\n" + "beaconReceivedCount %u\n" + "beaconMissedCount %u\n", + stats->mcast_tx_frame, stats->failed, stats->retry, + stats->multi_retry, stats->frame_dup, stats->rts_success, + stats->rts_failure, stats->ack_failure, stats->rx_frag, + stats->mcast_rx_frame, stats->fcs_error, stats->tx_frame, + stats->wep_icv_error[0], stats->wep_icv_error[1], + stats->wep_icv_error[2], stats->wep_icv_error[3], + stats->bcn_rcv_cnt, stats->bcn_miss_cnt); + + if (argc == 4 && !(strcmp(argv[3], "ext"))) { + printf("rxStuckIssueCount-1 %u\n" + "rxStuckIssueCount-2 %u\n" + "rxStuckRecoveryCount %u\n" + "rxStuckTsf-1 %llu\n" + "rxStuckTsf-2 %llu\n" + "txWatchdogRecoveryCount %u\n" + "txWatchdogTsf-1 %llu\n" + "txWatchdogTsf-2 %llu\n" + "channelSwitchAnnouncementSent %u\n" + "channelSwitchState %u\n" + "registerClass %u\n" + "channelNumber %u\n" + "channelSwitchMode %u\n" + "RxResetRecoveryCount %u\n" + "RxIsr2NotDoneCnt %u\n" + "gdmaAbortCnt %u\n" + "gResetRxMacCnt %u\n" + "gOwnrshpCtlErrCnt %u\n" + "gOwnrshpBcnErrCnt %u\n" + "gOwnrshpMgtErrCnt %u\n" + "gOwnrshpDatErrCnt %u\n" + "bigtk_mmeGoodCnt %u\n" + "bigtk_replayErrCnt %u\n" + "bigtk_micErrCnt %u\n" + "bigtk_mmeNotFoundCnt %u\n", + stats->rx_stuck_issue_cnt[0], + stats->rx_stuck_issue_cnt[1], + stats->rx_stuck_recovery_cnt, stats->rx_stuck_tsf[0], + stats->rx_stuck_tsf[1], stats->tx_watchdog_recovery_cnt, + stats->tx_watchdog_tsf[0], stats->tx_watchdog_tsf[1], + stats->channel_switch_ann_sent, + stats->channel_switch_state, stats->reg_class, + stats->channel_number, stats->channel_switch_mode, + stats->rx_reset_mac_recovery_cnt, + stats->rx_Isr2_NotDone_Cnt, stats->gdma_abort_cnt, + stats->g_reset_rx_mac_cnt, stats->dwCtlErrCnt, + stats->dwBcnErrCnt, stats->dwMgtErrCnt, + stats->dwDatErrCnt, stats->bigtk_mmeGoodCnt, + stats->bigtk_replayErrCnt, stats->bigtk_micErrCnt, + stats->bigtk_mmeNotFoundCnt); + } + + if (cmd->used_len == sizeof(struct eth_priv_get_log)) { + printf("dot11TransmittedFragmentCount %u\n", + stats->tx_frag_cnt); + printf("dot11QosTransmittedFragmentCount "); + for (i = 0; i < 8; i++) { + printf("%u ", stats->qos_tx_frag_cnt[i]); + } + printf("\ndot11QosFailedCount "); + for (i = 0; i < 8; i++) { + printf("%u ", stats->qos_failed_cnt[i]); + } + printf("\ndot11QosRetryCount "); + for (i = 0; i < 8; i++) { + printf("%u ", stats->qos_retry_cnt[i]); + } + printf("\ndot11QosMultipleRetryCount "); + for (i = 0; i < 8; i++) { + printf("%u ", stats->qos_multi_retry_cnt[i]); + } + printf("\ndot11QosFrameDuplicateCount "); + for (i = 0; i < 8; i++) { + printf("%u ", stats->qos_frm_dup_cnt[i]); + } + printf("\ndot11QosRTSSuccessCount "); + for (i = 0; i < 8; i++) { + printf("%u ", stats->qos_rts_suc_cnt[i]); + } + printf("\ndot11QosRTSFailureCount "); + for (i = 0; i < 8; i++) { + printf("%u ", stats->qos_rts_failure_cnt[i]); + } + printf("\ndot11QosACKFailureCount "); + for (i = 0; i < 8; i++) { + printf("%u ", stats->qos_ack_failure_cnt[i]); + } + printf("\ndot11QosReceivedFragmentCount "); + for (i = 0; i < 8; i++) { + printf("%u ", stats->qos_rx_frag_cnt[i]); + } + printf("\ndot11QosTransmittedFrameCount "); + for (i = 0; i < 8; i++) { + printf("%u ", stats->qos_tx_frm_cnt[i]); + } + printf("\ndot11QosDiscardedFrameCount "); + for (i = 0; i < 8; i++) { + printf("%u ", stats->qos_discarded_frm_cnt[i]); + } + printf("\ndot11QosMPDUsReceivedCount "); + for (i = 0; i < 8; i++) { + printf("%u ", stats->qos_mpdus_rx_cnt[i]); + } + printf("\ndot11QosRetriesReceivedCount "); + for (i = 0; i < 8; i++) { + printf("%u ", stats->qos_retries_rx_cnt[i]); + } + printf("\ndot11RSNAStatsCMACICVErrors %u\n" + "dot11RSNAStatsCMACReplays %u\n" + "dot11RSNAStatsRobustMgmtCCMPReplays %u\n" + "dot11RSNAStatsTKIPICVErrors %u\n" + "dot11RSNAStatsTKIPReplays %u\n" + "dot11RSNAStatsCCMPDecryptErrors %u\n" + "dot11RSNAstatsCCMPReplays %u\n" + "dot11TransmittedAMSDUCount %u\n" + "dot11FailedAMSDUCount %u\n" + "dot11RetryAMSDUCount %u\n" + "dot11MultipleRetryAMSDUCount %u\n" + "dot11TransmittedOctetsInAMSDUCount %llu\n" + "dot11AMSDUAckFailureCount %u\n" + "dot11ReceivedAMSDUCount %u\n" + "dot11ReceivedOctetsInAMSDUCount %llu\n" + "dot11TransmittedAMPDUCount %u\n" + "dot11TransmittedMPDUsInAMPDUCount %u\n" + "dot11TransmittedOctetsInAMPDUCount %llu\n" + "dot11AMPDUReceivedCount %u\n" + "dot11MPDUInReceivedAMPDUCount %u\n" + "dot11ReceivedOctetsInAMPDUCount %llu\n" + "dot11AMPDUDelimiterCRCErrorCount %u\n", + stats->cmacicv_errors, stats->cmac_replays, + stats->mgmt_ccmp_replays, stats->tkipicv_errors, + stats->tkip_replays, stats->ccmp_decrypt_errors, + stats->ccmp_replays, stats->tx_amsdu_cnt, + stats->failed_amsdu_cnt, stats->retry_amsdu_cnt, + stats->multi_retry_amsdu_cnt, + stats->tx_octets_in_amsdu_cnt, + stats->amsdu_ack_failure_cnt, stats->rx_amsdu_cnt, + stats->rx_octets_in_amsdu_cnt, stats->tx_ampdu_cnt, + stats->tx_mpdus_in_ampdu_cnt, + stats->tx_octets_in_ampdu_cnt, stats->ampdu_rx_cnt, + stats->mpdu_in_rx_ampdu_cnt, + stats->rx_octets_in_ampdu_cnt, + stats->ampdu_delimiter_crc_error_cnt); + } + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} + +#ifdef STA_SUPPORT +/** + * @brief Get signal + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_get_signal(int argc, char *argv[]) +{ +#define DATA_SIZE 12 + int ret = 0, data[DATA_SIZE], i = 0, copy_size = 0; + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + + memset(data, 0, sizeof(data)); + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + memset(buffer, 0, BUFFER_LENGTH); + + /* Sanity tests */ + if (argc < 3 || argc > 5) { + printf("Error: invalid no of arguments\n"); + printf("mlanutl mlanX getsignal [m] [n]\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + 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, &buffer, sizeof(buffer)); +#else + cmd->buf = buffer; +#endif + cmd->used_len = 0; + cmd->total_len = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: getsignal fail\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + /* Process result */ + copy_size = + (int)MIN((int)cmd->used_len, (int)(DATA_SIZE * sizeof(int))); + if (copy_size > 0) + memcpy(&data, buffer, copy_size); + printf("Get signal output is\t"); + for (i = 0; i < (int)(copy_size / sizeof(int)); i++) + printf("%d\t", data[i]); + printf("\n"); + +done: + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return ret; +} + +/** + * @brief Set signalext cfg + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_signalext_cfg(int argc, char *argv[]) +{ + int ret = 0; + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + memset(buffer, 0, BUFFER_LENGTH); + + /* Sanity tests */ + if (argc != 4) { + printf("Error: invalid no of arguments\n"); + printf("mlanutl mlanX signalextcfg [#]\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + 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, &buffer, sizeof(buffer)); +#else + cmd->buf = buffer; +#endif + cmd->used_len = 0; + cmd->total_len = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: signalext cfg fail\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + +done: + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return ret; +} + +/** + * @brief Get signal + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_get_signal_ext(int argc, char *argv[]) +{ +#define MAX_NUM_PATH 3 +#define PATH_SIZE 13 +#define PATH_A 1 +#define PATH_B 2 +#define PATH_AB 3 + int ret = 0, data[PATH_SIZE * MAX_NUM_PATH] = {0}; + int i = 0, copy_size = 0; + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + t_u8 num_path = 0; + + memset(data, 0, sizeof(data)); + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + memset(buffer, 0, BUFFER_LENGTH); + + /* Sanity tests */ + if (argc != 3 && argc != 4) { + printf("Error: invalid no of arguments\n"); + if (strncmp(argv[2], "getsignalextv2", + strlen("getsignalextv2")) == 0) + printf("mlanutl mlanX getsignalextv2 [m]\n"); + else if (strncmp(argv[2], "getsignalext", + strlen("getsignalext")) == 0) + printf("mlanutl mlanX getsignalext [m]\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + 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, &buffer, sizeof(buffer)); +#else + cmd->buf = buffer; +#endif + cmd->used_len = 0; + cmd->total_len = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: getsignal fail\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + /* Process result */ + copy_size = cmd->used_len; + if (copy_size > 0) + memcpy(&data, (int *)buffer, copy_size); + + num_path = copy_size / sizeof(int) / PATH_SIZE; + for (i = 0; i < num_path; i++) { + if (data[i * PATH_SIZE] == PATH_A) + printf("PATH A: %d %d %d %d %d %d %d %d %d %d %d %d\n", + data[i * PATH_SIZE + 1], data[i * PATH_SIZE + 2], + data[i * PATH_SIZE + 3], data[i * PATH_SIZE + 4], + data[i * PATH_SIZE + 5], data[i * PATH_SIZE + 6], + data[i * PATH_SIZE + 7], data[i * PATH_SIZE + 8], + data[i * PATH_SIZE + 9], + data[i * PATH_SIZE + 10], + data[i * PATH_SIZE + 11], + data[i * PATH_SIZE + 12]); + else if (data[i * PATH_SIZE] == PATH_B) + printf("PATH B: %d %d %d %d %d %d %d %d %d %d %d %d\n", + data[i * PATH_SIZE + 1], data[i * PATH_SIZE + 2], + data[i * PATH_SIZE + 3], data[i * PATH_SIZE + 4], + data[i * PATH_SIZE + 5], data[i * PATH_SIZE + 6], + data[i * PATH_SIZE + 7], data[i * PATH_SIZE + 8], + data[i * PATH_SIZE + 9], + data[i * PATH_SIZE + 10], + data[i * PATH_SIZE + 11], + data[i * PATH_SIZE + 12]); + else if (data[i * PATH_SIZE] == PATH_AB) + printf("PATH A+B: %d %d %d %d %d %d %d %d %d %d %d %d\n", + data[i * PATH_SIZE + 1], data[i * PATH_SIZE + 2], + data[i * PATH_SIZE + 3], data[i * PATH_SIZE + 4], + data[i * PATH_SIZE + 5], data[i * PATH_SIZE + 6], + data[i * PATH_SIZE + 7], data[i * PATH_SIZE + 8], + data[i * PATH_SIZE + 9], + data[i * PATH_SIZE + 10], + data[i * PATH_SIZE + 11], + data[i * PATH_SIZE + 12]); + } + printf("\n"); + +done: + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return ret; +} +#endif /* #ifdef STA_SUPPORT */ + +/** + * @brief Get txpwrlimit + * + * @param argc Number of arguments + * @param argv Pointer to the arguments array + * + * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_FAILURE + */ +static int get_txpwrlimit(FILE *fp_raw, char *argv[], t_u16 sub_band, + t_u8 *buffer, t_u16 len, struct eth_priv_cmd *cmd) +{ + struct ifreq ifr; + mlan_ds_misc_chan_trpc_cfg *trcp_cfg = NULL; + MrvlIETypes_ChanTRPCConfig_t *trpc_tlv = NULL; + MrvlIEtypes_Data_t *pTlvHdr; + int left_len; + int mod_num = 0; + int i = 0; + int j = 0; + t_u8 *pByte = NULL; + + memset(buffer, 0, len); + /* Insert command */ + strncpy((char *)buffer, argv[2], strlen(argv[2])); + trcp_cfg = (mlan_ds_misc_chan_trpc_cfg *)(buffer + strlen(argv[2])); + trcp_cfg->sub_band = sub_band; + if (cmd) { + /* 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 = len; + } + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: get_txpwrlimit fail\n"); + return MLAN_STATUS_FAILURE; + } + /* Process result */ + printf("------------------------------------------------------------------------------------\n"); + printf("Get txpwrlimit: sub_band=0x%x len=%d\n", trcp_cfg->sub_band, + trcp_cfg->length); + pByte = trcp_cfg->trpc_buf + S_DS_GEN + 4; + left_len = trcp_cfg->length - S_DS_GEN - 4; + while (left_len >= (int)sizeof(pTlvHdr->header)) { + pTlvHdr = (MrvlIEtypes_Data_t *)pByte; + pTlvHdr->header.len = le16_to_cpu(pTlvHdr->header.len); + + switch (le16_to_cpu(pTlvHdr->header.type)) { + case TLV_TYPE_CHAN_TRPC_CONFIG: + trpc_tlv = (MrvlIETypes_ChanTRPCConfig_t *)pTlvHdr; + printf("StartFreq: %d\n", trpc_tlv->start_freq); + printf("ChanWidth: %d\n", trpc_tlv->width); + printf("ChanNum: %d\n", trpc_tlv->chan_num); + mod_num = (pTlvHdr->header.len - 4) / + sizeof(mod_group_setting); + printf("Pwr:"); + for (i = 0; i < mod_num; i++) { + if (i == (mod_num - 1)) + printf("%d,%d", + trpc_tlv->mod_group[i].mod_group, + trpc_tlv->mod_group[i].power); + else + printf("%d,%d,", + trpc_tlv->mod_group[i].mod_group, + trpc_tlv->mod_group[i].power); + } + printf("\n"); + break; + default: + break; + } + left_len -= (pTlvHdr->header.len + sizeof(pTlvHdr->header)); + pByte += pTlvHdr->header.len + sizeof(pTlvHdr->header); + } + if (fp_raw) { + switch (sub_band) { + case 0: + fprintf(fp_raw, "txpwrlimit_2g_get={\n"); + break; + case 0x10: + fprintf(fp_raw, "txpwrlimit_5g_sub0_get={\n"); + break; + case 0x11: + fprintf(fp_raw, "txpwrlimit_5g_sub1_get={\n"); + break; + case 0x12: + fprintf(fp_raw, "txpwrlimit_5g_sub2_get={\n"); + break; + case 0x13: + fprintf(fp_raw, "txpwrlimit_5g_sub3_get={\n"); + break; + default: + break; + } + i = j = 0; + while (i < trcp_cfg->length) { + for (j = 0; j < 16; j++) { + fprintf(fp_raw, "%02x ", trcp_cfg->trpc_buf[i]); + if (++i >= trcp_cfg->length) + break; + } + fputc('\n', fp_raw); + } + fprintf(fp_raw, "}\n\n"); + } + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief Get txpwrlimit + * + * @param argc Number of arguments + * @param argv Pointer to the arguments array + * + * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_FAILURE + */ +static int process_get_txpwrlimit(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + int ret = MLAN_STATUS_SUCCESS; + t_u16 sub_band = 0; + FILE *fp_raw = NULL; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(sizeof(mlan_ds_misc_chan_trpc_cfg) + + strlen(argv[2])); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + memset(buffer, 0, sizeof(mlan_ds_misc_chan_trpc_cfg) + strlen(argv[2])); + /* Sanity tests */ + if (argc < 4) { + printf("Error: invalid no of arguments\n"); + printf("mlanutl mlanX/uapX get_txpwrlimit [0/0x10/0x11/0x12/0x13/0x1f/0xff]\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; + } + sub_band = a2hex_or_atoi(argv[3]); + if (argc == 5) { + fp_raw = fopen(argv[4], "w"); + if (fp_raw == NULL) { + fprintf(stderr, + "Cannot open the destination raw_data file %s\n", + argv[4]); + ret = MLAN_STATUS_FAILURE; + goto done; + } + } + switch (sub_band) { + case 0: + case 0x10: + case 0x11: + case 0x12: + case 0x13: + ret = get_txpwrlimit(fp_raw, argv, sub_band, buffer, + sizeof(mlan_ds_misc_chan_trpc_cfg) + + strlen(argv[2]), + cmd); + break; + case 0x1f: + ret = get_txpwrlimit(fp_raw, argv, 0x10, buffer, + sizeof(mlan_ds_misc_chan_trpc_cfg) + + strlen(argv[2]), + cmd); + ret = get_txpwrlimit(fp_raw, argv, 0x11, buffer, + sizeof(mlan_ds_misc_chan_trpc_cfg) + + strlen(argv[2]), + cmd); + ret = get_txpwrlimit(fp_raw, argv, 0x12, buffer, + sizeof(mlan_ds_misc_chan_trpc_cfg) + + strlen(argv[2]), + cmd); + ret = get_txpwrlimit(fp_raw, argv, 0x13, buffer, + sizeof(mlan_ds_misc_chan_trpc_cfg) + + strlen(argv[2]), + cmd); + break; + case 0xff: + ret = get_txpwrlimit(fp_raw, argv, 0, buffer, + sizeof(mlan_ds_misc_chan_trpc_cfg) + + strlen(argv[2]), + cmd); + ret = get_txpwrlimit(fp_raw, argv, 0x10, buffer, + sizeof(mlan_ds_misc_chan_trpc_cfg) + + strlen(argv[2]), + cmd); + ret = get_txpwrlimit(fp_raw, argv, 0x11, buffer, + sizeof(mlan_ds_misc_chan_trpc_cfg) + + strlen(argv[2]), + cmd); + ret = get_txpwrlimit(fp_raw, argv, 0x12, buffer, + sizeof(mlan_ds_misc_chan_trpc_cfg) + + strlen(argv[2]), + cmd); + ret = get_txpwrlimit(fp_raw, argv, 0x13, buffer, + sizeof(mlan_ds_misc_chan_trpc_cfg) + + strlen(argv[2]), + cmd); + break; + default: + printf("Error: invalid arguments\n"); + printf("mlanutl mlanX/uapX get_txpwrlimit [0/0x10/0x11/0x12/0x13/0x1f/0xff]\n"); + break; + } +done: + if (fp_raw) + fclose(fp_raw); + if (buffer) + free(buffer); + if (cmd) + free(cmd); + return ret; +} + +/** + * @brief Process VHT configuration + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_vhtcfg(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct eth_priv_vhtcfg vhtcfg; + struct ifreq ifr; + t_u8 i, num = 0; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + /* Sanity tests */ + if (argc < 5) { + printf("Insufficient parameters\n"); + printf("For STA interface: mlanutl mlanX vhtcfg [bwcfg] [vhtcap]\n"); + printf("For uAP interface: mlanutl uapX vhtcfg [bwcfg] [vhtcap] [vht_tx_mcs] [vht_rx_mcs]\n"); + free(buffer); + return MLAN_STATUS_FAILURE; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: vhtcfg fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + /* Process result */ + /* the first attribute is the number of vhtcfg entries */ + num = *buffer; + if (argc == 5) { + /* GET operation */ + printf("11AC VHT Configuration: \n"); + for (i = 0; i < num; i++) { + memcpy(&vhtcfg, buffer + 1 + i * sizeof(vhtcfg), + sizeof(vhtcfg)); + /* Band */ + if (vhtcfg.band == 1) + printf("Band: 2.4G\n"); + else + printf("Band: 5G\n"); + /* BW confi9 */ + + if (vhtcfg.bwcfg == 0) + printf(" BW config: Follow BW in the 11N config\n"); + else + printf(" BW config: Follow BW in VHT Capabilities\n"); + + /* Tx/Rx */ + if (vhtcfg.txrx & 0x1) + printf(" VHT operation for Tx: 0x%08x\n", + vhtcfg.vht_cap_info); + if (vhtcfg.txrx & 0x2) + /* VHT capabilities */ + printf(" VHT Capabilities Info: 0x%08x\n", + vhtcfg.vht_cap_info); + /* MCS */ + if (vhtcfg.txrx & 0x2) { + printf(" Tx MCS set: 0x%04x\n", + vhtcfg.vht_tx_mcs); + printf(" Rx MCS set: 0x%04x\n", + vhtcfg.vht_rx_mcs); + } + } + } else { + /* SET operation */ + } + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief Process dynamic bandwidth set/get + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_dyn_bw(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + int dyn_bw = 0; + + /* Check arguments */ + if (argc < 3 || argc > 4) { + printf("ERR:Incorrect number of arguments!\n"); + printf("Syntax: ./mlanutl mlanX dyn_bw \n"); + return MLAN_STATUS_FAILURE; + } + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: dyn_bw fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + /* Process result */ + dyn_bw = *(int *)buffer; + printf("Dynamic bandwidth: 0x%02x\n", dyn_bw); + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief Process HT Tx configuration + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_httxcfg(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + t_u32 *data = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: httxcfg fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + if (argc == 3) { + /* Get result */ + data = (t_u32 *)buffer; + printf("HT Tx cfg: \n"); + printf(" BG band: 0x%08x\n", data[0]); + printf(" A band: 0x%08x\n", data[1]); + } + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief Process HT capability configuration + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_htcapinfo(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct eth_priv_htcapinfo *ht_cap = NULL; + struct ifreq ifr; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: htcapinfo fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + /* Process result */ + if (argc == 3) { + ht_cap = (struct eth_priv_htcapinfo *)buffer; + printf("HT cap info: \n"); + printf(" BG band: 0x%08x\n", ht_cap->ht_cap_info_bg); + printf(" A band: 0x%08x\n", ht_cap->ht_cap_info_a); + } + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief Process HT Add BA parameters + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_addbapara(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + struct eth_priv_addba *addba = NULL; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: addbapara fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + if (argc == 3) { + /* Get */ + addba = (struct eth_priv_addba *)buffer; + printf("Add BA configuration: \n"); + printf(" Time out : %d\n", addba->time_out); + printf(" TX window: %d\n", addba->tx_win_size); + printf(" RX window: %d\n", addba->rx_win_size); + printf(" TX AMSDU : %d\n", addba->tx_amsdu); + printf(" RX AMSDU : %d\n", addba->rx_amsdu); + } + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief Process Aggregation priority table parameters + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_aggrpriotbl(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + int i; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: aggrpriotbl fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + if (argc == 3) { + /* Get */ + printf("Aggregation priority table cfg: \n"); + printf(" TID AMPDU AMSDU \n"); + for (i = 0; i < MAX_NUM_TID; i++) { + printf(" %d %3d %3d \n", i, + buffer[2 * i], buffer[2 * i + 1]); + } + } + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief Process HT Add BA reject configurations + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_addbareject(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + int i; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: addbareject fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + if (argc == 3) { + /* Get */ + printf("Add BA reject configuration: \n"); + printf(" TID Reject \n"); + for (i = 0; i < MAX_NUM_TID; i++) { + printf(" %d %d\n", i, buffer[i]); + } + } + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} + +#define MASK_11AX_OM_CONTROL 0xFFF + +/** + * @brief 11ax HE capability and operation configure + * + * @param argc Number of arguments + * @param argv Pointer to the arguments array + * + * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_FAILURE + */ + +static int process_11axcfg(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd; + struct ifreq ifr; + int id_len = 0; + FILE *fp = NULL; + int ret = 0, cmd_header_len = 0; + char config_id[20]; + char filename[256]; + + if (argc != 3 && argc != 4) { + printf("Err: Invalid number of arguments\n"); + printf("Usage: ./mlanutl 11axcfg [11axcfg.conf]\n"); + return MLAN_STATUS_FAILURE; + } + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + cmd_header_len = strlen(CMD_NXP) + strlen(argv[2]); + prepare_buffer(buffer, argv[2], 0, NULL); + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = cmd_header_len; + cmd->total_len = BUFFER_LENGTH; + + if (argc == 4) { + memset(filename, 0, sizeof(filename)); + strncpy(filename, argv[3], sizeof(filename) - 1); + + fp = fopen(filename, "r"); + if (fp == NULL) { + perror("fopen"); + fprintf(stderr, "Cannot open file %s\n", argv[3]); + ret = -EFAULT; + ; + goto done; + } + + snprintf(config_id, sizeof(config_id), "Band"); + id_len = fparse_for_cmd_and_hex(fp, buffer + cmd_header_len, + (t_u8 *)config_id); + + snprintf(config_id, sizeof(config_id), "HECap"); + 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); + } + /* Initialize the ifr structure */ + memset(&ifr, 0, sizeof(ifr)); + 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("mlanutl: 11axcfg"); + ret = -EFAULT; + goto done; + } + hexdump("11axcfg", buffer + cmd_header_len, sizeof(mlan_ds_11ax_he_cfg), + ' '); +done: + if (fp) + fclose(fp); + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + return ret; +} + +/** + * @brief Process 11ax command + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_11axcmdcfg(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + mlan_ds_11ax_cmd_cfg *axcmd = NULL; + t_u32 action = 0; + t_u32 prefix_len = 0; + + if (strcmp(argv[3], "tx_omi") == 0) { + sprintf(argv[3], "%d", MLAN_11AXCMD_CFG_ID_TX_OMI); + } else if (strcmp(argv[3], "obssnbru_toltime") == 0) { + sprintf(argv[3], "%d", MLAN_11AXCMD_CFG_ID_OBSSNBRU_TOLTIME); + } else { + printf("ERR:unknown command %s!\n", argv[3]); + return MLAN_STATUS_FAILURE; + } + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = strlen((char *)buffer); + cmd->total_len = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: 11axcmd fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + prefix_len += strlen(CMD_NXP) + strlen(argv[2]); + action = *(t_u32 *)(buffer + prefix_len); + if (action == MLAN_ACT_SET) { + if (argv[4] == 0) { + printf("Invalid OBSSNBRU tolerance time: Valid range[1..3600]\n"); + free(buffer); + return MLAN_STATUS_FAILURE; + } + } + if (action == MLAN_ACT_GET) { + axcmd = (mlan_ds_11ax_cmd_cfg *)(buffer + prefix_len + + sizeof(t_u32)); + switch (axcmd->sub_id) { + case MLAN_11AXCMD_TXOMI_SUBID: + printf("tx OMI: 0x%x\n", axcmd->param.txomi_cfg.omi & + MASK_11AX_OM_CONTROL); + break; + case MLAN_11AXCMD_OBSS_TOLTIME_SUBID: + if (axcmd->param.toltime_cfg.tol_time > 3600 || + !axcmd->param.toltime_cfg.tol_time) + printf("OBSS Narrow Bandwidth RU tolerance Time: disabled\n"); + else + printf("OBSS Narrow Bandwidth RU Tolerance Time: %d sec\n", + axcmd->param.toltime_cfg.tol_time); + break; + default: + printf("Unknown sub_command 0x%x\n", axcmd->sub_id); + break; + } + } + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief Process tx rate configuration + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_txratecfg(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct eth_priv_tx_rate_cfg *txratecfg = NULL; + struct ifreq ifr; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: txratecfg fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + /* Process result */ + txratecfg = (struct eth_priv_tx_rate_cfg *)buffer; + if (argc == 3) { + /* GET operation */ + printf("Tx Rate Configuration: \n"); + /* format */ + if (txratecfg->rate_format == 0xFF) { + printf(" Type: 0xFF (Auto)\n"); + } else if (txratecfg->rate_format <= 3) { + printf(" Type: %d (%s)\n", + txratecfg->rate_format, + rate_format[txratecfg->rate_format]); + if (txratecfg->rate_format == 0) + printf(" Rate Index: %d (%s)\n", + txratecfg->rate_index, + lg_rate[txratecfg->rate_index]); + else if (txratecfg->rate_format >= 1) + printf(" MCS Index: %d\n", + (int)txratecfg->rate_index); + if (txratecfg->rate_format == 2 || + txratecfg->rate_format == 3) + printf(" NSS: %d\n", + (int)txratecfg->nss); + if (txratecfg->rate_setting == 0xffff) + printf("Rate setting :Preamble type/BW/GI/STBC/.. : auto \n"); + else { + printf("Preamble type: %x\n", + (txratecfg->rate_setting & 0x0003)); + printf("BW: %x\n", + (txratecfg->rate_setting & 0x001C) >> 2); + printf("LTF + GI size %x\n", + (txratecfg->rate_setting & 0x0060) >> 5); + printf("STBC %x\n", + (txratecfg->rate_setting & 0x0080) >> 7); + printf("DCM %x\n", + (txratecfg->rate_setting & 0x0100) >> 8); + printf("Coding %x\n", + (txratecfg->rate_setting & 0x0200) >> 9); + printf("maxPE %x\n", + (txratecfg->rate_setting & 0x3000) >> + 12); + } + } else { + printf(" Unknown rate format.\n"); + } + } + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief Process host_cmd response + * @param cmd_name Command name + * @param buf A pointer to the response buffer + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +int process_host_cmd_resp(char *cmd_name, t_u8 *buf) +{ + t_u32 hostcmd_size = 0; + HostCmd_DS_GEN *hostcmd = NULL; + int ret = MLAN_STATUS_SUCCESS; + + 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->seq_num = le16_to_cpu(hostcmd->seq_num); + hostcmd->result = le16_to_cpu(hostcmd->result); + + hostcmd->command &= ~HostCmd_RET_BIT; + if (!hostcmd->result) { + switch (hostcmd->command) { + case HostCmd_CMD_CFG_DATA: { + HostCmd_DS_802_11_CFG_DATA *pstcfgData = + (HostCmd_DS_802_11_CFG_DATA *)(buf + S_DS_GEN); + pstcfgData->data_len = + le16_to_cpu(pstcfgData->data_len); + pstcfgData->action = le16_to_cpu(pstcfgData->action); + + if (pstcfgData->action == HostCmd_ACT_GEN_GET) { + hexdump("cfgdata", pstcfgData->data, + pstcfgData->data_len, ' '); + } + break; + } + case HostCmd_CMD_802_11_TPC_ADAPT_REQ: { + mlan_ioctl_11h_tpc_resp *tpcIoctlResp = + (mlan_ioctl_11h_tpc_resp *)(buf + S_DS_GEN); + if (tpcIoctlResp->status_code == 0) { + printf("tpcrequest: txPower(%d), linkMargin(%d), rssi(%d)\n", + tpcIoctlResp->tx_power, + tpcIoctlResp->link_margin, + tpcIoctlResp->rssi); + } else { + printf("tpcrequest: failure, status = %d\n", + tpcIoctlResp->status_code); + } + break; + } + case HostCmd_CMD_802_11_CRYPTO: { + t_u16 alg = le16_to_cpu( + (t_u16) * (buf + S_DS_GEN + sizeof(t_u16))); + if (alg == CIPHER_TEST_AES_CCM || + alg == CIPHER_TEST_GCMP) { + HostCmd_DS_802_11_CRYPTO_AES_CCM *cmd_aes_ccm = + (HostCmd_DS_802_11_CRYPTO_AES_CCM + *)(buf + S_DS_GEN); + + cmd_aes_ccm->encdec = + le16_to_cpu(cmd_aes_ccm->encdec); + cmd_aes_ccm->algorithm = + le16_to_cpu(cmd_aes_ccm->algorithm); + cmd_aes_ccm->key_length = + le16_to_cpu(cmd_aes_ccm->key_length); + cmd_aes_ccm->nonce_length = + le16_to_cpu(cmd_aes_ccm->nonce_length); + cmd_aes_ccm->AAD_length = + le16_to_cpu(cmd_aes_ccm->AAD_length); + cmd_aes_ccm->data.header.type = le16_to_cpu( + cmd_aes_ccm->data.header.type); + cmd_aes_ccm->data.header.len = le16_to_cpu( + cmd_aes_ccm->data.header.len); + + printf("crypto_result: encdec=%d algorithm=%d, KeyLen=%d," + " NonceLen=%d,AADLen=%d,dataLen=%d\n", + cmd_aes_ccm->encdec, + cmd_aes_ccm->algorithm, + cmd_aes_ccm->key_length, + cmd_aes_ccm->nonce_length, + cmd_aes_ccm->AAD_length, + cmd_aes_ccm->data.header.len); + + hexdump("Key", cmd_aes_ccm->key, + cmd_aes_ccm->key_length, ' '); + hexdump("Nonce", cmd_aes_ccm->nonce, + cmd_aes_ccm->nonce_length, ' '); + hexdump("AAD", cmd_aes_ccm->AAD, + cmd_aes_ccm->AAD_length, ' '); + hexdump("Data", cmd_aes_ccm->data.data, + cmd_aes_ccm->data.header.len, ' '); + } else if (alg == CIPHER_TEST_WAPI) { + HostCmd_DS_802_11_CRYPTO_WAPI *cmd_wapi = + (HostCmd_DS_802_11_CRYPTO_WAPI + *)(buf + S_DS_GEN); + + cmd_wapi->encdec = + le16_to_cpu(cmd_wapi->encdec); + cmd_wapi->algorithm = + le16_to_cpu(cmd_wapi->algorithm); + cmd_wapi->key_length = + le16_to_cpu(cmd_wapi->key_length); + cmd_wapi->nonce_length = + le16_to_cpu(cmd_wapi->nonce_length); + cmd_wapi->AAD_length = + le16_to_cpu(cmd_wapi->AAD_length); + + printf("crypto_result: encdec=%d algorithm=%d, KeyLen=%d," + " NonceLen=%d,AADLen=%d,dataLen=%d\n", + cmd_wapi->encdec, cmd_wapi->algorithm, + cmd_wapi->key_length, + cmd_wapi->nonce_length, + cmd_wapi->AAD_length, + cmd_wapi->data_length); + + hexdump("Key", cmd_wapi->key, + cmd_wapi->key_length, ' '); + hexdump("Nonce", cmd_wapi->nonce, + cmd_wapi->nonce_length, ' '); + hexdump("AAD", cmd_wapi->AAD, + cmd_wapi->AAD_length, ' '); + } else { + HostCmd_DS_802_11_CRYPTO *cmd = + (HostCmd_DS_802_11_CRYPTO *)(buf + + S_DS_GEN); + cmd->encdec = le16_to_cpu(cmd->encdec); + cmd->algorithm = le16_to_cpu(cmd->algorithm); + cmd->key_IV_length = + le16_to_cpu(cmd->key_IV_length); + cmd->key_length = le16_to_cpu(cmd->key_length); + cmd->data.header.type = + le16_to_cpu(cmd->data.header.type); + cmd->data.header.len = + le16_to_cpu(cmd->data.header.len); + + printf("crypto_result: encdec=%d algorithm=%d,KeyIVLen=%d," + " KeyLen=%d,dataLen=%d\n", + cmd->encdec, cmd->algorithm, + cmd->key_IV_length, cmd->key_length, + cmd->data.header.len); + hexdump("KeyIV", cmd->keyIV, cmd->key_IV_length, + ' '); + hexdump("Key", cmd->key, cmd->key_length, ' '); + hexdump("Data", cmd->data.data, + cmd->data.header.len, ' '); + } + break; + } + case HostCmd_CMD_802_11_AUTO_TX: { + HostCmd_DS_802_11_AUTO_TX *at = + (HostCmd_DS_802_11_AUTO_TX *)(buf + S_DS_GEN); + + if (le16_to_cpu(at->action) == HostCmd_ACT_GEN_GET) { + if (S_DS_GEN + sizeof(at->action) == + hostcmd->size) { + printf("auto_tx not configured\n"); + + } else { + MrvlIEtypesHeader_t *header = + &at->auto_tx.header; + + header->type = + le16_to_cpu(header->type); + header->len = le16_to_cpu(header->len); + + if ((S_DS_GEN + sizeof(at->action) + + sizeof(MrvlIEtypesHeader_t) + + header->len == + hostcmd->size) && + (header->type == + TLV_TYPE_AUTO_TX)) { + AutoTx_MacFrame_t *atmf = + &at->auto_tx + .auto_tx_mac_frame; + + printf("Interval: %d second(s)\n", + le16_to_cpu( + atmf->interval)); + printf("Priority: %#x\n", + atmf->priority); + printf("Frame Length: %d\n", + le16_to_cpu( + atmf->frame_len)); + printf("Dest Mac Address: " + "%02x:%02x:%02x:%02x:%02x:%02x\n", + atmf->dest_mac_addr[0], + atmf->dest_mac_addr[1], + atmf->dest_mac_addr[2], + atmf->dest_mac_addr[3], + atmf->dest_mac_addr[4], + atmf->dest_mac_addr[5]); + printf("Src Mac Address: " + "%02x:%02x:%02x:%02x:%02x:%02x\n", + atmf->src_mac_addr[0], + atmf->src_mac_addr[1], + atmf->src_mac_addr[2], + atmf->src_mac_addr[3], + atmf->src_mac_addr[4], + atmf->src_mac_addr[5]); + + hexdump("Frame Payload", + atmf->payload, + le16_to_cpu( + atmf->frame_len) - + MLAN_MAC_ADDR_LENGTH * + 2, + ' '); + } else { + printf("incorrect auto_tx command response\n"); + } + } + } + break; + } + case HostCmd_CMD_802_11_SUBSCRIBE_EVENT: { + HostCmd_DS_802_11_SUBSCRIBE_EVENT *se = + (HostCmd_DS_802_11_SUBSCRIBE_EVENT *)(buf + + S_DS_GEN); + if (le16_to_cpu(se->action) == HostCmd_ACT_GEN_GET) { + int len = + S_DS_GEN + + sizeof(HostCmd_DS_802_11_SUBSCRIBE_EVENT); + printf("\nEvent\t\tValue\tFreq\tsubscribed\n\n"); + while (len < hostcmd->size) { + MrvlIEtypesHeader_t *header = + (MrvlIEtypesHeader_t *)(buf + + len); + switch (le16_to_cpu(header->type)) { + case TLV_TYPE_RSSI_LOW: { + MrvlIEtypes_RssiThreshold_t *low_rssi = + (MrvlIEtypes_RssiThreshold_t + *)(buf + len); + printf("Beacon Low RSSI\t%d\t%d\t%s\n", + low_rssi->RSSI_value, + low_rssi->RSSI_freq, + (le16_to_cpu(se->events) & + 0x0001) ? + "yes" : + "no"); + break; + } + case TLV_TYPE_SNR_LOW: { + MrvlIEtypes_SnrThreshold_t *low_snr = + (MrvlIEtypes_SnrThreshold_t + *)(buf + len); + printf("Beacon Low SNR\t%d\t%d\t%s\n", + low_snr->SNR_value, + low_snr->SNR_freq, + (le16_to_cpu(se->events) & + 0x0002) ? + "yes" : + "no"); + break; + } + case TLV_TYPE_FAILCOUNT: { + MrvlIEtypes_FailureCount_t + *failure_count = + (MrvlIEtypes_FailureCount_t + *)(buf + + len); + printf("Failure Count\t%d\t%d\t%s\n", + failure_count->fail_value, + failure_count->fail_freq, + (le16_to_cpu(se->events) & + 0x0004) ? + "yes" : + "no"); + break; + } + case TLV_TYPE_BCNMISS: { + MrvlIEtypes_BeaconsMissed_t + *bcn_missed = + (MrvlIEtypes_BeaconsMissed_t + *)(buf + + len); + printf("Beacon Missed\t%d\tN/A\t%s\n", + bcn_missed->beacon_missed, + (le16_to_cpu(se->events) & + 0x0008) ? + "yes" : + "no"); + break; + } + case TLV_TYPE_RSSI_HIGH: { + MrvlIEtypes_RssiThreshold_t + *high_rssi = + (MrvlIEtypes_RssiThreshold_t + *)(buf + + len); + printf("Bcn High RSSI\t%d\t%d\t%s\n", + high_rssi->RSSI_value, + high_rssi->RSSI_freq, + (le16_to_cpu(se->events) & + 0x0010) ? + "yes" : + "no"); + break; + } + + case TLV_TYPE_SNR_HIGH: { + MrvlIEtypes_SnrThreshold_t *high_snr = + (MrvlIEtypes_SnrThreshold_t + *)(buf + len); + printf("Beacon High SNR\t%d\t%d\t%s\n", + high_snr->SNR_value, + high_snr->SNR_freq, + (le16_to_cpu(se->events) & + 0x0020) ? + "yes" : + "no"); + break; + } + case TLV_TYPE_RSSI_LOW_DATA: { + MrvlIEtypes_RssiThreshold_t *low_rssi = + (MrvlIEtypes_RssiThreshold_t + *)(buf + len); + printf("Data Low RSSI\t%d\t%d\t%s\n", + low_rssi->RSSI_value, + low_rssi->RSSI_freq, + (le16_to_cpu(se->events) & + 0x0040) ? + "yes" : + "no"); + break; + } + case TLV_TYPE_SNR_LOW_DATA: { + MrvlIEtypes_SnrThreshold_t *low_snr = + (MrvlIEtypes_SnrThreshold_t + *)(buf + len); + printf("Data Low SNR\t%d\t%d\t%s\n", + low_snr->SNR_value, + low_snr->SNR_freq, + (le16_to_cpu(se->events) & + 0x0080) ? + "yes" : + "no"); + break; + } + case TLV_TYPE_RSSI_HIGH_DATA: { + MrvlIEtypes_RssiThreshold_t + *high_rssi = + (MrvlIEtypes_RssiThreshold_t + *)(buf + + len); + printf("Data High RSSI\t%d\t%d\t%s\n", + high_rssi->RSSI_value, + high_rssi->RSSI_freq, + (le16_to_cpu(se->events) & + 0x0100) ? + "yes" : + "no"); + break; + } + case TLV_TYPE_SNR_HIGH_DATA: { + MrvlIEtypes_SnrThreshold_t *high_snr = + (MrvlIEtypes_SnrThreshold_t + *)(buf + len); + printf("Data High SNR\t%d\t%d\t%s\n", + high_snr->SNR_value, + high_snr->SNR_freq, + (le16_to_cpu(se->events) & + 0x0200) ? + "yes" : + "no"); + break; + } + case TLV_TYPE_LINK_QUALITY: { + MrvlIEtypes_LinkQuality_t *link_qual = + (MrvlIEtypes_LinkQuality_t + *)(buf + len); + printf("Link Quality Parameters:\n"); + printf("------------------------\n"); + printf("Link Quality Event Subscribed\t%s\n", + (le16_to_cpu(se->events) & + 0x0400) ? + "yes" : + "no"); + printf("Link SNR Threshold = %d\n", + le16_to_cpu( + link_qual + ->link_SNR_thrs)); + printf("Link SNR Frequency = %d\n", + le16_to_cpu( + link_qual + ->link_SNR_freq)); + printf("Min Rate Value = %d\n", + le16_to_cpu( + link_qual + ->min_rate_val)); + printf("Min Rate Frequency = %d\n", + le16_to_cpu( + link_qual + ->min_rate_freq)); + printf("Tx Latency Value = %d\n", + le32_to_cpu( + link_qual + ->tx_latency_val)); + printf("Tx Latency Threshold = %d\n", + le32_to_cpu( + link_qual + ->tx_latency_thrs)); + + break; + } + case TLV_TYPE_PRE_BEACON_LOST: { + MrvlIEtypes_PreBeaconLost_t + *pre_bcn_lost = + (MrvlIEtypes_PreBeaconLost_t + *)(buf + + len); + printf("------------------------\n"); + printf("Pre-Beacon Lost Event Subscribed\t%s\n", + (le16_to_cpu(se->events) & + 0x0800) ? + "yes" : + "no"); + printf("Pre-Beacon Lost: %d\n", + pre_bcn_lost + ->pre_beacon_lost); + break; + } + default: + printf("Unknown subscribed event TLV Type=%#x," + " Len=%d\n", + le16_to_cpu( + header->type), + le16_to_cpu( + header->len)); + break; + } + + len += (sizeof(MrvlIEtypesHeader_t) + + le16_to_cpu(header->len)); + } + } + break; + } + case HostCmd_CMD_MAC_REG_ACCESS: + case HostCmd_CMD_BBP_REG_ACCESS: + case HostCmd_CMD_RF_REG_ACCESS: + case HostCmd_CMD_CAU_REG_ACCESS: { + HostCmd_DS_REG *preg = + (HostCmd_DS_REG *)(buf + S_DS_GEN); + preg->action = le16_to_cpu(preg->action); + if (preg->action == HostCmd_ACT_GEN_GET) { + preg->value = le32_to_cpu(preg->value); + printf("value = 0x%08x\n", preg->value); + } + break; + } + case HostCmd_CMD_MEM_ACCESS: { + HostCmd_DS_MEM *pmem = + (HostCmd_DS_MEM *)(buf + S_DS_GEN); + pmem->action = le16_to_cpu(pmem->action); + if (pmem->action == HostCmd_ACT_GEN_GET) { + pmem->value = le32_to_cpu(pmem->value); + printf("value = 0x%08x\n", pmem->value); + } + break; + } + case HostCmd_CMD_LINK_STATS_SUMMARY: { + HostCmd_DS_LINK_STATS_SUMMARY *linkstats = + (HostCmd_DS_LINK_STATS_SUMMARY *)(buf + + S_DS_GEN); + /* GET operation */ + printf("Link Statistics: \n"); + /* format */ + printf("Duration: %u\n", + (int)le32_to_cpu( + linkstats->timeSinceLastQuery_ms)); + + printf("Beacon count: %u\n", + le16_to_cpu(linkstats->bcnCnt)); + printf("Beacon missing: %u\n", + le16_to_cpu(linkstats->bcnMiss)); + printf("Beacon RSSI avg: %d\n", + le16_to_cpu(linkstats->bcnRssiAvg)); + printf("Beacon SNR avg: %d\n", + le16_to_cpu(linkstats->bcnSnrAvg)); + + printf("Rx packets: %u\n", + (int)le32_to_cpu(linkstats->rxPkts)); + printf("Rx RSSI avg: %d\n", + le16_to_cpu(linkstats->rxRssiAvg)); + printf("Rx SNR avg: %d\n", + le16_to_cpu(linkstats->rxSnrAvg)); + + printf("Tx packets: %u\n", + (int)le32_to_cpu(linkstats->txPkts)); + printf("Tx Attempts: %u\n", + (int)le32_to_cpu(linkstats->txAttempts)); + printf("Tx Failures: %u\n", + (int)le32_to_cpu(linkstats->txFailures)); + printf("Tx Initial Rate: %s\n", + rateIdStr[linkstats->txInitRate]); + + printf("Tx AC VO: %u [ %u ]\n", + le16_to_cpu(linkstats->txQueuePktCnt[WMM_AC_VO]), + (int)le32_to_cpu( + linkstats->txQueueDelay[WMM_AC_VO]) / + 1000); + printf("Tx AC VI: %u [ %u ]\n", + le16_to_cpu(linkstats->txQueuePktCnt[WMM_AC_VI]), + (int)le32_to_cpu( + linkstats->txQueueDelay[WMM_AC_VI]) / + 1000); + printf("Tx AC BE: %u [ %u ]\n", + le16_to_cpu(linkstats->txQueuePktCnt[WMM_AC_BE]), + (int)le32_to_cpu( + linkstats->txQueueDelay[WMM_AC_BE]) / + 1000); + printf("Tx AC BK: %u [ %u ]\n", + le16_to_cpu(linkstats->txQueuePktCnt[WMM_AC_BK]), + (int)le32_to_cpu( + linkstats->txQueueDelay[WMM_AC_BK]) / + 1000); + break; + } + case HostCmd_CMD_WMM_PARAM_CONFIG: { + HostCmd_DS_WMM_PARAM_CONFIG *wmm_param = + (HostCmd_DS_WMM_PARAM_CONFIG *)(buf + S_DS_GEN); + printf("WMM Params: \n"); + printf("\tBE: AIFSN=%d, CW_MAX=%d CW_MIN=%d, TXOP=%d\n", + wmm_param->ac_params[AC_BE].aci_aifsn.aifsn, + wmm_param->ac_params[AC_BE].ecw.ecw_max, + wmm_param->ac_params[AC_BE].ecw.ecw_min, + le16_to_cpu( + wmm_param->ac_params[AC_BE].tx_op_limit)); + printf("\tBK: AIFSN=%d, CW_MAX=%d CW_MIN=%d, TXOP=%d\n", + wmm_param->ac_params[AC_BK].aci_aifsn.aifsn, + wmm_param->ac_params[AC_BK].ecw.ecw_max, + wmm_param->ac_params[AC_BK].ecw.ecw_min, + le16_to_cpu( + wmm_param->ac_params[AC_BK].tx_op_limit)); + printf("\tVI: AIFSN=%d, CW_MAX=%d CW_MIN=%d, TXOP=%d\n", + wmm_param->ac_params[AC_VI].aci_aifsn.aifsn, + wmm_param->ac_params[AC_VI].ecw.ecw_max, + wmm_param->ac_params[AC_VI].ecw.ecw_min, + le16_to_cpu( + wmm_param->ac_params[AC_VI].tx_op_limit)); + printf("\tVO: AIFSN=%d, CW_MAX=%d CW_MIN=%d, TXOP=%d\n", + wmm_param->ac_params[AC_VO].aci_aifsn.aifsn, + wmm_param->ac_params[AC_VO].ecw.ecw_max, + wmm_param->ac_params[AC_VO].ecw.ecw_min, + le16_to_cpu( + 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"); + } else // else print default cmdresp + { + printf("HOSTCMD_RESP: CmdCode=%#04x, Size=%#04x," + " SeqNum=%#04x, Result=%#04x\n", + hostcmd->command, hostcmd->size, + hostcmd->seq_num, hostcmd->result); + hexdump("payload", (t_void *)(buf + S_DS_GEN), + hostcmd->size - S_DS_GEN, ' '); + } + } break; + default: + printf("HOSTCMD_RESP: CmdCode=%#04x, Size=%#04x," + " SeqNum=%#04x, Result=%#04x\n", + hostcmd->command, hostcmd->size, + hostcmd->seq_num, hostcmd->result); + hexdump("payload", (t_void *)(buf + S_DS_GEN), + hostcmd->size - S_DS_GEN, ' '); + break; + } + } else { + printf("HOSTCMD failed: CmdCode=%#04x, Size=%#04x," + " SeqNum=%#04x, Result=%#04x\n", + hostcmd->command, hostcmd->size, hostcmd->seq_num, + hostcmd->result); + } + return ret; +} + +/** + * @brief Process hssetpara configuration + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_hssetpara(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: hssetpara fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} + +#define STACK_NBYTES 100 /**< Number of bytes in stack */ +#define MAX_BYTESEQ 6 /**< Maximum byte sequence */ +#define TYPE_DNUM 1 /**< decimal number */ +#define TYPE_BYTESEQ 2 /**< byte sequence */ +#define MAX_OPERAND 0x40 /**< Maximum operands */ +#define TYPE_EQ (MAX_OPERAND + 1) /**< byte comparison: == operator */ +#define TYPE_EQ_DNUM (MAX_OPERAND + 2) /**< decimal comparison: =d operator */ +#define TYPE_EQ_BIT (MAX_OPERAND + 3) /**< bit comparison: =b operator */ +#define TYPE_AND (MAX_OPERAND + 4) /**< && operator */ +#define TYPE_OR (MAX_OPERAND + 5) /**< || operator */ + +typedef struct { + t_u16 sp; /**< Stack pointer */ + t_u8 byte[STACK_NBYTES]; /**< Stack */ +} mstack_t; + +typedef struct { + t_u8 type; /**< Type */ + t_u8 reserve[3]; /**< so 4-byte align val array */ + /* byte sequence is the largest among all the operands and operators. */ + /* byte sequence format: 1 byte of num of bytes, then variable num bytes + */ + t_u8 val[MAX_BYTESEQ + 1]; /**< Value */ +} op_t; + +/** + * @brief push data to stack + * + * @param s a pointer to mstack_t structure + * + * @param nbytes number of byte to push to stack + * + * @param val a pointer to data buffer + * + * @return TRUE-- sucess , FALSE -- fail + * + */ +static int push_n(mstack_t *s, t_u8 nbytes, t_u8 *val) +{ + if ((s->sp + nbytes) < STACK_NBYTES) { + memcpy((void *)(s->byte + s->sp), (const void *)val, + (size_t)nbytes); + s->sp += nbytes; + /* printf("push: n %d sp %d\n", nbytes, s->sp); */ + return TRUE; + } else /* stack full */ + return FALSE; +} + +/** + * @brief push data to stack + * + * @param s a pointer to mstack_t structure + * + * @param op a pointer to op_t structure + * + * @return TRUE-- sucess , FALSE -- fail + * + */ +static int push(mstack_t *s, op_t *op) +{ + t_u8 nbytes; + switch (op->type) { + case TYPE_DNUM: + if (push_n(s, 4, op->val)) + return push_n(s, 1, &op->type); + return FALSE; + case TYPE_BYTESEQ: + nbytes = op->val[0]; + if (push_n(s, nbytes, op->val + 1) && push_n(s, 1, op->val) && + push_n(s, 1, &op->type)) + return TRUE; + return FALSE; + default: + return push_n(s, 1, &op->type); + } +} + +/** + * @brief parse RPN string + * + * @param s a pointer to Null-terminated string to scan. + * + * @param first_time a pointer to return first_time + * + * @return A pointer to the last token found in string. + * NULL is returned when there are no more tokens to be + * found. + * + */ +static char *getop(char *s, int *first_time) +{ + const char delim[] = " \t\n"; + char *p; + if (*first_time) { + p = strtok(s, delim); + *first_time = FALSE; + } else { + p = strtok(NULL, delim); + } + return p; +} + +/** + * @brief Verify hex digit. + * + * @param c input ascii char + * @param h a pointer to return integer value of the digit + * char. + * @return TURE -- c is hex digit, FALSE -- c is not hex + * digit. + */ +static int ishexdigit(char c, t_u8 *h) +{ + if (c >= '0' && c <= '9') { + *h = c - '0'; + return TRUE; + } else if (c >= 'a' && c <= 'f') { + *h = c - 'a' + 10; + return TRUE; + } else if (c >= 'A' && c <= 'F') { + *h = c - 'A' + 10; + return TRUE; + } + return FALSE; +} + +/** + * @brief convert hex string to integer. + * + * @param s A pointer to hex string, string length up to 2 + * digits. + * @return integer value. + */ +static t_u8 hex_atoi(char *s) +{ + int i; + t_u8 digit; /* digital value */ + t_u8 t = 0; /* total value */ + + for (i = 0, t = 0; ishexdigit(s[i], &digit) && i < 2; i++) + t = 16 * t + digit; + return t; +} + +/** + * @brief Parse byte sequence in hex format string to a byte sequence. + * + * @param opstr A pointer to byte sequence in hex format string, with + * ':' as delimiter between two byte. + * @param val A pointer to return byte sequence string + * @return NA + */ +static void parse_hex(char *opstr, t_u8 *val) +{ + char delim = ':'; + char *p; + char *q; + t_u8 i; + + /* +1 is for skipping over the preceding h character. */ + p = opstr + 1; + + /* First byte */ + val[1] = hex_atoi(p++); + + /* Parse subsequent bytes. */ + /* Each byte is preceded by the : character. */ + for (i = 1; *p; i++) { + q = strchr(p, delim); + if (!q) + break; + p = q + 1; + val[i + 1] = hex_atoi(p); + } + /* Set num of bytes */ + val[0] = i; +} + +/** + * @brief str2bin, convert RPN string to binary format + * + * @param str A pointer to rpn string + * @param stack A pointer to mstack_t structure + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int str2bin(char *str, mstack_t *stack) +{ + int first_time; + char *opstr; + op_t op; /* operator/operand */ + int dnum; + int ret = MLAN_STATUS_SUCCESS; + + memset(stack, 0, sizeof(mstack_t)); + first_time = TRUE; + while ((opstr = getop(str, &first_time)) != NULL) { + if (isdigit((unsigned char)*opstr)) { + op.type = TYPE_DNUM; + dnum = cpu_to_le32(atoi(opstr)); + memcpy((t_u8 *)op.val, &dnum, sizeof(dnum)); + if (!push(stack, &op)) { + printf("push decimal number failed\n"); + ret = MLAN_STATUS_FAILURE; + break; + } + } else if (*opstr == 'h') { + op.type = TYPE_BYTESEQ; + parse_hex(opstr, op.val); + if (!push(stack, &op)) { + printf("push byte sequence failed\n"); + ret = MLAN_STATUS_FAILURE; + break; + } + } else if (!strcmp(opstr, "==")) { + op.type = TYPE_EQ; + if (!push(stack, &op)) { + printf("push byte cmp operator failed\n"); + ret = MLAN_STATUS_FAILURE; + break; + } + } else if (!strcmp(opstr, "=d")) { + op.type = TYPE_EQ_DNUM; + if (!push(stack, &op)) { + printf("push decimal cmp operator failed\n"); + ret = MLAN_STATUS_FAILURE; + break; + } + } else if (!strcmp(opstr, "=b")) { + op.type = TYPE_EQ_BIT; + if (!push(stack, &op)) { + printf("push bit cmp operator failed\n"); + ret = MLAN_STATUS_FAILURE; + break; + } + } else if (!strcmp(opstr, "&&")) { + op.type = TYPE_AND; + if (!push(stack, &op)) { + printf("push AND operator failed\n"); + ret = MLAN_STATUS_FAILURE; + break; + } + } else if (!strcmp(opstr, "||")) { + op.type = TYPE_OR; + if (!push(stack, &op)) { + printf("push OR operator failed\n"); + ret = MLAN_STATUS_FAILURE; + break; + } + } else { + printf("Unknown operand\n"); + ret = MLAN_STATUS_FAILURE; + break; + } + } + return ret; +} + +#define FILTER_BYTESEQ TYPE_EQ /**< byte sequence */ +#define FILTER_DNUM TYPE_EQ_DNUM /**< decimal number */ +#define FILTER_BITSEQ TYPE_EQ_BIT /**< bit sequence */ +#define FILTER_TEST (FILTER_BITSEQ + 1) /**< test */ + +#define NAME_TYPE 1 /**< Field name 'type' */ +#define NAME_PATTERN 2 /**< Field name 'pattern' */ +#define NAME_OFFSET 3 /**< Field name 'offset' */ +#define NAME_NUMBYTE 4 /**< Field name 'numbyte' */ +#define NAME_REPEAT 5 /**< Field name 'repeat' */ +#define NAME_BYTE 6 /**< Field name 'byte' */ +#define NAME_MASK 7 /**< Field name 'mask' */ +#define NAME_DEST 8 /**< Field name 'dest' */ + +static struct mef_fields { + char *name; /**< Name */ + t_s8 nameid; /**< Name Id. */ +} mef_fields[] = {{"type", NAME_TYPE}, {"pattern", NAME_PATTERN}, + {"offset", NAME_OFFSET}, {"numbyte", NAME_NUMBYTE}, + {"repeat", NAME_REPEAT}, {"byte", NAME_BYTE}, + {"mask", NAME_MASK}, {"dest", NAME_DEST}}; + +/** + * @brief get filter data + * + * @param fp A pointer to file stream + * @param ln A pointer to line number + * @param buf A pointer to hostcmd data + * @param size A pointer to the return size of hostcmd buffer + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int mlan_get_filter_data(FILE *fp, int *ln, t_u8 *buf, t_u16 *size) +{ + t_s32 errors = 0, i; + char line[256], *pos = NULL, *pos1 = NULL; + t_u16 type = 0; + t_u32 pattern = 0; + t_u16 repeat = 0; + t_u16 offset = 0; + char byte_seq[50]; + char mask_seq[50]; + t_u16 numbyte = 0; + t_s8 type_find = 0; + t_s8 pattern_find = 0; + t_s8 offset_find = 0; + t_s8 numbyte_find = 0; + t_s8 repeat_find = 0; + t_s8 byte_find = 0; + t_s8 mask_find = 0; + t_s8 dest_find = 0; + char dest_seq[50]; + + *size = 0; + while ((pos = mlan_config_get_line(fp, line, sizeof(line), ln))) { + if (strcmp(pos, "}") == 0) { + break; + } + pos1 = strchr(pos, '='); + if (pos1 == NULL) { + printf("Line %d: Invalid mef_filter line '%s'\n", *ln, + pos); + errors++; + continue; + } + *pos1++ = '\0'; + for (i = 0; (t_u32)i < NELEMENTS(mef_fields); i++) { + if (strncmp(pos, mef_fields[i].name, + strlen(mef_fields[i].name)) == 0) { + switch (mef_fields[i].nameid) { + case NAME_TYPE: + type = a2hex_or_atoi(pos1); + if ((type != FILTER_DNUM) && + (type != FILTER_BYTESEQ) && + (type != FILTER_BITSEQ) && + (type != FILTER_TEST)) { + printf("Invalid filter type:%d\n", + type); + return MLAN_STATUS_FAILURE; + } + type_find = 1; + break; + case NAME_PATTERN: + pattern = a2hex_or_atoi(pos1); + pattern_find = 1; + break; + case NAME_OFFSET: + offset = a2hex_or_atoi(pos1); + offset_find = 1; + break; + case NAME_NUMBYTE: + numbyte = a2hex_or_atoi(pos1); + numbyte_find = 1; + break; + case NAME_REPEAT: + repeat = a2hex_or_atoi(pos1); + repeat_find = 1; + break; + case NAME_BYTE: + memset(byte_seq, 0, sizeof(byte_seq)); + strncpy(byte_seq, pos1, + (sizeof(byte_seq) - 1)); + byte_find = 1; + break; + case NAME_MASK: + memset(mask_seq, 0, sizeof(mask_seq)); + strncpy(mask_seq, pos1, + (sizeof(mask_seq) - 1)); + mask_find = 1; + break; + case NAME_DEST: + memset(dest_seq, 0, sizeof(dest_seq)); + strncpy(dest_seq, pos1, + (sizeof(dest_seq) - 1)); + dest_find = 1; + break; + } + break; + } + } + if (i == NELEMENTS(mef_fields)) { + printf("Line %d: unknown mef field '%s'.\n", *line, + pos); + errors++; + } + } + if (type_find == 0) { + printf("Can not find filter type\n"); + return MLAN_STATUS_FAILURE; + } + switch (type) { + case FILTER_DNUM: + if (!pattern_find || !offset_find || !numbyte_find) { + printf("Missing field for FILTER_DNUM: pattern=%d,offset=%d,numbyte=%d\n", + pattern_find, offset_find, numbyte_find); + return MLAN_STATUS_FAILURE; + } + memset(line, 0, sizeof(line)); + snprintf(line, sizeof(line), "%d %d %d =d ", pattern, offset, + numbyte); + break; + case FILTER_BYTESEQ: + if (!byte_find || !offset_find || !repeat_find) { + printf("Missing field for FILTER_BYTESEQ: byte=%d,offset=%d,repeat=%d\n", + byte_find, offset_find, repeat_find); + return MLAN_STATUS_FAILURE; + } + memset(line, 0, sizeof(line)); + snprintf(line, sizeof(line), "%d h%s %d == ", repeat, byte_seq, + offset); + break; + case FILTER_BITSEQ: + if (!byte_find || !offset_find || !mask_find) { + printf("Missing field for FILTER_BITSEQ: byte=%d,offset=%d,mask_find=%d\n", + byte_find, offset_find, mask_find); + return MLAN_STATUS_FAILURE; + } + if (strlen(byte_seq) != strlen(mask_seq)) { + printf("byte string's length is different with mask's length!\n"); + return MLAN_STATUS_FAILURE; + } + memset(line, 0, sizeof(line)); + snprintf(line, sizeof(line), "h%s %d h%s =b ", byte_seq, offset, + mask_seq); + break; + case FILTER_TEST: + if (!byte_find || !offset_find || !repeat_find || !dest_find) { + printf("Missing field for FILTER_TEST: byte=%d,offset=%d,repeat=%d,dest=%d\n", + byte_find, offset_find, repeat_find, dest_find); + return MLAN_STATUS_FAILURE; + } + memset(line, 0, sizeof(line)); + snprintf(line, sizeof(line), "h%s %d h%s %d ", dest_seq, repeat, + byte_seq, offset); + break; + } + memcpy(buf, line, strlen(line)); + *size = strlen(line); + return MLAN_STATUS_SUCCESS; +} + +#define NAME_MODE 1 /**< Field name 'mode' */ +#define NAME_ACTION 2 /**< Field name 'action' */ +#define NAME_FILTER_NUM 3 /**< Field name 'filter_num' */ +#define NAME_RPN 4 /**< Field name 'RPN' */ +static struct mef_entry_fields { + char *name; /**< Name */ + t_s8 nameid; /**< Name id */ +} mef_entry_fields[] = { + {"mode", NAME_MODE}, + {"action", NAME_ACTION}, + {"filter_num", NAME_FILTER_NUM}, + {"RPN", NAME_RPN}, +}; + +typedef struct _MEF_ENTRY { + /** Mode */ + t_u8 Mode; + /** Size */ + t_u8 Action; + /** Size of expression */ + t_u16 ExprSize; +} MEF_ENTRY; + +/** + * @brief get mef_entry data + * + * @param fp A pointer to file stream + * @param ln A pointer to line number + * @param buf A pointer to hostcmd data + * @param size A pointer to the return size of hostcmd buffer + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int mlan_get_mef_entry_data(FILE *fp, int *ln, t_u8 *buf, t_u16 *size) +{ + char line[256], *pos = NULL, *pos1 = NULL; + t_u8 mode, action, filter_num = 0; + char rpn[256]; + t_s8 mode_find = 0; + t_s8 action_find = 0; + t_s8 filter_num_find = 0; + t_s8 rpn_find = 0; + char rpn_str[256]; + int rpn_len = 0; + char filter_name[50]; + t_s8 name_found = 0; + t_u16 len = 0; + int i; + int first_time = TRUE; + char *opstr = NULL; + char filter_action[10]; + t_s32 errors = 0; + MEF_ENTRY *pMefEntry = (MEF_ENTRY *)buf; + mstack_t stack; + while ((pos = mlan_config_get_line(fp, line, sizeof(line), ln))) { + if (strcmp(pos, "}") == 0) { + break; + } + pos1 = strchr(pos, '='); + if (pos1 == NULL) { + printf("Line %d: Invalid mef_entry line '%s'\n", *ln, + pos); + errors++; + continue; + } + *pos1++ = '\0'; + if (!mode_find || !action_find || !filter_num_find || + !rpn_find) { + for (i = 0; + (unsigned int)i < NELEMENTS(mef_entry_fields); + i++) { + if (strncmp(pos, mef_entry_fields[i].name, + strlen(mef_entry_fields[i].name)) == + 0) { + switch (mef_entry_fields[i].nameid) { + case NAME_MODE: + mode = a2hex_or_atoi(pos1); + if (mode & ~0x7) { + printf("invalid mode=%d\n", + mode); + return MLAN_STATUS_FAILURE; + } + pMefEntry->Mode = mode; + mode_find = 1; + break; + case NAME_ACTION: + action = a2hex_or_atoi(pos1); + if (action & ~0xff) { + printf("invalid action=%d\n", + action); + return MLAN_STATUS_FAILURE; + } + pMefEntry->Action = action; + action_find = 1; + break; + case NAME_FILTER_NUM: + filter_num = + a2hex_or_atoi(pos1); + filter_num_find = 1; + break; + case NAME_RPN: + memset(rpn, 0, sizeof(rpn)); + strncpy(rpn, pos1, + (sizeof(rpn) - 1)); + rpn_find = 1; + break; + } + break; + } + } + if (i == NELEMENTS(mef_fields)) { + printf("Line %d: unknown mef_entry field '%s'.\n", + *line, pos); + return MLAN_STATUS_FAILURE; + } + } + if (mode_find && action_find && filter_num_find && rpn_find) { + for (i = 0; i < filter_num; i++) { + opstr = getop(rpn, &first_time); + if (opstr == NULL) + break; + snprintf(filter_name, sizeof(filter_name), + "%s={", opstr); + name_found = 0; + while ((pos = mlan_config_get_line( + fp, line, sizeof(line), ln))) { + if (strncmp(pos, filter_name, + strlen(filter_name)) == 0) { + name_found = 1; + break; + } + } + if (!name_found) { + fprintf(stderr, + "mlanutl: %s not found in file\n", + filter_name); + return MLAN_STATUS_FAILURE; + } + if (MLAN_STATUS_FAILURE == + mlan_get_filter_data( + fp, ln, (t_u8 *)(rpn_str + rpn_len), + &len)) + break; + rpn_len += len; + if (i > 0) { + memcpy(rpn_str + rpn_len, filter_action, + strlen(filter_action)); + rpn_len += strlen(filter_action); + } + opstr = getop(rpn, &first_time); + if (opstr == NULL) + break; + memset(filter_action, 0, sizeof(filter_action)); + snprintf(filter_action, sizeof(filter_action), + "%s ", opstr); + } + /* Remove the last space */ + if (rpn_len > 0) { + rpn_len--; + rpn_str[rpn_len] = 0; + } + if (MLAN_STATUS_FAILURE == str2bin(rpn_str, &stack)) { + printf("Fail on str2bin!\n"); + return MLAN_STATUS_FAILURE; + } + *size = sizeof(MEF_ENTRY); + pMefEntry->ExprSize = cpu_to_le16(stack.sp); + memmove(buf + sizeof(MEF_ENTRY), stack.byte, stack.sp); + *size += stack.sp; + break; + } else if (mode_find && action_find && filter_num_find && + (filter_num == 0)) { + pMefEntry->ExprSize = 0; + *size = sizeof(MEF_ENTRY); + break; + } + } + return MLAN_STATUS_SUCCESS; +} + +#define MEFCFG_CMDCODE 0x009a + +/** + * @brief Process mefcfg command + * @param argc number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_mefcfg(int argc, char *argv[]) +{ + char line[256], cmdname[256], *pos = NULL; + int cmdname_found = 0, name_found = 0; + int ln = 0; + int ret = MLAN_STATUS_SUCCESS; + int i; + t_u8 *buffer = NULL; + t_u16 len = 0; + HostCmd_DS_MEF_CFG *mefcmd = NULL; + HostCmd_DS_GEN *hostcmd = NULL; + FILE *fp = NULL; + t_u32 cmd_len = 0, cmd_header_len; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + + if (argc < 4) { + printf("Error: invalid no of arguments\n"); + printf("Syntax: ./mlanutl mlan0 mefcfg \n"); + exit(1); + } + + cmd_header_len = strlen(CMD_NXP) + strlen("HOSTCMD"); + cmd_len = sizeof(HostCmd_DS_GEN) + sizeof(HostCmd_DS_MEF_CFG); + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return -ENOMEM; + } + + memset(buffer, 0, BUFFER_LENGTH); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + /* buf = MRVL_CMD */ + prepare_buffer(buffer, HOSTCMD, 0, NULL); + + /* buf = MRVL_CMD */ + hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32)); + hostcmd->command = cpu_to_le16(MEFCFG_CMDCODE); + hostcmd->seq_num = 0; + hostcmd->result = 0; + /* buf = MRVL_CMD + */ + mefcmd = (HostCmd_DS_MEF_CFG *)(buffer + cmd_header_len + + sizeof(t_u32) + S_DS_GEN); + + /* Host Command Population */ + snprintf(cmdname, sizeof(cmdname), "%s={", argv[2]); + cmdname_found = 0; + fp = fopen(argv[3], "r"); + if (fp == NULL) { + fprintf(stderr, "Cannot open file %s\n", argv[4]); + exit(1); + } + + while ((pos = mlan_config_get_line(fp, line, sizeof(line), &ln))) { + if (strcmp(pos, cmdname) == 0) { + cmdname_found = 1; + snprintf(cmdname, sizeof(cmdname), "Criteria="); + name_found = 0; + while ((pos = mlan_config_get_line( + fp, line, sizeof(line), &ln))) { + if (strncmp(pos, cmdname, strlen(cmdname)) == + 0) { + name_found = 1; + mefcmd->Criteria = a2hex_or_atoi( + pos + strlen(cmdname)); + break; + } + } + if (!name_found) { + fprintf(stderr, + "mlanutl: criteria not found in file '%s'\n", + argv[3]); + break; + } + snprintf(cmdname, sizeof(cmdname), "NumEntries="); + name_found = 0; + while ((pos = mlan_config_get_line( + fp, line, sizeof(line), &ln))) { + if (strncmp(pos, cmdname, strlen(cmdname)) == + 0) { + name_found = 1; + mefcmd->NumEntries = a2hex_or_atoi( + pos + strlen(cmdname)); + break; + } + } + if (!name_found) { + fprintf(stderr, + "mlanutl: NumEntries not found in file '%s'\n", + argv[3]); + break; + } + for (i = 0; i < mefcmd->NumEntries; i++) { + snprintf(cmdname, sizeof(cmdname), + "mef_entry_%d={", i); + name_found = 0; + while ((pos = mlan_config_get_line( + fp, line, sizeof(line), &ln))) { + if (strncmp(pos, cmdname, + strlen(cmdname)) == 0) { + name_found = 1; + break; + } + } + if (!name_found) { + fprintf(stderr, + "mlanutl: %s not found in file '%s'\n", + cmdname, argv[3]); + break; + } + if (MLAN_STATUS_FAILURE == + mlan_get_mef_entry_data( + fp, &ln, (t_u8 *)hostcmd + cmd_len, + &len)) { + ret = MLAN_STATUS_FAILURE; + break; + } + cmd_len += len; + } + break; + } + } + fclose(fp); + /* buf = MRVL_CMD */ + memcpy(buffer + cmd_header_len, (t_u8 *)&cmd_len, sizeof(t_u32)); + + if (!cmdname_found) + fprintf(stderr, + "mlanutl: cmdname '%s' not found in file '%s'\n", + argv[4], argv[3]); + + if (!cmdname_found || !name_found) { + ret = MLAN_STATUS_FAILURE; + goto mef_exit; + } + hostcmd->size = cpu_to_le16(cmd_len); + mefcmd->Criteria = cpu_to_le32(mefcmd->Criteria); + mefcmd->NumEntries = cpu_to_le16(mefcmd->NumEntries); + hexdump("mefcfg", buffer + cmd_header_len, cmd_len, ' '); + + /* Initialize the ifr structure */ + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name)); + ifr.ifr_ifru.ifru_data = (void *)cmd; + /* Perform ioctl */ + if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) { + perror("ioctl[MEF_CFG]"); + printf("ERR:Command sending failed!\n"); + + if (buffer) + free(buffer); + + if (cmd) + free(cmd); + + return MLAN_STATUS_FAILURE; + } + + ret = process_host_cmd_resp(HOSTCMD, buffer); + +mef_exit: + if (buffer) + free(buffer); + if (cmd) + free(cmd); + return ret; +} + +/** + * @brief Check the Hex String + * @param s A pointer to the string + * @return MLAN_STATUS_SUCCESS --HexString, MLAN_STATUS_FAILURE --not + * HexString + */ +static int ishexstring(char *s) +{ + int ret = MLAN_STATUS_FAILURE; + t_s32 tmp; + + if (!strncasecmp("0x", s, 2)) { + s += 2; + } + while (*s) { + tmp = toupper((unsigned char)*s); + if (((tmp >= 'A') && (tmp <= 'F')) || + ((tmp >= '0') && (tmp <= '9'))) { + ret = MLAN_STATUS_SUCCESS; + } else { + ret = MLAN_STATUS_FAILURE; + break; + } + s++; + } + + return ret; +} +/** + * @brief Converts colon separated MAC address to hex value + * + * @param mac A pointer to the colon separated MAC string + * @param raw A pointer to the hex data buffer + * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE + * MAC_BROADCAST - if broadcast mac + * MAC_MULTICAST - if multicast mac + */ +int mac2raw(char *mac, t_u8 *raw) +{ + unsigned int temp_raw[ETH_ALEN]; + int num_tokens = 0; + int i; + + if (strlen(mac) != ((2 * ETH_ALEN) + (ETH_ALEN - 1))) { + return MLAN_STATUS_FAILURE; + } + num_tokens = sscanf(mac, "%2x:%2x:%2x:%2x:%2x:%2x", temp_raw + 0, + temp_raw + 1, temp_raw + 2, temp_raw + 3, + temp_raw + 4, temp_raw + 5); + if (num_tokens != ETH_ALEN) { + return MLAN_STATUS_FAILURE; + } + for (i = 0; i < num_tokens; i++) + raw[i] = (t_u8)temp_raw[i]; + + if (memcmp(raw, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0) { + return MAC_BROADCAST; + } else if (raw[0] & 0x01) { + return MAC_MULTICAST; + } + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief Convert String to Integer + * @param buf A pointer to the string + * @return Integer + */ +static int atoval(char *buf) +{ + if (!strncasecmp(buf, "0x", 2)) + return a2hex(buf + 2); + else if (!ishexstring(buf)) + return a2hex(buf); + else + return atoi(buf); +} + +/** + * @brief Parses a command line + * + * @param line The line to parse + * @param args Pointer to the argument buffer to be filled in + * @param args_count Max number of elements which can be filled in buffer + * 'args' + * @return Number of arguments in the line or EOF + */ +int parse_line(char *line, char *args[], t_u16 args_count) +{ + int arg_num = 0; + int is_start = 0; + int is_quote = 0; + int length = 0; + int i = 0; + + arg_num = 0; + length = strlen(line); + /* Process line */ + + /* Find number of arguments */ + is_start = 0; + is_quote = 0; + for (i = 0; (i < length) && (arg_num < args_count); i++) { + /* Ignore leading spaces */ + if (is_start == 0) { + if (line[i] == ' ') { + continue; + } else if (line[i] == '\t') { + continue; + } else if (line[i] == '\n') { + break; + } else { + is_start = 1; + args[arg_num] = &line[i]; + arg_num++; + } + } + if (is_start == 1) { + /* Ignore comments */ + if (line[i] == '#') { + if (is_quote == 0) { + line[i] = '\0'; + arg_num--; + } + break; + } + /* Separate by '=' */ + if (line[i] == '=') { + line[i] = '\0'; + is_start = 0; + continue; + } + /* Separate by ',' */ + if (line[i] == ',') { + line[i] = '\0'; + is_start = 0; + continue; + } + /* Change ',' to ' ', but not inside quotes */ + if ((line[i] == ',') && (is_quote == 0)) { + line[i] = ' '; + continue; + } + } + /* Remove newlines */ + if (line[i] == '\n') { + line[i] = '\0'; + } + /* Check for quotes */ + if (line[i] == '"') { + is_quote = (is_quote == 1) ? 0 : 1; + continue; + } + if (((line[i] == ' ') || (line[i] == '\t')) && + (is_quote == 0)) { + line[i] = '\0'; + is_start = 0; + continue; + } + } + return arg_num; +} + +/** + * @brief Process cloud keep alive command + * @param argc number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_cloud_keep_alive(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + FILE *fp = NULL; + int ret = MLAN_STATUS_SUCCESS; + char line[256], cmdname[256], *pos = NULL; + int cmdname_found = 0, name_found = 0, arg_num = 0; + int ln = 0, i = 0; + char *args[256]; + cloud_keep_alive *keep_alive = NULL; + + if (argc < 5) { + printf("Error: invalid no of arguments\n"); + printf("Syntax: ./mlanutl mlanX cloud_keep_alive \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; + } + memset(buffer, 0, BUFFER_LENGTH); + + /* Insert command */ + strncpy((char *)buffer, argv[2], strlen(argv[2])); + + keep_alive = (cloud_keep_alive *)(buffer + strlen(argv[2])); + + cmdname_found = 0; + snprintf(cmdname, sizeof(cmdname), "%s={", argv[4]); + + fp = fopen(argv[3], "r"); + if (fp == NULL) { + fprintf(stderr, "Cannot open file %s\n", argv[3]); + ret = MLAN_STATUS_FAILURE; + if (buffer) + free(buffer); + goto done; + } + + while ((pos = mlan_config_get_line(fp, line, sizeof(line), &ln))) { + if (strcmp(pos, cmdname) == 0) { + cmdname_found = 1; + snprintf(cmdname, sizeof(cmdname), "mkeep_alive_id="); + name_found = 0; + while ((pos = mlan_config_get_line( + fp, line, sizeof(line), &ln))) { + if (strncmp(pos, cmdname, strlen(cmdname)) == + 0) { + name_found = 1; + keep_alive->mkeep_alive_id = + a2hex_or_atoi(pos + + strlen(cmdname)); + break; + } + } + if (!name_found) { + fprintf(stderr, + "mlanutl: keep alive id not found in file '%s'\n", + argv[3]); + break; + } + snprintf(cmdname, sizeof(cmdname), "enable="); + name_found = 0; + while ((pos = mlan_config_get_line( + fp, line, sizeof(line), &ln))) { + if (strncmp(pos, cmdname, strlen(cmdname)) == + 0) { + name_found = 1; + keep_alive->enable = a2hex_or_atoi( + pos + strlen(cmdname)); + break; + } + } + if (!name_found) { + fprintf(stderr, + "mlanutl: enable not found in file '%s'\n", + argv[3]); + break; + } + if (strcmp(argv[4], "reset") == 0) { + snprintf(cmdname, sizeof(cmdname), "reset="); + name_found = 0; + while ((pos = mlan_config_get_line( + fp, line, sizeof(line), &ln))) { + if (strncmp(pos, cmdname, + strlen(cmdname)) == 0) { + name_found = 1; + keep_alive + ->reset = a2hex_or_atoi( + pos + strlen(cmdname)); + break; + } + } + if (!name_found) { + fprintf(stderr, + "mlanutl: reset not found in file '%s'\n", + argv[3]); + break; + } + } + if (strcmp(argv[4], "start") == 0) { + snprintf(cmdname, sizeof(cmdname), + "sendInterval="); + name_found = 0; + while ((pos = mlan_config_get_line( + fp, line, sizeof(line), &ln))) { + if (strncmp(pos, cmdname, + strlen(cmdname)) == 0) { + name_found = 1; + keep_alive->sendInterval = + a2hex_or_atoi( + pos + + strlen(cmdname)); + break; + } + } + if (!name_found) { + fprintf(stderr, + "mlanutl: sendInterval not found in file '%s'\n", + argv[3]); + break; + } + snprintf(cmdname, sizeof(cmdname), + "retryInterval="); + name_found = 0; + while ((pos = mlan_config_get_line( + fp, line, sizeof(line), &ln))) { + if (strncmp(pos, cmdname, + strlen(cmdname)) == 0) { + name_found = 1; + keep_alive->retryInterval = + a2hex_or_atoi( + pos + + strlen(cmdname)); + break; + } + } + if (!name_found) { + fprintf(stderr, + "mlanutl: retryInterval not found in file '%s'\n", + argv[3]); + break; + } + snprintf(cmdname, sizeof(cmdname), + "retryCount="); + name_found = 0; + while ((pos = mlan_config_get_line( + fp, line, sizeof(line), &ln))) { + if (strncmp(pos, cmdname, + strlen(cmdname)) == 0) { + name_found = 1; + keep_alive->retryCount = + a2hex_or_atoi( + pos + + strlen(cmdname)); + break; + } + } + if (!name_found) { + fprintf(stderr, + "mlanutl: retryCount not found in file '%s'\n", + argv[3]); + break; + } + snprintf(cmdname, sizeof(cmdname), + "destMacAddr="); + name_found = 0; + while ((pos = mlan_config_get_line( + fp, line, sizeof(line), &ln))) { + if (strncmp(pos, cmdname, + strlen(cmdname)) == 0) { + name_found = 1; + mac2raw(pos + strlen(cmdname), + keep_alive->dst_mac); + break; + } + } + if (!name_found) { + fprintf(stderr, + "mlanutl: destination MAC address not found in file '%s'\n", + argv[3]); + break; + } + snprintf(cmdname, sizeof(cmdname), + "srcMacAddr="); + name_found = 0; + while ((pos = mlan_config_get_line( + fp, line, sizeof(line), &ln))) { + if (strncmp(pos, cmdname, + strlen(cmdname)) == 0) { + name_found = 1; + mac2raw(pos + strlen(cmdname), + keep_alive->src_mac); + break; + } + } + if (!name_found) { + fprintf(stderr, + "mlanutl: source MAC address not found in file '%s'\n", + argv[3]); + break; + } + snprintf(cmdname, sizeof(cmdname), "pktLen="); + name_found = 0; + while ((pos = mlan_config_get_line( + fp, line, sizeof(line), &ln))) { + if (strncmp(pos, cmdname, + strlen(cmdname)) == 0) { + name_found = 1; + keep_alive->pkt_len = + a2hex_or_atoi( + pos + + strlen(cmdname)); + break; + } + } + if (!name_found) { + fprintf(stderr, + "mlanutl: ip packet length not found in file '%s'\n", + argv[3]); + break; + } + snprintf(cmdname, sizeof(cmdname), "ipPkt="); + name_found = 0; + while ((pos = mlan_config_get_line( + fp, line, sizeof(line), &ln))) { + if (strncmp(pos, cmdname, + strlen(cmdname)) == 0) { + name_found = 1; + arg_num = parse_line(line, args, + 256); + if (arg_num < + keep_alive->pkt_len) { + fprintf(stderr, + "Invalid ipPkt or pkt_len in '%s'\n", + argv[3]); + break; + } + for (i = 0; + i < keep_alive->pkt_len; + i++) + keep_alive->pkt[i] = + (t_u8)atoval( + args[i + + 1]); + break; + } + } + if (!name_found) { + fprintf(stderr, + "mlanutl: ipPkt data not found in file '%s'\n", + argv[3]); + break; + } + } + } + } + if (!cmdname_found) { + fprintf(stderr, "mlanutl: ipPkt data not found in file '%s'\n", + argv[3]); + free(buffer); + if (fp) + fclose(fp); + return MLAN_STATUS_FAILURE; + } + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: cloud keep alive fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + /* Process result */ + keep_alive = (cloud_keep_alive *)(buffer + strlen(argv[2])); + if (strcmp(argv[4], "start") != 0) { + hexdump("Last cloud keep alive packet info", keep_alive->pkt, + keep_alive->pkt_len, ' '); + } + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + +done: + return ret; +} + +/** + * @brief Implement Minimum BA Threshold command + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +static int process_min_ba_threshold_cfg(int argc, char *argv[]) +{ + int ret = 0; + t_u8 min_ba_thres = 0; + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + memset(buffer, 0, BUFFER_LENGTH); + + /* Sanity tests */ + if (argc < 3 || argc > 4) { + printf("Error: invalid no of arguments\n"); + printf("mlanutl mlanX min_ba_threshold [#]\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + 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, &buffer, sizeof(buffer)); +#else + cmd->buf = buffer; +#endif + cmd->used_len = 0; + cmd->total_len = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: min_ba_threshold fail\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + + /* Process result */ + if (argc == 3) { + memcpy(&min_ba_thres, buffer, sizeof(min_ba_thres)); + printf("Min Tx BA Threshold: %d\n", min_ba_thres); + } + +done: + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return ret; +} + +/** + * * @brief Process txwatchdog check command + * * @param argc number of arguments + * * @param argv A pointer to arguments array + * * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + * */ +static int process_txwatchdog(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: txwatchdog fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + /* Process Get result */ + if (argc == 3) { + printf("txwatchdog check: %s\n", + ((*(t_u32 *)buffer == 0) ? "Disabled" : "Enabled")); + } + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} + +static int process_getuuid(int argc, char *argv[]) +{ + t_u8 *buffer = NULL; + struct eth_priv_cmd *cmd = NULL; + struct ifreq ifr; + + /* Initialize buffer */ + buffer = (t_u8 *)malloc(BUFFER_LENGTH); + if (!buffer) { + printf("ERR:Cannot allocate buffer for command!\n"); + return MLAN_STATUS_FAILURE; + } + + prepare_buffer(buffer, argv[2], 0, NULL); + + cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd)); + if (!cmd) { + printf("ERR: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 = BUFFER_LENGTH; + + /* 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("mlanutl"); + fprintf(stderr, "mlanutl: version fail\n"); + if (cmd) + free(cmd); + if (buffer) + free(buffer); + return MLAN_STATUS_FAILURE; + } + + printf("uuid: %s\n", buffer); + + if (buffer) + free(buffer); + if (cmd) + free(cmd); + + return MLAN_STATUS_SUCCESS; +} + +/******************************************************** + Global Functions +********************************************************/ + +/** + * @brief Entry function for mlanutl + * @param argc Number of arguments + * @param argv A pointer to arguments array + * @return MLAN_STATUS_SUCCESS--success, otherwise--fail + */ +int main(int argc, char *argv[]) +{ + int ret = MLAN_STATUS_SUCCESS; + + if ((argc == 2) && (strcmp(argv[1], "-v") == 0)) { + fprintf(stdout, "NXP mlanutl version %s\n", MLANUTL_VER); + exit(0); + } + if (argc < 3) { + fprintf(stderr, "Invalid number of parameters!\n"); + display_usage(); + exit(1); + } + + strncpy(dev_name, argv[1], IFNAMSIZ - 1); + + /* + * Create a socket + */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) { + fprintf(stderr, "mlanutl: Cannot open socket.\n"); + exit(1); + } + + ret = process_command(argc, argv); + + if (ret == MLAN_STATUS_NOTFOUND) { + if (ret) { + fprintf(stderr, "Invalid command specified!\n"); + display_usage(); + ret = 1; + } + } + + close(sockfd); + return ret; +} diff --git a/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.h b/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.h new file mode 100644 index 0000000..15c6b32 --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.h @@ -0,0 +1,1202 @@ +/** @file mlanutl.h + * + * @brief This file contains definitions for application + * + * + * 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 + * (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: + 11/26/2008: initial version +************************************************************************/ +#ifndef _MLANUTL_H_ +#define _MLANUTL_H_ + +/** Include header files */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/** Type definition: boolean */ +typedef enum { FALSE, TRUE } boolean; + +/** 16 bits byte swap */ +#define swap_byte_16(x) \ + ((t_u16)((((t_u16)(x)&0x00ffU) << 8) | (((t_u16)(x)&0xff00U) >> 8))) + +/** 32 bits byte swap */ +#define swap_byte_32(x) \ + ((t_u32)((((t_u32)(x)&0x000000ffUL) << 24) | \ + (((t_u32)(x)&0x0000ff00UL) << 8) | \ + (((t_u32)(x)&0x00ff0000UL) >> 8) | \ + (((t_u32)(x)&0xff000000UL) >> 24))) + +/** Convert to correct endian format */ +/** Do nothing */ +#define cpu_to_le16(x) (x) +/** Do nothing */ +#define cpu_to_le32(x) (x) +/** Do nothing */ +#define le16_to_cpu(x) (x) +/** Do nothing */ +#define le32_to_cpu(x) (x) + +/** TLV header */ +#define TLVHEADER /** Tag */ \ + t_u16 tag; \ + /** Length */ \ + t_u16 length + +/** Length of TLV header */ +#define TLVHEADER_LEN 4 + +/** Character, 1 byte */ +typedef signed char t_s8; +/** Unsigned character, 1 byte */ +typedef unsigned char t_u8; + +/** Short integer */ +typedef signed short t_s16; +/** Unsigned short integer */ +typedef unsigned short t_u16; + +/** Integer */ +typedef signed int t_s32; +/** Unsigned integer */ +typedef unsigned int t_u32; + +/** Long long integer */ +typedef signed long long t_s64; +/** Unsigned long long integer */ +typedef unsigned long long t_u64; + +/** Void pointer (4-bytes) */ +typedef void t_void; + +enum _mlan_act_ioctl { + MLAN_ACT_SET = 1, + MLAN_ACT_GET, + MLAN_ACT_CANCEL, + MLAN_ACT_CLEAR, + MLAN_ACT_RESET, + MLAN_ACT_DEFAULT +}; + +/** The attribute pack used for structure packing */ +#ifndef __ATTRIB_PACK__ +#define __ATTRIB_PACK__ __attribute__((packed)) +#endif + +/** Success */ +#define MLAN_STATUS_SUCCESS (0) +/** Failure */ +#define MLAN_STATUS_FAILURE (-1) +/** Not found */ +#define MLAN_STATUS_NOTFOUND (1) + +/** IOCTL number */ +#define MLAN_ETH_PRIV (SIOCDEVPRIVATE + 14) + +/** Command buffer max length */ +#define BUFFER_LENGTH (4 * 1024) + +/** Find number of elements */ +#define NELEMENTS(x) (sizeof(x) / sizeof(x[0])) + +/** BIT value */ +#define MBIT(x) (((t_u32)1) << (x)) + +#ifndef MIN +/** Find minimum value */ +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif /* MIN */ + +/** Length of ethernet address */ +#ifndef ETH_ALEN +#define ETH_ALEN 6 +#endif + +/** 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 + +/** Maximum number of TID */ +#define MAX_NUM_TID 8 + +/** Device name */ +extern char dev_name[IFNAMSIZ + 1]; + +#define HOSTCMD "hostcmd" + +/** NXP private command identifier */ +#define CMD_NXP "MRVL_CMD" + +struct command_node { + char *name; + int (*handler)(int, char **); +}; + +/** Private command structure */ +#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT +struct eth_priv_cmd { + /** Command buffer pointer */ + t_u64 buf; + /** buffer updated by driver */ + int used_len; + /** buffer sent by application */ + int total_len; +} __ATTRIB_PACK__; +#else +struct eth_priv_cmd { + /** Command buffer */ + t_u8 *buf; + /** Used length */ + int used_len; + /** Total length */ + int total_len; +}; +#endif + +/** data structure for cmd getdatarate */ +struct eth_priv_data_rate { + /** Tx data rate */ + t_u32 tx_data_rate; + /** Rx data rate */ + t_u32 rx_data_rate; + + /** Tx channel bandwidth */ + t_u32 tx_bw; + /** Tx guard interval */ + t_u32 tx_gi; + /** Rx channel bandwidth */ + t_u32 rx_bw; + /** Rx guard interval */ + t_u32 rx_gi; + /** MCS index */ + t_u32 tx_mcs_index; + t_u32 rx_mcs_index; + /** NSS */ + t_u32 tx_nss; + t_u32 rx_nss; + /* LG rate: 0, HT rate: 1, VHT rate: 2 */ + t_u32 tx_rate_format; + t_u32 rx_rate_format; +}; + +/** data structure for cmd getlog */ +struct eth_priv_get_log { + /** Multicast transmitted frame count */ + t_u32 mcast_tx_frame; + /** Failure count */ + t_u32 failed; + /** Retry count */ + t_u32 retry; + /** Multi entry count */ + t_u32 multi_retry; + /** Duplicate frame count */ + t_u32 frame_dup; + /** RTS success count */ + t_u32 rts_success; + /** RTS failure count */ + t_u32 rts_failure; + /** Ack failure count */ + t_u32 ack_failure; + /** Rx fragmentation count */ + t_u32 rx_frag; + /** Multicast Tx frame count */ + t_u32 mcast_rx_frame; + /** FCS error count */ + t_u32 fcs_error; + /** Tx frame count */ + t_u32 tx_frame; + /** WEP ICV error count */ + t_u32 wep_icv_error[4]; + /** beacon recv count */ + t_u32 bcn_rcv_cnt; + /** beacon miss count */ + t_u32 bcn_miss_cnt; + /** received amsdu count*/ + t_u32 amsdu_rx_cnt; + /** received msdu count in amsdu*/ + t_u32 msdu_in_rx_amsdu_cnt; + /** tx amsdu count*/ + t_u32 amsdu_tx_cnt; + /** tx msdu count in amsdu*/ + t_u32 msdu_in_tx_amsdu_cnt; + /** Tx frag count */ + t_u32 tx_frag_cnt; + /** Qos Tx frag count */ + t_u32 qos_tx_frag_cnt[8]; + /** Qos failed count */ + t_u32 qos_failed_cnt[8]; + /** Qos retry count */ + t_u32 qos_retry_cnt[8]; + /** Qos multi retry count */ + t_u32 qos_multi_retry_cnt[8]; + /** Qos frame dup count */ + t_u32 qos_frm_dup_cnt[8]; + /** Qos rts success count */ + t_u32 qos_rts_suc_cnt[8]; + /** Qos rts failure count */ + t_u32 qos_rts_failure_cnt[8]; + /** Qos ack failure count */ + t_u32 qos_ack_failure_cnt[8]; + /** Qos Rx frag count */ + t_u32 qos_rx_frag_cnt[8]; + /** Qos Tx frame count */ + t_u32 qos_tx_frm_cnt[8]; + /** Qos discarded frame count */ + t_u32 qos_discarded_frm_cnt[8]; + /** Qos mpdus Rx count */ + t_u32 qos_mpdus_rx_cnt[8]; + /** Qos retry rx count */ + t_u32 qos_retries_rx_cnt[8]; + /** CMACICV errors count */ + t_u32 cmacicv_errors; + /** CMAC replays count */ + t_u32 cmac_replays; + /** mgmt CCMP replays count */ + t_u32 mgmt_ccmp_replays; + /** TKIP ICV errors count */ + t_u32 tkipicv_errors; + /** TKIP replays count */ + t_u32 tkip_replays; + /** CCMP decrypt errors count */ + t_u32 ccmp_decrypt_errors; + /** CCMP replays count */ + t_u32 ccmp_replays; + /** Tx amsdu count */ + t_u32 tx_amsdu_cnt; + /** failed amsdu count */ + t_u32 failed_amsdu_cnt; + /** retry amsdu count */ + t_u32 retry_amsdu_cnt; + /** multi-retry amsdu count */ + t_u32 multi_retry_amsdu_cnt; + /** Tx octets in amsdu count */ + t_u64 tx_octets_in_amsdu_cnt; + /** amsdu ack failure count */ + t_u32 amsdu_ack_failure_cnt; + /** Rx amsdu count */ + t_u32 rx_amsdu_cnt; + /** Rx octets in amsdu count */ + t_u64 rx_octets_in_amsdu_cnt; + /** Tx ampdu count */ + t_u32 tx_ampdu_cnt; + /** tx mpdus in ampdu count */ + t_u32 tx_mpdus_in_ampdu_cnt; + /** tx octets in ampdu count */ + t_u64 tx_octets_in_ampdu_cnt; + /** ampdu Rx count */ + t_u32 ampdu_rx_cnt; + /** mpdu in Rx ampdu count */ + t_u32 mpdu_in_rx_ampdu_cnt; + /** Rx octets ampdu count */ + t_u64 rx_octets_in_ampdu_cnt; + /** ampdu delimiter CRC error count */ + t_u32 ampdu_delimiter_crc_error_cnt; + /** Rx Stuck Related Info*/ + /** Rx Stuck Issue count */ + t_u32 rx_stuck_issue_cnt[2]; + /** Rx Stuck Recovery count */ + t_u32 rx_stuck_recovery_cnt; + /** Rx Stuck TSF */ + t_u64 rx_stuck_tsf[2]; + /** Tx Watchdog Recovery Related Info */ + /** Tx Watchdog Recovery count */ + t_u32 tx_watchdog_recovery_cnt; + /** Tx Watchdog TSF */ + t_u64 tx_watchdog_tsf[2]; + /** Channel Switch Related Info */ + /** Channel Switch Announcement Sent */ + t_u32 channel_switch_ann_sent; + /** Channel Switch State */ + t_u32 channel_switch_state; + /** Register Class */ + t_u32 reg_class; + /** Channel Number */ + t_u32 channel_number; + /** Channel Switch Mode */ + t_u32 channel_switch_mode; + /** Reset Rx Mac Recovery Count */ + t_u32 rx_reset_mac_recovery_cnt; + /** ISR2 Not Done Count*/ + t_u32 rx_Isr2_NotDone_Cnt; + /** GDMA Abort Count */ + t_u32 gdma_abort_cnt; + /** Rx Reset MAC Count */ + t_u32 g_reset_rx_mac_cnt; + // Ownership error counters + /*Error Ownership error count*/ + t_u32 dwCtlErrCnt; + /*Control Ownership error count*/ + t_u32 dwBcnErrCnt; + /*Control Ownership error count*/ + t_u32 dwMgtErrCnt; + /*Control Ownership error count*/ + t_u32 dwDatErrCnt; + /*BIGTK MME good count*/ + t_u32 bigtk_mmeGoodCnt; + /*BIGTK Replay error count*/ + t_u32 bigtk_replayErrCnt; + /*BIGTK MIC error count*/ + t_u32 bigtk_micErrCnt; + /*BIGTK MME not included count*/ + t_u32 bigtk_mmeNotFoundCnt; +}; + +/** MLAN MAC Address Length */ +#define MLAN_MAC_ADDR_LENGTH 6 +#define COUNTRY_CODE_LEN 3 +/** Type definition of eth_priv_countrycode for CMD_COUNTRYCODE */ +struct eth_priv_countrycode { + /** Country Code */ + t_u8 country_code[COUNTRY_CODE_LEN]; +}; + +/** Type enumeration of WMM AC_QUEUES */ +typedef enum _mlan_wmm_ac_e { + WMM_AC_BK, + WMM_AC_BE, + WMM_AC_VI, + WMM_AC_VO +} __ATTRIB_PACK__ mlan_wmm_ac_e; + +/** IEEE Type definitions */ +typedef enum _IEEEtypes_ElementId_e { + SSID = 0, + SUPPORTED_RATES = 1, + FH_PARAM_SET = 2, + DS_PARAM_SET = 3, + CF_PARAM_SET = 4, + + IBSS_PARAM_SET = 6, + + COUNTRY_INFO = 7, + + POWER_CONSTRAINT = 32, + POWER_CAPABILITY = 33, + TPC_REQUEST = 34, + TPC_REPORT = 35, + SUPPORTED_CHANNELS = 36, + CHANNEL_SWITCH_ANN = 37, + QUIET = 40, + IBSS_DFS = 41, + HT_CAPABILITY = 45, + HT_OPERATION = 61, + BSSCO_2040 = 72, + OVERLAPBSSSCANPARAM = 74, + EXT_CAPABILITY = 127, + + VHT_CAPABILITY = 191, + VHT_OPERATION = 192, + EXT_BSS_LOAD = 193, + BW_CHANNEL_SWITCH = 194, + VHT_TX_POWER_ENV = 195, + EXT_POWER_CONSTR = 196, + AID_INFO = 197, + QUIET_CHAN = 198, + OPER_MODE_NTF = 199, + + ERP_INFO = 42, + EXTENDED_SUPPORTED_RATES = 50, + + VENDOR_SPECIFIC_221 = 221, + WMM_IE = VENDOR_SPECIFIC_221, + + WPS_IE = VENDOR_SPECIFIC_221, + + WPA_IE = VENDOR_SPECIFIC_221, + RSN_IE = 48, + EXTENSION = 255, +} __ATTRIB_PACK__ IEEEtypes_ElementId_e; + +typedef enum _IEEEtypes_Ext_ElementId_e { + HE_CAPABILITY = 35, + HE_OPERATION = 36, + HE_6G_CAPABILITY = 59 +} IEEEtypes_Ext_ElementId_e; + +/** Capability Bit Map*/ +typedef struct _IEEEtypes_CapInfo_t { + /** Capability Bit Map : ESS */ + t_u8 ess : 1; + /** Capability Bit Map : IBSS */ + t_u8 ibss : 1; + /** Capability Bit Map : CF pollable */ + t_u8 cf_pollable : 1; + /** Capability Bit Map : CF poll request */ + t_u8 cf_poll_rqst : 1; + /** Capability Bit Map : privacy */ + t_u8 privacy : 1; + /** Capability Bit Map : Short preamble */ + t_u8 short_preamble : 1; + /** Capability Bit Map : PBCC */ + t_u8 pbcc : 1; + /** Capability Bit Map : Channel agility */ + t_u8 chan_agility : 1; + /** Capability Bit Map : Spectrum management */ + t_u8 spectrum_mgmt : 1; + /** Capability Bit Map : Reserved */ + t_u8 rsrvd3 : 1; + /** Capability Bit Map : Short slot time */ + t_u8 short_slot_time : 1; + /** Capability Bit Map : APSD */ + t_u8 apsd : 1; + /** Capability Bit Map : Reserved */ + t_u8 rsvrd2 : 1; + /** Capability Bit Map : DSS OFDM */ + t_u8 dsss_ofdm : 1; + /** Capability Bit Map : Reserved */ + t_u8 rsrvd1 : 2; +} __ATTRIB_PACK__ IEEEtypes_CapInfo_t, *pIEEEtypes_CapInfo_t; + +/** IEEE IE header */ +typedef struct _IEEEtypes_Header_t { + /** Element ID */ + t_u8 element_id; + /** Length */ + t_u8 len; +} __ATTRIB_PACK__ IEEEtypes_Header_t, *pIEEEtypes_Header_t; + +/** IEEE IE header */ +#define IEEE_HEADER_LEN sizeof(IEEEtypes_Header_t) + +/** Maximum size of IEEE Information Elements */ +#define IEEE_MAX_IE_SIZE 256 + +/** Vendor specific IE header */ +typedef struct _IEEEtypes_VendorHeader_t { + /** Element ID */ + t_u8 element_id; + /** Length */ + t_u8 len; + /** OUI */ + t_u8 oui[3]; + /** OUI type */ + t_u8 oui_type; + /** OUI subtype */ + t_u8 oui_subtype; + /** Version */ + t_u8 version; +} __ATTRIB_PACK__ IEEEtypes_VendorHeader_t, *pIEEEtypes_VendorHeader_t; + +/** Vendor specific IE */ +typedef struct _IEEEtypes_VendorSpecific_t { + /** Vendor specific IE header */ + IEEEtypes_VendorHeader_t vend_hdr; + /** IE Max - size of previous fields */ + t_u8 data[IEEE_MAX_IE_SIZE - sizeof(IEEEtypes_VendorHeader_t)]; +} __ATTRIB_PACK__ IEEEtypes_VendorSpecific_t, *pIEEEtypes_VendorSpecific_t; + +/** IEEE IE */ +typedef struct _IEEEtypes_Generic_t { + /** Generic IE header */ + IEEEtypes_Header_t ieee_hdr; + /** IE Max - size of previous fields */ + t_u8 data[IEEE_MAX_IE_SIZE - sizeof(IEEEtypes_Header_t)]; +} __ATTRIB_PACK__ IEEEtypes_Generic_t, *pIEEEtypes_Generic_t; + +/** Convert character to integer */ +#define CHAR2INT(x) (((x) >= 'A') ? ((x) - 'A' + 10) : ((x) - '0')) + +/** Command RET code, MSB is set to 1 */ +#define HostCmd_RET_BIT 0x8000 +/** General purpose action : Get */ +#define HostCmd_ACT_GEN_GET 0x0000 +/** General purpose action : Set */ +#define HostCmd_ACT_GEN_SET 0x0001 +/** General purpose action : Clear */ +#define HostCmd_ACT_GEN_CLEAR 0x0004 +/** General purpose action : Remove */ +#define HostCmd_ACT_GEN_REMOVE 0x0004 + +/** TLV type ID definition */ +#define PROPRIETARY_TLV_BASE_ID 0x0100 + +/** MrvlIEtypesHeader_t */ +typedef struct MrvlIEtypesHeader { + /** Header type */ + t_u16 type; + /** Header length */ + t_u16 len; +} __ATTRIB_PACK__ MrvlIEtypesHeader_t; + +/** MrvlIEtypes_Data_t */ +typedef struct MrvlIEtypes_Data_t { + /** Header */ + MrvlIEtypesHeader_t header; + /** Data */ + t_u8 data[1]; +} __ATTRIB_PACK__ MrvlIEtypes_Data_t; + +/** channel band */ +enum { BAND_2GHZ = 0, + BAND_5GHZ = 1, + BAND_6GHZ = 2, + BAND_4GHZ = 3, +}; + +/** channel offset */ +enum { SEC_CHAN_NONE = 0, + SEC_CHAN_ABOVE = 1, + SEC_CHAN_5MHZ = 2, + SEC_CHAN_BELOW = 3 }; + +/** channel bandwidth */ +enum { CHAN_BW_20MHZ = 0, + CHAN_BW_10MHZ, + CHAN_BW_40MHZ, + CHAN_BW_80MHZ, +}; + +/** Band_Config_t */ +typedef struct _Band_Config_t { + /** Band Info - (00)=2.4GHz, (01)=5GHz */ + t_u8 chanBand : 2; + /** Channel Width - (00)=20MHz, (10)=40MHz, (11)=80MHz */ + t_u8 chanWidth : 2; + /** Secondary Channel Offset - (00)=None, (01)=Above, (11)=Below */ + t_u8 chan2Offset : 2; + /** Channel Selection Mode - (00)=manual, (01)=ACS, (02)=Adoption mode*/ + t_u8 scanMode : 2; +} __ATTRIB_PACK__ Band_Config_t; + +/** Maximum length of lines in configuration file */ +#define MAX_CONFIG_LINE 1024 +/** MAC BROADCAST */ +#define MAC_BROADCAST 0x1FF +/** MAC MULTICAST */ +#define MAC_MULTICAST 0x1FE + +/** HostCmd_DS_GEN */ +typedef struct MAPP_HostCmd_DS_GEN { + /** Command */ + t_u16 command; + /** Size */ + t_u16 size; + /** Sequence number */ + t_u16 seq_num; + /** Result */ + t_u16 result; +} __ATTRIB_PACK__ HostCmd_DS_GEN; + +/** Size of HostCmd_DS_GEN */ +#define S_DS_GEN sizeof(HostCmd_DS_GEN) + +/** max mod group */ +#define MAX_MOD_GROUP 35 + +/** modulation setting */ +typedef struct _mod_group_setting { + /** modulation group */ + t_u8 mod_group; + /** power */ + t_u8 power; +} __ATTRIB_PACK__ mod_group_setting; + +/** chan trpc config */ +typedef struct _ChanTRPCConfig_t { + /** start freq */ + t_u16 start_freq; + /* channel width */ + t_u8 width; + /** channel number */ + t_u8 chan_num; + mod_group_setting mod_group[MAX_MOD_GROUP]; +} __ATTRIB_PACK__ ChanTRPCConfig_t; + +/** MrvlIETypes_ChanTRPCConfig_t */ +typedef struct _MrvlIETypes_ChanTRPCConfig_t { + /** Header */ + MrvlIEtypesHeader_t header; + /** start freq */ + t_u16 start_freq; + /* channel width */ + t_u8 width; + /** channel number */ + t_u8 chan_num; + /** mode groups */ + mod_group_setting mod_group[]; +} __ATTRIB_PACK__ MrvlIETypes_ChanTRPCConfig_t; + +/*This command gets/sets the Transmit Rate-based Power Control (TRPC) channel + * configuration.*/ +#define HostCmd_CHANNEL_TRPC_CONFIG 0x00fb + +/** TLV OF CHAN_TRPC_CONFIG */ +#define TLV_TYPE_CHAN_TRPC_CONFIG (PROPRIETARY_TLV_BASE_ID + 137) + +/** mlan_ds_misc_chan_trpc_cfg */ +typedef struct _mlan_ds_misc_chan_trpc_cfg { + /** sub_band */ + t_u16 sub_band; + /** length */ + t_u16 length; + /** trpc buf */ + t_u8 trpc_buf[BUFFER_LENGTH]; +} __ATTRIB_PACK__ mlan_ds_misc_chan_trpc_cfg; + +struct eth_priv_addba { + t_u32 time_out; + t_u32 tx_win_size; + t_u32 rx_win_size; + t_u32 tx_amsdu; + t_u32 rx_amsdu; +}; + +struct eth_priv_htcapinfo { + t_u32 ht_cap_info_bg; + t_u32 ht_cap_info_a; +}; + +/** data_structure for cmd vhtcfg */ +struct eth_priv_vhtcfg { + /** Band (1: 2.4G, 2: 5 G, 3: both 2.4G and 5G) */ + t_u32 band; + /** TxRx (1: Tx, 2: Rx, 3: both Tx and Rx) */ + t_u32 txrx; + /** BW CFG (0: 11N CFG, 1: vhtcap) */ + t_u32 bwcfg; + /** VHT capabilities. */ + t_u32 vht_cap_info; + /** VHT Tx mcs */ + t_u32 vht_tx_mcs; + /** VHT Rx mcs */ + t_u32 vht_rx_mcs; + /** VHT rx max rate */ + t_u16 vht_rx_max_rate; + /** VHT max tx rate */ + t_u16 vht_tx_max_rate; +}; + +/** data structure for cmd txratecfg */ +struct eth_priv_tx_rate_cfg { + /* LG rate: 0, HT rate: 1, VHT rate: 2 */ + t_u32 rate_format; + /** Rate/MCS index (0xFF: auto) */ + t_u32 rate_index; + /** Rate rate */ + t_u32 rate; + /** NSS */ + t_u32 nss; + /** Rate Setting */ + t_u16 rate_setting; +}; + +#define MLAN_11AXCMD_CFG_ID_TX_OMI 6 +#define MLAN_11AXCMD_CFG_ID_OBSSNBRU_TOLTIME 7 + +#define MLAN_11AXCMD_TXOMI_SUBID 0x105 +#define MLAN_11AXCMD_OBSS_TOLTIME_SUBID 0x106 + +/** Type definition of mlan_ds_11ax_he_capa for MLAN_OID_11AX_HE_CFG */ +typedef struct _mlan_ds_11ax_he_capa { + /** tlv id of he capability */ + t_u16 id; + /** length of the payload */ + t_u16 len; + /** extension id */ + t_u8 ext_id; + /** he mac capability info */ + t_u8 he_mac_cap[6]; + /** he phy capability info */ + t_u8 he_phy_cap[11]; + /** he txrx mcs support for 80MHz */ + t_u8 he_txrx_mcs_support[4]; + /** val for txrx mcs 160Mhz or 80+80, and PPE thresholds */ + t_u8 val[28]; +} __ATTRIB_PACK__ mlan_ds_11ax_he_capa, *pmlan_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*/ + t_u8 band; + /** mlan_ds_11ax_he_capa */ + mlan_ds_11ax_he_capa he_cap; +} __ATTRIB_PACK__ mlan_ds_11ax_he_cfg, *pmlan_ds_11ax_he_cfg; + +/** Type definition of mlan_11axcmdcfg_obss_pd_offset for MLAN_OID_11AX_CMD_CFG + */ +typedef struct _mlan_11axcmdcfg_obss_pd_offset { + /** */ + t_u8 offset[2]; +} __ATTRIB_PACK__ mlan_11axcmdcfg_obss_pd_offset; + +/** Type definition of mlan_11axcmdcfg_sr_control for MLAN_OID_11AX_CMD_CFG */ +typedef struct _mlan_11axcmdcfg_sr_control { + /** 1 enable, 0 disable */ + t_u8 control; +} __ATTRIB_PACK__ mlan_11axcmdcfg_sr_control; + +/** Type definition of mlan_ds_11ax_sr_cmd for MLAN_OID_11AX_CMD_CFG */ +typedef struct _mlan_ds_11ax_sr_cmd { + /** type*/ + t_u16 type; + /** length of TLV */ + t_u16 len; + /** value */ + union { + mlan_11axcmdcfg_obss_pd_offset obss_pd_offset; + mlan_11axcmdcfg_sr_control sr_control; + } param; +} __ATTRIB_PACK__ mlan_ds_11ax_sr_cmd, *pmlan_ds_11ax_sr_cmd; + +/** Type definition of mlan_ds_11ax_beam_cmd for MLAN_OID_11AX_CMD_CFG */ +typedef struct _mlan_ds_11ax_beam_cmd { + /** command value: 1 is disable, 0 is enable*/ + t_u8 value; +} mlan_ds_11ax_beam_cmd, *pmlan_ds_11ax_beam_cmd; + +/** Type definition of mlan_ds_11ax_htc_cmd for MLAN_OID_11AX_CMD_CFG */ +typedef struct _mlan_ds_11ax_htc_cmd { + /** command value: 1 is enable, 0 is disable*/ + t_u8 value; +} mlan_ds_11ax_htc_cmd, *pmlan_ds_11ax_htc_cmd; + +/** Type definition of mlan_ds_11ax_txop_cmd for MLAN_OID_11AX_CMD_CFG */ +typedef struct _mlan_ds_11ax_txop_cmd { + /** Two byte rts threshold value of which only 10 bits, bit 0 to bit 9 + * are valid */ + t_u16 rts_thres; +} mlan_ds_11ax_txop_cmd, *pmlan_ds_11ax_txop_cmd; + +/** Type definition of mlan_ds_11ax_txomi_cmd for MLAN_OID_11AX_CMD_CFG */ +typedef struct _mlan_ds_11ax_txomi_cmd { + /* 11ax spec 9.2.4.6a.2 OM Control 12 bits. Bit 0 to bit 11 */ + t_u16 omi; +} mlan_ds_11ax_txomi_cmd, *pmlan_ds_11ax_txomi_cmd; + +/** Type definition of mlan_ds_11ax_toltime_cmd for MLAN_OID_11AX_CMD_CFG */ +typedef struct _mlan_ds_11ax_toltime_cmd { + /* OBSS Narrow Bandwidth RU Tolerance Time */ + t_u32 tol_time; +} mlan_ds_11ax_toltime_cmd, *pmlan_ds_11ax_toltime_cmd; + +/** Type definition of mlan_ds_11ax_cmd_cfg for MLAN_OID_11AX_CMD_CFG */ +typedef struct _mlan_ds_11ax_cmd_cfg { + /** Sub-command */ + t_u32 sub_command; + /** Sub-id */ + t_u32 sub_id; + /** 802.11n configuration parameter */ + union { + /** SR configuration for MLAN_11AXCMD_SR_SUBID */ + mlan_ds_11ax_sr_cmd sr_cfg; + /** Beam configuration for MLAN_11AXCMD_BEAM_SUBID */ + mlan_ds_11ax_beam_cmd beam_cfg; + /** HTC configuration for MLAN_11AXCMD_HTC_SUBID */ + mlan_ds_11ax_htc_cmd htc_cfg; + /** HTC configuration for MLAN_11AXCMD_TXOPRTS_SUBID */ + mlan_ds_11ax_txop_cmd txop_cfg; + /** HTC configuration for MLAN_11AXCMD_TXOMI_SUBID */ + mlan_ds_11ax_txomi_cmd txomi_cfg; + /** HTC configuration for MLAN_11AXCMD_TXOMI_SUBID */ + mlan_ds_11ax_toltime_cmd toltime_cfg; + } param; +} mlan_ds_11ax_cmd_cfg, *pmlan_ds_11ax_cmd_cfg; + +/** Maximum number of AC QOS queues available in the driver/firmware */ +#define MAX_AC_QUEUES 4 + +/** Read/Write Mac register */ +#define HostCmd_CMD_MAC_REG_ACCESS 0x0019 +/** Read/Write BBP register */ +#define HostCmd_CMD_BBP_REG_ACCESS 0x001a +/** Read/Write RF register */ +#define HostCmd_CMD_RF_REG_ACCESS 0x001b + +/** Data structure of WMM Aci/Aifsn */ +typedef struct _IEEEtypes_WmmAciAifsn_t { + /** Aifsn */ + t_u8 aifsn : 4; + /** Acm */ + t_u8 acm : 1; + /** Aci */ + t_u8 aci : 2; + /** Reserved */ + t_u8 reserved : 1; +} __ATTRIB_PACK__ IEEEtypes_WmmAciAifsn_t, *pIEEEtypes_WmmAciAifsn_t; + +/** Data structure of WMM ECW */ +typedef struct _IEEEtypes_WmmEcw_t { + /** Minimum Ecw */ + t_u8 ecw_min : 4; + /** Maximum Ecw */ + t_u8 ecw_max : 4; +} __ATTRIB_PACK__ IEEEtypes_WmmEcw_t, *pIEEEtypes_WmmEcw_t; + +/** Data structure of WMM AC parameters */ +typedef struct _IEEEtypes_WmmAcParameters_t { + IEEEtypes_WmmAciAifsn_t aci_aifsn; /**< AciAifSn */ + IEEEtypes_WmmEcw_t ecw; /**< Ecw */ + t_u16 tx_op_limit; /**< Tx op limit */ +} __ATTRIB_PACK__ IEEEtypes_WmmAcParameters_t, *pIEEEtypes_WmmAcParameters_t; + +/** HostCmd_DS_802_11_CFG_DATA */ +typedef struct MAPP_HostCmd_DS_802_11_CFG_DATA { + /** Action */ + t_u16 action; + /** Type */ + t_u16 type; + /** Data length */ + t_u16 data_len; + /** Data */ + t_u8 data[1]; +} __ATTRIB_PACK__ HostCmd_DS_802_11_CFG_DATA; + +/** Host Command ID : Configuration data */ +#define HostCmd_CMD_CFG_DATA 0x008f + +/** mlan_ioctl_11h_tpc_resp */ +typedef struct { + int status_code; /**< Firmware command result status code */ + int tx_power; /**< Reported TX Power from the TPC Report */ + int link_margin; /**< Reported Link margin from the TPC Report */ + int rssi; /**< RSSI of the received TPC Report frame */ +} __ATTRIB_PACK__ mlan_ioctl_11h_tpc_resp; + +/** Host Command ID : 802.11 TPC adapt req */ +#define HostCmd_CMD_802_11_TPC_ADAPT_REQ 0x0060 + +/** HostCmd_DS_802_11_CRYPTO */ +typedef struct MAPP_HostCmd_DS_802_11_CRYPTO { + t_u16 encdec; /**< Decrypt=0, Encrypt=1 */ + t_u16 algorithm; /**< RC4=1 AES=2 , AES_KEY_WRAP=3 */ + t_u16 key_IV_length; /**< Length of Key IV (bytes) */ + t_u8 keyIV[32]; /**< Key IV */ + t_u16 key_length; /**< Length of Key (bytes) */ + t_u8 key[32]; /**< Key */ + MrvlIEtypes_Data_t data; /**< Plain text if encdec=Encrypt, Ciphertext + data if encdec=Decrypt*/ +} __ATTRIB_PACK__ HostCmd_DS_802_11_CRYPTO; + +/** HostCmd_DS_802_11_CRYPTO_AES_CCM */ +typedef struct MAPP_HostCmd_DS_802_11_CRYPTO_AES_CCM { + t_u16 encdec; /**< Decrypt=0, Encrypt=1 */ + t_u16 algorithm; /**< AES_CCM=4 */ + t_u16 key_length; /**< Length of Key (bytes) */ + t_u8 key[32]; /**< Key */ + t_u16 nonce_length; /**< Length of Nonce (bytes) */ + t_u8 nonce[14]; /**< Nonce */ + t_u16 AAD_length; /**< Length of AAD (bytes) */ + t_u8 AAD[32]; /**< AAD */ + MrvlIEtypes_Data_t data; /**< Plain text if encdec=Encrypt, Ciphertext + data if encdec=Decrypt*/ +} __ATTRIB_PACK__ HostCmd_DS_802_11_CRYPTO_AES_CCM; + +/** HostCmd_DS_802_11_CRYPTO_WAPI */ +typedef struct MAPP_HostCmd_DS_802_11_CRYPTO_WAPI { + t_u16 encdec; /**< Decrypt=0, Encrypt=1 */ + t_u16 algorithm; /**< WAPI =5 */ + t_u16 key_length; /**< Length of Key (bytes) */ + t_u8 key[32]; /**< Key */ + t_u16 nonce_length; /**< Length of Nonce (bytes) */ + t_u8 nonce[16]; /**< Nonce */ + t_u16 AAD_length; /**< Length of AAD (bytes) */ + t_u8 AAD[48]; /**< AAD */ + t_u16 data_length; /**< Length of data (bytes) */ +} __ATTRIB_PACK__ HostCmd_DS_802_11_CRYPTO_WAPI; +/** WAPI cipher test */ +#define CIPHER_TEST_WAPI (5) +/** AES CCM cipher test */ +#define CIPHER_TEST_AES_CCM (4) +/** GCMP cipher test */ +#define CIPHER_TEST_GCMP (6) +/** Host Command ID : 802.11 crypto */ +#define HostCmd_CMD_802_11_CRYPTO 0x0078 + +/** HostCmd_DS_802_11_SUBSCRIBE_EVENT */ +typedef struct MAPP_HostCmd_DS_802_11_SUBSCRIBE_EVENT { + /** Action */ + t_u16 action; + /** Events */ + t_u16 events; +} __ATTRIB_PACK__ HostCmd_DS_802_11_SUBSCRIBE_EVENT; + +/** MrvlIEtypes_RssiParamSet_t */ +typedef struct MrvlIEtypes_RssiThreshold { + /** Header */ + MrvlIEtypesHeader_t header; + /** RSSI value */ + t_u8 RSSI_value; + /** RSSI frequency */ + t_u8 RSSI_freq; +} __ATTRIB_PACK__ MrvlIEtypes_RssiThreshold_t; + +/** MrvlIEtypes_SnrThreshold_t */ +typedef struct MrvlIEtypes_SnrThreshold { + /** Header */ + MrvlIEtypesHeader_t header; + /** SNR value */ + t_u8 SNR_value; + /** SNR frequency */ + t_u8 SNR_freq; +} __ATTRIB_PACK__ MrvlIEtypes_SnrThreshold_t; + +/** MrvlIEtypes_FailureCount_t */ +typedef struct MrvlIEtypes_FailureCount { + /** Header */ + MrvlIEtypesHeader_t header; + /** Failure value */ + t_u8 fail_value; + /** Failure frequency */ + t_u8 fail_freq; +} __ATTRIB_PACK__ MrvlIEtypes_FailureCount_t; + +/** MrvlIEtypes_BeaconsMissed_t */ +typedef struct MrvlIEtypes_BeaconsMissed { + /** Header */ + MrvlIEtypesHeader_t header; + /** Number of beacons missed */ + t_u8 beacon_missed; + /** Reserved */ + t_u8 reserved; +} __ATTRIB_PACK__ MrvlIEtypes_BeaconsMissed_t; + +/** MrvlIEtypes_LinkQuality_t */ +typedef struct MrvlIEtypes_LinkQuality { + /** Header */ + MrvlIEtypesHeader_t header; + /** Link SNR threshold */ + t_u16 link_SNR_thrs; + /** Link SNR frequency */ + t_u16 link_SNR_freq; + /** Minimum rate value */ + t_u16 min_rate_val; + /** Minimum rate frequency */ + t_u16 min_rate_freq; + /** Tx latency value */ + t_u32 tx_latency_val; + /** Tx latency threshold */ + t_u32 tx_latency_thrs; +} __ATTRIB_PACK__ MrvlIEtypes_LinkQuality_t; + +/** Host Command ID : 802.11 subscribe event */ +#define HostCmd_CMD_802_11_SUBSCRIBE_EVENT 0x0075 + +/** TLV type : Beacon RSSI low */ +#define TLV_TYPE_RSSI_LOW (PROPRIETARY_TLV_BASE_ID + 0x04) /* 0x0104 */ +/** TLV type : Beacon SNR low */ +#define TLV_TYPE_SNR_LOW (PROPRIETARY_TLV_BASE_ID + 0x05) /* 0x0105 */ +/** TLV type : Fail count */ +#define TLV_TYPE_FAILCOUNT (PROPRIETARY_TLV_BASE_ID + 0x06) /* 0x0106 */ +/** TLV type : BCN miss */ +#define TLV_TYPE_BCNMISS (PROPRIETARY_TLV_BASE_ID + 0x07) /* 0x0107 */ +/** TLV type : Beacon RSSI high */ +#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 0x16) /* 0x0116 */ +/** TLV type : Beacon SNR high */ +#define TLV_TYPE_SNR_HIGH (PROPRIETARY_TLV_BASE_ID + 0x17) /* 0x0117 */ + +/** TLV type :Link Quality */ +#define TLV_TYPE_LINK_QUALITY (PROPRIETARY_TLV_BASE_ID + 0x24) /* 0x0124 */ + +/** TLV type : Data RSSI low */ +#define TLV_TYPE_RSSI_LOW_DATA (PROPRIETARY_TLV_BASE_ID + 0x26) /* 0x0126 */ +/** TLV type : Data SNR low */ +#define TLV_TYPE_SNR_LOW_DATA (PROPRIETARY_TLV_BASE_ID + 0x27) /* 0x0127 */ +/** TLV type : Data RSSI high */ +#define TLV_TYPE_RSSI_HIGH_DATA (PROPRIETARY_TLV_BASE_ID + 0x28) /* 0x0128 */ +/** TLV type : Data SNR high */ +#define TLV_TYPE_SNR_HIGH_DATA (PROPRIETARY_TLV_BASE_ID + 0x29) /* 0x0129 */ + +/** MrvlIEtypes_PreBeaconLost_t */ +typedef struct MrvlIEtypes_PreBeaconLost { + /** Header */ + MrvlIEtypesHeader_t header; + /** Pre-Beacon Lost */ + t_u8 pre_beacon_lost; + /** Reserved */ + t_u8 reserved; +} __ATTRIB_PACK__ MrvlIEtypes_PreBeaconLost_t; + +/** TLV type: Pre-Beacon Lost */ +#define TLV_TYPE_PRE_BEACON_LOST (PROPRIETARY_TLV_BASE_ID + 0x49) /* 0x0149 */ + +/** AutoTx_MacFrame_t */ +typedef struct AutoTx_MacFrame { + t_u16 interval; /**< in seconds */ + t_u8 priority; /**< User Priority: 0~7, ignored if non-WMM */ + t_u8 reserved; /**< set to 0 */ + t_u16 frame_len; /**< Length of MAC frame payload */ + t_u8 dest_mac_addr[MLAN_MAC_ADDR_LENGTH]; /**< Destination MAC address + */ + t_u8 src_mac_addr[MLAN_MAC_ADDR_LENGTH]; /**< Source MAC address */ + t_u8 payload[]; /**< Payload */ +} __ATTRIB_PACK__ AutoTx_MacFrame_t; + +/** MrvlIEtypes_AutoTx_t */ +typedef struct MrvlIEtypes_AutoTx { + MrvlIEtypesHeader_t header; /**< Header */ + AutoTx_MacFrame_t auto_tx_mac_frame; /**< Auto Tx MAC frame */ +} __ATTRIB_PACK__ MrvlIEtypes_AutoTx_t; + +/** HostCmd_DS_802_11_AUTO_TX */ +typedef struct MAPP_HostCmd_DS_802_11_AUTO_TX { + /** Action */ + t_u16 action; /* 0 = ACT_GET; 1 = ACT_SET; */ + MrvlIEtypes_AutoTx_t auto_tx; /**< Auto Tx */ +} __ATTRIB_PACK__ HostCmd_DS_802_11_AUTO_TX; + +/** Host Command ID : 802.11 auto Tx */ +#define HostCmd_CMD_802_11_AUTO_TX 0x0082 + +/** TLV type : Auto Tx */ +#define TLV_TYPE_AUTO_TX (PROPRIETARY_TLV_BASE_ID + 0x18) /* 0x0118 */ + +/** Host Command ID : CAU register access */ +#define HostCmd_CMD_CAU_REG_ACCESS 0x00ed + +/** Host Command ID : Memory access */ +#define HostCmd_CMD_MEM_ACCESS 0x0086 + +typedef struct { + t_u32 timeSinceLastQuery_ms; /**< Duration of stats collection */ + + t_u16 bcnCnt; /**< Number of beacons received */ + t_u16 bcnMiss; /**< Estimate of beacons missed */ + t_s16 bcnRssiAvg; /**< Avg beacon RSSI */ + t_s16 bcnSnrAvg; /**< Avg beacon SNR */ + + t_u32 rxPkts; /**< Number of packets received */ + t_s16 rxRssiAvg; /**< Avg received packet RSSI */ + t_s16 rxSnrAvg; /**< Avg received packet SNR */ + + t_u32 txPkts; /**< Number of packets transmitted */ + t_u32 txAttempts; /**< Number of attempts made */ + t_u32 txFailures; /**< Number of pkts that failed */ + t_u8 txInitRate; /**< Current rate adaptation TX rateid */ + t_u8 reserved[3]; /**< Reserved */ + + t_u16 txQueuePktCnt[MAX_AC_QUEUES]; /**< Number of packets per AC */ + t_u32 txQueueDelay[MAX_AC_QUEUES]; /**< Averge queue delay per AC*/ +} __ATTRIB_PACK__ HostCmd_DS_LINK_STATS_SUMMARY; + +#define HostCmd_CMD_LINK_STATS_SUMMARY 0x00d3 + +/** Type enumeration of WMM AC_QUEUES */ +typedef enum _wmm_ac { + AC_BE, + AC_BK, + AC_VI, + AC_VO, +} wmm_ac; + +/** Data structure of Host command WMM_PARAM_CFG */ +typedef struct _HostCmd_DS_WMM_PARAM_CONFIG { + /** action */ + t_u16 action; + /** AC Parameters Record WMM_AC_BE, WMM_AC_BK, WMM_AC_VI, WMM_AC_VO */ + IEEEtypes_WmmAcParameters_t ac_params[MAX_AC_QUEUES]; +} __ATTRIB_PACK__ HostCmd_DS_WMM_PARAM_CONFIG; + +/** Host Command ID : Configure ADHOC_OVER_IP parameters */ +#define HostCmd_CMD_WMM_PARAM_CONFIG 0x023a + +/** HostCmd_DS_REG */ +typedef struct MAPP_HostCmd_DS_REG { + /** Read or write */ + t_u16 action; + /** Register offset */ + t_u16 offset; + /** Value */ + t_u32 value; +} __ATTRIB_PACK__ HostCmd_DS_REG; + +/** HostCmd_DS_MEM */ +typedef struct MAPP_HostCmd_DS_MEM { + /** Read or write */ + t_u16 action; + /** Reserved */ + t_u16 reserved; + /** Address */ + t_u32 addr; + /** Value */ + t_u32 value; +} __ATTRIB_PACK__ HostCmd_DS_MEM; + +typedef struct _HostCmd_DS_MEF_CFG { + /** Criteria */ + t_u32 Criteria; + /** Number of entries */ + t_u16 NumEntries; +} __ATTRIB_PACK__ HostCmd_DS_MEF_CFG; + +typedef struct _MEF_CFG_DATA { + /** Size */ + t_u16 size; + /** Data */ + HostCmd_DS_MEF_CFG data; +} __ATTRIB_PACK__ MEF_CFG_DATA; + +/** cloud keep alive parameters */ +typedef struct _cloud_keep_alive { + /** id */ + t_u8 mkeep_alive_id; + /** enable/disable of this id */ + t_u8 enable; + /** enable/disable reset*/ + t_u8 reset; + /** Reserved */ + t_u8 reserved; + /** Destination MAC address */ + t_u8 dst_mac[ETH_ALEN]; + /** Source MAC address */ + t_u8 src_mac[ETH_ALEN]; + /** packet send period */ + t_u32 sendInterval; + /** packet retry interval */ + t_u32 retryInterval; + /** packet retry count */ + t_u8 retryCount; + /** packet length */ + t_u8 pkt_len; + /** packet content */ + 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..6ea6b63 --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanutl/mlanwls.c @@ -0,0 +1,1790 @@ +/** @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_NTB 1 +#define PROTO_DOT11AZ_TB 2 +#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_ranging_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, 2:Dot11az_tb", + " : 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 config file", + " mlanutl mlan0 ftm session_cfg 2 config/ftm.conf - Sets dot11az tb ranging session params from config 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 + .range_tlv.type) == + FTM_NTB_RANGING_CFG_TLV_ID) || + (le16_to_cpu(phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az + .range_tlv.type) == + FTM_TB_RANGING_CFG_TLV_ID)) { + if (le16_to_cpu(phostcmd->cmd.ftm_session_cfg.action) == + MLAN_ACT_GET) { + /* Get */ + printf("\n\nGet Ranging Parameters: \n"); + } else { + /* Set */ + printf("\n\nSet Ranging Parameters: \n"); + } + printf("---------------------------------\n"); + printf("format_bw:%d \n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az + .range_tlv.val.format_bw); + printf("az_measurement_freq:%d \n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az + .range_tlv.val.az_measurement_freq); + printf("az_number_of_measurements:%d \n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az + .range_tlv.val.az_number_of_measurements); + printf("max_i2r_sts_upto80:%d \n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az + .range_tlv.val.max_i2r_sts_upto80); + printf("max_r2i_sts_upto80:%d \n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az + .range_tlv.val.max_r2i_sts_upto80); + printf("i2r_lmr_feedback:%d \n\n", + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az + .range_tlv.val.i2r_lmr_feedback); + } 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_ranging_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.range_tlv.len = + cpu_to_le16(sizeof(ranging_cfg_t)); + + if (app_data->protocol_type == PROTO_DOT11AZ_TB) { + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az.range_tlv.type = + cpu_to_le16(FTM_TB_RANGING_CFG_TLV_ID); + } else { + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az.range_tlv.type = + cpu_to_le16(FTM_NTB_RANGING_CFG_TLV_ID); + } + + if (app_data->hostcmd_action == MLAN_ACT_SET) { + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az.range_tlv.val + .format_bw = app_data->range_cfg.format_bw; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az.range_tlv.val + .max_i2r_sts_upto80 = + app_data->range_cfg.max_i2r_sts_upto80; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az.range_tlv.val + .max_r2i_sts_upto80 = + app_data->range_cfg.max_r2i_sts_upto80; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az.range_tlv.val + .az_measurement_freq = + app_data->range_cfg.az_measurement_freq; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az.range_tlv.val + .az_number_of_measurements = + app_data->range_cfg.az_number_of_measurements; + phostcmd->cmd.ftm_session_cfg.tlv.cfg_11az.range_tlv.val + .i2r_lmr_feedback = + app_data->range_cfg.i2r_lmr_feedback; + } + /*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); + 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; + phostcmd->cmd_hdr.size += sizeof(ftm_session_cfg_tlv_t); + + 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; + phostcmd->cmd_hdr.size += sizeof(lci_tlv_t); + } + + 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) - + sizeof(app_data->civic_cfg.civic_address)) + + app_data->civic_cfg.civic_address_length); + 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 += + sizeof(civic_loc_tlv_t) - + sizeof(app_data->civic_cfg.civic_address) + + 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_NTB) || + (app_data->protocol_type == PROTO_DOT11AZ_TB)) { + printf("[INFO] Set/Get DOT11AZ Ranging Config \n"); + ret = process_dot11az_ranging_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 = 0; + int ret = MLAN_STATUS_SUCCESS; + + /*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 = 0; + + // 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) { + if (strlen(args[1]) <= 255) { + gwls_data.civic_cfg + .civic_address_length = + strlen(args[1]); + strncpy((char *)&gwls_data.civic_cfg + .civic_address[0], + args[1], + gwls_data.civic_cfg + .civic_address_length); + PRINT_CFG("\t ADDRESS=%s\n", args[1]); + } else { + DBG_ERROR( + "\t [ERROR] Invalid Civic Address Len\n"); + } + + } else { + // printf("Invalid line entry\n %s",args[1]); + } + } + + if ((gwls_data.protocol_type == PROTO_DOT11AZ_NTB) || + (gwls_data.protocol_type == PROTO_DOT11AZ_TB)) { + if (strcmp(args[0], "DOT11AZ_RANGING_CFG") == 0) { + if (gwls_data.protocol_type == + PROTO_DOT11AZ_NTB) { + printf("DOT11AZ_NTB_RANGING_CFG\n\n"); + } else { + printf("DOT11AZ_TB_RANGING_CFG\n\n"); + } + } else if (strcmp(args[0], "FORMAT_BW") == 0) { + gwls_data.range_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.range_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.range_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.range_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.range_cfg.az_number_of_measurements = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t AZ_NUMBER_OF_MEASUREMENTS=%d\n", + param); + } else if (strcmp(args[0], "I2R_LMR_FEEDBACK") == 0) { + gwls_data.range_cfg.i2r_lmr_feedback = + (t_u8)(atoi(args[1])); + PRINT_CFG("\t I2R_LMR_FEEDBACK=%d\n\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/TB Ranging default config*/ + gwls_data.range_cfg.az_measurement_freq = 1; + gwls_data.range_cfg.az_number_of_measurements = 6; + gwls_data.range_cfg.format_bw = 2; + gwls_data.range_cfg.max_i2r_sts_upto80 = 0; + gwls_data.range_cfg.max_r2i_sts_upto80 = 1; + gwls_data.range_cfg.i2r_lmr_feedback = 0; + + /*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..50f7b88 --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanutl/mlanwls.h @@ -0,0 +1,379 @@ +/** @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_TB_RANGING_CFG_TLV_ID (PROPRIETARY_TLV_BASE_ID + 344) +#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 / FTM_SESSION_CFG_TB_RANGING TLV + * data*/ +typedef struct _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; + /** Initator lmr feedback */ + t_u8 i2r_lmr_feedback; + /**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__ 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[256]; +} __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 _ranging_cfg_tlv { + /** Type*/ + t_u16 type; + /** Length*/ + t_u16 len; + /** Value*/ + ranging_cfg_t val; +} __ATTRIB_PACK__ 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 */ + ranging_cfg_tlv_t range_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*/ + ranging_cfg_t range_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_main.h b/mxm_wifiex/wlan_src/mlan/mlan_main.h index b37d8f1..a7daad9 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_main.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_main.h @@ -2268,7 +2268,7 @@ typedef struct _adapter_operations { } mlan_adapter_operations; /** Adapter data structure for MLAN */ -typedef struct _mlan_adapter { +struct _mlan_adapter { /** MOAL handle structure */ t_void *pmoal_handle; /** BSS Attributes */ @@ -2791,7 +2791,7 @@ typedef struct _mlan_adapter { /* higher 8 bytes of uuid */ t_u64 uuid_hi; -} mlan_adapter, *pmlan_adapter; +}; /** Check if stream 2X2 enabled */ #define IS_STREAM_2X2(x) ((x)&FEATURE_CTRL_STREAM_2X2) diff --git a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c index 420f8c4..3962724 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c @@ -1211,7 +1211,7 @@ int woal_cfg80211_change_virtual_intf(struct wiphy *wiphy, #endif /* WIFI_DIRECT_SUPPORT */ #if defined(STA_SUPPORT) && defined(UAP_SUPPORT) if (priv->bss_type == MLAN_BSS_TYPE_UAP) { -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) woal_cfg80211_del_beacon(wiphy, dev, 0); #else woal_cfg80211_del_beacon(wiphy, dev); @@ -1445,7 +1445,7 @@ fail: */ #endif int woal_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) int link_id, #endif t_u8 key_index, @@ -1504,7 +1504,7 @@ int woal_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, */ #endif int woal_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) int link_id, #endif t_u8 key_index, @@ -1563,7 +1563,7 @@ int woal_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, #endif int woal_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) int link_id, #endif t_u8 key_index @@ -1598,7 +1598,7 @@ int woal_cfg80211_set_default_key(struct wiphy *wiphy, #if KERNEL_VERSION(2, 6, 30) <= CFG80211_VERSION_CODE int woal_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) int link_id, #endif t_u8 key_index) @@ -1612,7 +1612,7 @@ int woal_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, #if KERNEL_VERSION(5, 10, 0) <= CFG80211_VERSION_CODE int woal_cfg80211_set_default_beacon_key(struct wiphy *wiphy, struct net_device *netdev, -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) int link_id, #endif t_u8 key_index) @@ -2199,7 +2199,7 @@ done: * @return 0 -- success, otherwise fail */ int woal_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, -#if KERNEL_VERSION(5, 19, 2) <= CFG80211_VERSION_CODE +#if KERNEL_VERSION(5, 15, 2) <= CFG80211_VERSION_CODE unsigned int link_id, #endif const u8 *peer, @@ -4889,10 +4889,10 @@ void woal_cfg80211_notify_channel(moal_private *priv, #if KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE mutex_lock(&priv->wdev->mtx); #endif -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) cfg80211_ch_switch_notify(priv->netdev, &chandef, 0); #else - cfg80211_ch_switch_notify(priv->netdev, &chandef); + cfg80211_ch_switch_notify(priv->netdev, &chandef, 0); #endif #if KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE mutex_unlock(&priv->wdev->mtx); @@ -5238,7 +5238,7 @@ int woal_get_wiphy_chan_dfs_state(struct wiphy *wiphy, if (sband->channels[i].flags & IEEE80211_CHAN_RADAR) { #if CFG80211_VERSION_CODE > KERNEL_VERSION(3, 8, 13) ch_dfs_state->dfs_state = - sband->channels[i].dfs_state; + (dfs_state_t)sband->channels[i].dfs_state; ch_dfs_state->dfs_required = MTRUE; #endif } diff --git a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h index 85c628a..566f498 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h @@ -128,7 +128,7 @@ int woal_cfg80211_change_virtual_intf(struct wiphy *wiphy, int woal_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed); int woal_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) int link_id, #endif t_u8 key_index, @@ -138,7 +138,7 @@ int woal_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, const t_u8 *mac_addr, struct key_params *params); int woal_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) int link_id, #endif t_u8 key_index, @@ -162,7 +162,7 @@ int woal_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev); #endif int woal_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, -#if KERNEL_VERSION(5, 19, 2) <= CFG80211_VERSION_CODE +#if KERNEL_VERSION(5, 15, 2) <= CFG80211_VERSION_CODE unsigned int link_id, #endif const u8 *peer, @@ -213,7 +213,7 @@ int woal_cfg80211_set_channel(struct wiphy *wiphy, #if KERNEL_VERSION(2, 6, 37) < CFG80211_VERSION_CODE int woal_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *dev, -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) int link_id, #endif t_u8 key_index, bool ucast, bool mcast); @@ -225,7 +225,7 @@ int woal_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *dev, #if KERNEL_VERSION(2, 6, 30) <= CFG80211_VERSION_CODE int woal_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) int link_id, #endif t_u8 key_index); @@ -234,7 +234,7 @@ int woal_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, #if KERNEL_VERSION(5, 10, 0) <= CFG80211_VERSION_CODE int woal_cfg80211_set_default_beacon_key(struct wiphy *wiphy, struct net_device *netdev, -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) int link_id, #endif t_u8 key_index); @@ -436,7 +436,7 @@ int woal_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, struct beacon_parameters *params); #endif -#if KERNEL_VERSION(5, 19, 2) <= CFG80211_VERSION_CODE +#if KERNEL_VERSION(5, 15, 2) <= CFG80211_VERSION_CODE int woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev, unsigned int link_id); #else diff --git a/mxm_wifiex/wlan_src/mlinux/moal_main.c b/mxm_wifiex/wlan_src/mlinux/moal_main.c index 87ff9bb..b188d32 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_main.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_main.c @@ -971,7 +971,7 @@ static void woal_hang_work_queue(struct work_struct *work) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) priv->wdev->connected) { #else - priv->wdev->current_bss) { + priv->wdev->connected) { #endif #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) if (priv->host_mlme) @@ -5798,7 +5798,7 @@ int woal_close(struct net_device *dev) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) if (IS_STA_CFG80211(cfg80211_wext) && priv->wdev->connected) { #else - if (IS_STA_CFG80211(cfg80211_wext) && priv->wdev->current_bss) { + if (IS_STA_CFG80211(cfg80211_wext) && priv->wdev->connected) { #endif priv->cfg_disconnect = MTRUE; cfg80211_disconnected(priv->netdev, 0, NULL, 0, @@ -8929,7 +8929,7 @@ t_void woal_send_disconnect_to_system(moal_private *priv, #if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) priv->wdev->connected) { #else - priv->wdev->current_bss) { + priv->wdev->connected) { #endif PRINTM(MMSG, "wlan: Disconnected from " MACSTR diff --git a/mxm_wifiex/wlan_src/mlinux/moal_shim.c b/mxm_wifiex/wlan_src/mlinux/moal_shim.c index 035119f..6f401af 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_shim.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_shim.c @@ -3457,7 +3457,7 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) cfg80211_ch_switch_notify(priv->netdev, &priv->chan, 0); #else - cfg80211_ch_switch_notify(priv->netdev, &priv->chan); + cfg80211_ch_switch_notify(priv->netdev, &priv->chan, 0); #endif priv->chan_under_nop = MFALSE; } @@ -3791,7 +3791,7 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) if (!priv->wdev->connected) { #else - if (!priv->wdev->current_bss) { + if (!priv->wdev->connected) { #endif PRINTM(MEVENT, "HostMlme: Drop deauth/disassociate, current_bss = null\n"); @@ -4165,7 +4165,7 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) roam_info->links[0].bssid = priv->cfg_bssid; #else - roam_info->bssid = priv->cfg_bssid; + roam_info->links[0].bssid = priv->cfg_bssid; #endif roam_info->req_ie = req_ie; roam_info->req_ie_len = ie_len; diff --git a/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c b/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c index 6048071..a9b5285 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c @@ -103,7 +103,7 @@ static int woal_cfg80211_dump_survey(struct wiphy *wiphy, #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) static int woal_cfg80211_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) unsigned int link_id, #endif struct cfg80211_chan_def *chandef); @@ -5380,7 +5380,7 @@ static int woal_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, if (priv->media_connected == MFALSE) { PRINTM(MMSG, " Already disconnected\n"); #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) if (priv->wdev->connected && #else if (priv->wdev->current_bss && @@ -5711,7 +5711,7 @@ done: #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) static int woal_cfg80211_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) unsigned int link_id, #endif struct cfg80211_chan_def *chandef) @@ -8621,7 +8621,7 @@ int woal_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, passoc_rsp = (IEEEtypes_AssocRsp_t *) assoc_rsp->assoc_resp_buf; #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) roam_info.links[0].bssid = priv->cfg_bssid; #else roam_info.bssid = priv->cfg_bssid; @@ -9093,7 +9093,7 @@ void woal_start_roaming(moal_private *priv) } #endif #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) roam_info.links[0].bssid = priv->cfg_bssid; #else roam_info.bssid = priv->cfg_bssid; diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c b/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c index 2c1b75a..0556c40 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c @@ -2348,7 +2348,7 @@ int woal_cfg80211_del_virtual_intf(struct wiphy *wiphy, } } if (vir_priv && vir_priv->bss_type == MLAN_BSS_TYPE_UAP) { -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) if (woal_cfg80211_del_beacon(wiphy, dev, 0)) #else if (woal_cfg80211_del_beacon(wiphy, dev)) @@ -2356,13 +2356,13 @@ int woal_cfg80211_del_virtual_intf(struct wiphy *wiphy, PRINTM(MERROR, "%s: del_beacon failed\n", __func__); #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) vir_priv->wdev->links[0].ap.beacon_interval = 0; #else vir_priv->wdev->beacon_interval = 0; #endif #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 15, 0) -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) memset(&vir_priv->wdev->links[0].ap.chandef, 0, sizeof(vir_priv->wdev->links[0].ap.chandef)); #else @@ -2371,7 +2371,7 @@ int woal_cfg80211_del_virtual_intf(struct wiphy *wiphy, #endif #endif #endif -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) vir_priv->wdev->u.ap.ssid_len = 0; #else vir_priv->wdev->ssid_len = 0; @@ -2650,7 +2650,7 @@ done: * * @return 0 -- success, otherwise fail */ -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) int woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev, unsigned int link_id) #else @@ -3436,7 +3436,7 @@ static void woal_switch_uap_channel(moal_private *priv, t_u8 wait_option) priv->channel = uap_channel.channel; moal_memcpy_ext(priv->phandle, &priv->chan, &priv->csa_chan, sizeof(struct cfg80211_chan_def), sizeof(priv->chan)); -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 2) cfg80211_ch_switch_notify(priv->netdev, &priv->chan, 0); #else cfg80211_ch_switch_notify(priv->netdev, &priv->chan);